company_banner

Yet another вариант отправки уведомлений от Asterisk в Telegram

    image

    Добрый день, уважаемые хабражители. В последнее время на хабре появилось несколько статей об интеграции Asterisk и Telegram: раз, два.

    Предлагаю рассмотреть еще один вариант.

    По некоторым причинам данные решения мне не подходили.

    Что-то по объективным причинам: использование telegram-cli, по отзывам не слишком стабильного, да и для его использования нужно авторизоваться на сервере под своим telegram-аккаунтом, показалось мне не слишком удобным и правильным.

    Что-то по субъективным: не хотелось использовать php как в варианте 1 и заставлять сотрудников писать боту свои номера.

    Ну и, само собой, куда интереснее самому изобретать велосипед, удовольствие от процесса воплощения в жизнь своей задумки никто не отменял:)

    Исходные данные:


    У клиента несколько удаленных менеджеров с мобильными телефонами, звонок поступает на Asterisk на общий SIP-номер, после чего через sip-транк переадресуется на мобильные менеджеров. При данной схеме довольно много удобств — менеджеры не обязаны сидеть в офисе, а могут работать, что называется «в поле» (@boffart извини за плагиат:). Однако есть одно неудобство, которое перевешивает все плюсы — невозможность увидеть исходный Callerid клиента.

    Для реализации обхода данного неудобства было принято решение об отправке в общую группу менеджеров в telegram сообщения вида «Входящий вызов с номера ${CALLERID(num)} на номер ${EXTEN}».

    Итак, приступим:


    Для отправки в группу уведомлений о звонке необходим telegram-бот. Регистрация нового бота процесс довольно тривиальный и очень хорошо описанный здесь

    После регистрации бота напишем небольшой скрипт на python, который будет вызываться из Asterisk'a и слать нам в telegram уведомления.

    Используемая версия python — 2.7

    Так как я реализовывал все на Centos 6.6, в котором «из коробки» используется python 2.6 (проверить вашу версию python можно набрав в консоли python -V), то для начала нам нужно установить python 2.7. Есть два варианта: установка из rpm-пакетов и из исходников. Рассмотрим оба.

    Установка из исходников


    Обновим систему и поставим необходимые пакеты:
    yum -y update
    yum groupinstall -y 'development tools'
    yum install -y zlib-dev openssl-devel sqlite-devel bzip2-devel
    yum install xz-libs


    Качаем исходники python 2.7:
    wget http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tar.xz
    xz -d Python-2.7.6.tar.xz
    tar -xvf Python-2.7.6.tar


    Конфигурация и установка python 2.7:
    cd Python-2.7.6
    ./configure --prefix=/usr/local/bin (префикс можно ставить любой удобный вам, к примеру импортировать его из переменной $HOME)
    make
    make altinstall


    Установка pip 2.7:
    Перед установкой необходиом скачать и установить setuptools
    wget --no-check-certificate https://pypi.python.org/packages/source/s/setuptools/setuptools-1.4.2.tar.gz
    tar -xvf setuptools-1.4.2.tar.gz
    cd setuptools-1.4.2
    python2.7 setup.py install
    
    и сам pip
    curl https://bootstrap.pypa.io/get-pip.py | python2.7 -


    Установка из rpm


    Добавляем rpm-пакеты, ставим python, pip:
    rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/epel-release-6-5.noarch.rpm
    rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/ius-release-1.0-14.ius.el6.noarch.rpm
    yum clean all
    yum install python27
    yum install python27-pip


    Python нужной версии установлен, установим библиотеку для работы с Telegram API:

    pip2.7 install pyTelegramBotAPI==2.3.1
    

    И непосредственно сам код скрипта:
    #!/usr/local/bin/python2.7
    # -*- coding: utf-8 -*-
    
    import telebot
    import sys
    
    token = 'INSERT_YOUR_TOKEN'  # Вводим свой телеграм API токен
    group_id = -123456789  # Вводим id группы, куда надо слать сообщения (обратите внимание, что id группы - отрицательное целое число)
    bot = telebot.TeleBot(token, skip_pending=True)
    
    
    # Ловим команду старта при старте без аргументов (первый старт)
    @bot.message_handler(func=lambda message: True, commands=['start'])
    def start(message):
        if len(sys.argv) != 1:
            return
        bot.send_message(message.chat.id, "ID чата: " + str(message.chat.id))
        print message.chat.id
        sys.exit()
    
    
    # Если были переданы три аргумента, то возвращаем в чат сообщение
    if len(sys.argv) == 4:
        callerid = str(sys.argv[1])
        exten = str(sys.argv[2])
        redirectnum = str(sys.argv[3])
        bot.send_message(group_id, "Вызов с номера " + callerid + "\nна номер " + exten + "\nпереадресован на номер " + redirectnum)
    # Если аргумента нет, то считаем первым стартом и запускаем в режиме полинга
    if len(sys.argv) == 1:
        bot.polling(none_stop=True)


    Дело осталось за малым: перед поступлением входящего звонка вызвать скрипт из dialplan'а Asterisk. У меня он, к примеру, такой:

    vim /etc/asterisk/extensions.conf:
    exten => 84951234567,1,Set(CALLERID(num)=+7${CALLERID(num)})
    same => n,Answer()
    same => n,Playback(hello)
    same => n,Set(REDIRECTNUM=+79261234567)
    same => n,System(/etc/asterisk/redirector/redirector.py ${CALLERID(num)} +7${EXTEN:1} ${REDIRECTNUM})
    same =>n,Dial(SIP/mytrunk/mymobilenumer&SIP/mytrunk/mymobilenumber2,40,tTm(default))
    same =>n,Hangup()


    При входящем звонке менеджеры получают в группу telegram подобное сообщение:image

    Для удобства хабровчан оформил всё в github.

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

    Автор: Asterisk'ер компании Southbridge Михаил Комов.
    Метки:
    Southbridge 66,14
    Обеспечиваем стабильную работу серверов
    Поделиться публикацией
    Комментарии 10
    • 0
      Здорово, даже в голову не приходило скрестить Астериск с Телеграммом.
      Спасибо за ссылку попробуем потыркаться
      • 0
        Т.е. менеджер должен услышать сообщение телеграма ДО того как ему поступит входящий звонок (во время звонка не все айфоны даже держат сессию 3G)?

        Рекомендую «резолвить» CALLERID в название контрагента по базе CRM (если номер неизвестный — принявший звонок менеджер д.б. по приходу в офис внести его в БД.

        • 0

          Добрый день, спасибо за ваш интерес к статье.


          Т.е. менеджер должен услышать сообщение телеграма ДО того как ему поступит входящий звонок (во время звонка >не все айфоны даже держат сессию 3G)?

          Не обязательно, он просто должен знать номер звонящего, суть в этом.


          Рекомендую «резолвить» CALLERID в название контрагента по базе CRM (если номер неизвестный — принявший >звонок менеджер д.б. по приходу в офис внести его в БД.

          Согласен, отличное дополнение. Данная статья — это, так сказать, "каркас" для оповещения, какие аргументы передавать нужно в каждой конкретной реализации — решается по месту:)

        • 0
          Можно ли реализовать поиск номера из сообщения в адресной книге телефона? Или например, подключиться к адресной книге в gmail.com и выполнять там поиск перед переадресацией звонка, что бы в сообщении уже было имя звонящего, а не просто номер?
          • 0
            Можно, конечно. Только это логически независимые вещи. Вот тут https://habrahabr.ru/post/261391/, к примеру, имена хранятся в MySQL, и остаются через ODBC. Так что вы изначально можете получить имя звонящего, а потом отправить его в телеграм.
          • 0
            А где вебхуки? Где кнопочка перезвонить? Какой то детский пост получился…
            • 0
              Повторюсь, это лишь «каркас», который удовлетворял требованиям заказчика. Развивать можно до куда фантазия простирается :)
              • –2
                Ну так ссылку бы на документацию телеграмм API документацию прикрепили и хорош. Тоже каркас.
            • 0
              Вариант безусловно удобный, но ставить для этого python с зависимостями — излишнее.
              Тоже самое можно сделать с помощью curl из скрипта shell.
              • 0
                А почему вы вызываете скрипт через system, а не используете AGI? Нет необходимости передавать агрументы они все в agi.env

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое