Продолжение экспериментов над установленной и рабочей системы из статьи: "Raspberry Pi + FreeBPX(asterisk) + Mikrotik = АТС мини с переходом на PJSIP (sipnet, zadarma, multifon)", подключение telegram бота.

Обновление

apt update && apt upgrade

Стандартная процедура, но учитывая что система работает на стареньком Debian Buster, то актуальные репозитории уходят в архивы и могут возникать некоторые ошибки, как например:

Пример ошибки связанный с репозиторием sury.org

The following signatures were invalid: EXPKEYSIG B188E2B695BD4743 DEB.SURY.ORG Automatic Signing Key <deb@sury.org>

Решение этой ошибки:

apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B188E2B695BD4743

И по ходу обновления соглашаться с заменой путей к репозиториям.

Установка дополнительных программ для телеграм бота:

apt install python3-pip
pip3 install pyTelegramBotAPI

Переход на PJSIP

Поддался современным веяниям в отказе от протокола SIP в пользу PJSIP.

Во время манипуляций не забываем сохранять изменения кнопкой Submit.

Заходим на веб своего freepbx -> setting -> advansed setting -> sip channel driver:

отключение sip

PJSIP общие настройки:

setting -> sip setting -> pjsip

настройки

Настройка транков провайдеров

SIPNET
Connectivity -> trunks
Connectivity -> trunks
Вкладка advanced в  транке
Вкладка advanced в транке

Zadarma ( Novofon)

Мультифон (multifon)

Создание extension (номера для абонентов) ничем не отличается от обычного sip -> задаете логин (номер) и пароль, для приема сообщений прописать в Messages Context - messages (как написано в файле /etc/asterisk/extensions_custom.conf ).

Подключение Telegram

Для чего? Т.к. у меня подключены модемы и иногда приходят смс нужные. И заметил такую особенность, что если отправитель смс какой-то мутный сервис, который любит сложности в своем названии (использовать буквы и символы, без номера) и особенно с символом @ на конце, то стандартная схема сообщения в sip теряет его на этапе пересылки в экстеншен, хотя в файл записывает нормально. Телеграм пересылает все сообщения без потерь и еще удобно показывает с какого донгла пришло. Так же этот скрипт работает, как дополнительный журнал звонков и помогает в работе уведомлений ( типа сервера пуш уведомлений).

Скрипт телегам бота

/usr/local/bin/sms2tg.py (Не забываем заменить API:KEY и CHATID на свои)
!/usr/bin/python3.7
import base64
import telebot
import sys
bot = telebot.TeleBot('API:KEY')
chat_id = CHATID
bot.send_message(chat_id, sys.argv[1])

Созданному файлу назначаем владельца asterisk и права на выполнение 755.

полная инфа по скрипту : здесь

Получение API:KEY через системного бота @BotFather (создаем своего бота, придумываем название, получаем). Chat_ID ищем в телеграмме, там полно ботов (например Get My ID), которые дают эту информацию.

Переходим в консоль сервера к файлу: /etc/asterisk/extensions_custom.conf

/etc/asterisk/extensions_custom.conf
[from-trunk-dongle]

exten => sms,1,Verbose(Incoming SMS: From: ${CALLERID(num)} ${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,Set(MESSAGE(body)=${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME} - ${CALLERID(num)}: ${BASE64_DECODE(${SMS_BASE64})})' >> /var/log/asterisk/sms.txt)
exten => sms,n,Set(MESSAGE(from)="${CALLERID(num)}"); <${CALLERID(num)}>)
exten => sms,n,Set(CALLERID(name)=${CALLERID(num)})
exten => sms,n,Verbose(1,${MESSAGE(from)})
exten => sms,n,MessageSend(pjsip:300,${MESSAGE(from)})
exten => sms,n,System(/usr/local/bin/sms2tg.py 'СМС: ${DONGLENAME}${CALLERID(name)}: ${MESSAGE(body)}')
exten => sms,n,Hangup()

exten => _+X.,1,Set(CALLERID(name)=${CALLERID(num)})
exten => _+X.,n,System(/usr/local/bin/sms2tg.py 'Звонил: ${DONGLENAME}${CALLERID(name)}')
exten => _+X.,n,Goto(from-trunk,${EXTEN},1)
exten => h,n,Hangup()

exten => ussd,1,Verbose(Incoming USSD: ${BASE64_DECODE(${USSD_BASE64})})
exten => ussd,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME}: ${BASE64_DECODE(${USSD_BASE64})}' >> /var/log/asterisk/ussd.txt)
exten => ussd,n,Hangup()

[messages]
include => send-sms
exten => _XXX,1,MessageSend(pjsip:${EXTEN},"${CALLERID(name)}"${MESSAGE(from)})

[send-sms]
exten => _+X.,1,NoOp(SMS send to dongle)
same => n,NoOp(To ${MESSAGE(to)})
same => n,NoOp(From ${MESSAGE(from)})
same => n,NoOp(Body ${MESSAGE(body)})
same => n,Set(SMSTO=${EXTEN})
same => n,DongleSendSMS(dongle1,${SMSTO},"${MESSAGE(body)}",1440,yes)
same => n,Hangup()

Есть небольшая особенность при приеме звонков через модемы - будут приниматься звонки только с нормальных номеров в соответствии с указанным шаблоном (exten => _+X.,), с сервисных номеров 3х-4х значных входящий звонок не пройдет. Можно заменить на шаблон _. , но это порождает дополнительные сложности в дублировании уведомлений и так не рекомендуют, хотя я сам почти год его использовал.

Очистка памяти сим-карт и модемов от СМС

Для очистки памяти SIM череp консоль астериска дать команды:

dongle cmd dongle0 AT+CPMS=\"SM\",\"SM\",\"SM\"

dongle cmd dongle0 AT+CMGD=1,4


Для очистки памяти модема через консоль астериска дать команды:

dongle cmd dongle0 AT+CPMS=\"ME\",\"ME\",\"ME\"

dongle cmd dongle0 AT+CMGD=1,4

dongle0 меняете на свои, которые в файле dongle.conf

Команды для применения изменений, выполнять в консоли астериска CLI

core reload now

dialplan reload

dongle reload now

Комментарии (3)


  1. Dmitry27 Автор
    08.12.2022 14:43

    Еще вопрос в догонку: почему не работает экстен вида exten => s,1,... для входящих, только при указании конкретного шаблона?


  1. enamchuk
    10.12.2022 13:58

    "Поддался современным веяниям в отказе от протокола SIP в пользу PJSIP. ".
    Протокола PJSIP не существует, это просто другой драйвер, другая реализация протокола SIP.

    "при приеме звонков через модемы - будут приниматься звонки только с нормальных номеров в соответствии с указанным шаблоном (exten => _+X.,), с сервисных номеров 3х-4х значных входящий звонок не пройдет."

    Всё проходит корректно, вообще не важно, с какого номера вам звонят - с "нормальных", сервисных или международных, т.к. входящий вызов поступает на номер SIM, указанный в конфиге (dongle.conf - пропишите exten=ваш_номер в контекстах ваших номеров), и только на этот номер и поступит вызов.
    Кстати, проблем с "@" также нет, если экранировать все передаваемые параметры.

    Входящие сообщения отправляю на несколько внутренних SIP-телефонов, сохраняю в базу данных MySQL (в отдельную таблицу, ранее сохранял в поле userfield в таблице CDR, но длинные sms мешают просмотру детализации вызовов), а также в Telegram-бот (bash-скрипт).
    Исходящие сообщения также хорошо отправляются с SIP-телефонов через модем.

    Статья полезная, и наверняка кому-нибудь пригодится.
    Приходите к нам в Telegram-чат: https://t.me/asterisk_ru


    1. Dmitry27 Автор
      10.12.2022 17:18

      Всё проходит корректно, вообще не важно, с какого номера вам звонят - с "нормальных", сервисных или международных, т.к. входящий вызов поступает на номер SIM, указанный в конфиге (dongle.conf - пропишите exten=ваш_номер в контекстах ваших номеров), и только на этот номер и поступит вызов. Кстати, проблем с "@" также нет, если экранировать все передаваемые параметры.

      В донгле все прописано. Я вечер сидел подбирал варианты шаблонов, не проходят звонки если шаблон не соответствует (_. или _+X.). И что значит экранировать @? Во входящем имени отправителя смс? Я проблему @ на конце имени отправителя вообще заметил когда устал ждать код подтверждения от мвидео.

      Исходящие - проблем нет. Мне очень понравилось с ботом, когда разделил смс и звонки уведомления удобочитаемые стали, чем просто в клиента приходит. И я преимущественно на мобильном клиенте, соответственно некоторые не любят ждать долго гудков, бросают трубку, у мой телефон не успел принять звонок, но в телеге уже есть уведомление.