Привет, Хабр! Я уже давно наблюдаю за тобой, но все никак не решаюсь сделать свой первый шаг. Теперь мне показалось что я готов. Расскажу о своем опыте работы с telegram ботом — последнее время эта тема достаточно популярна на просторах сети, да и на самом Хабре я встречал уже не мало статей. Но по большей части в них рассказывается о принципах создания ботов, и нет ни слова о том, какую практическую пользу можно из этих самых ботов извлечь.

У меня был опыт создания систем мониторинга состояния серверов, с возможностью настройки стратегий тестирования и отправкой коротких sms сообщений с целью информирования о неполадках на одном из наблюдаемых серверов, но все это довольно не удобно, а так же платно — каждое сообщение стоит денег.

Что такое «система мониторинга состояния»? По своей архитектуре это должен быть небольшой модуль, который отвечает за проверку состояния и за информирование об отклонениях от нормального состояния.

Есть множество готовых комплексных решений, включающих в себя такую систему мониторинга. Это и знаменитый zabbix и nagios, и yandex метрика и еще огромная куча аналогичных прекрасных инструментов.

Аналитика


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

Первое время любой свежий сайт мало интересен пользователям. Однако при достаточных усилиях или денежных вложениях (обычно и то и другое) на ресурсе появляется трафик.

Мы уже поместили в наш код скрипт google analytics и можем наблюдать за динамикой изменения нашей аудитории. Но этого не всегда бывает достаточно. Иногда хочется знать больше — хочется контролировать весь процесс нахождения пользователя на сайте, вести его, направлять. Анализируя заголовки запросов и ответов можно получить исчерпывающую информацию о том, что делал каждый пользователь, когда и зачем. Для этого рано или поздно вы начинаете читать логи вашего веб сервера — иногда там скрыта ошибка, которая поможет исправить вам серьезный баг, а иногда просто интересно понять: кто же все-таки спамит вашу гостевую книгу?

Бот


Python и django идеально подходят для работы с telegram ботом. Что такое бот? В этом контексте, бот — это интерфейс взаимодействия между вашим приложением и клиентом telegram. Этот интерфейс позволит отправлять сообщения в зависимости от бизнес логики вашего приложения.
Я не буду расписывать здесь весь процесс создания и настройки веб приложения на django — врят ли у меня получится сделать это лучше чем у создателей официальной докумментации. Скажу только, что это не должно занять у вас больше десяти минут, если вы уже работали с этим фреймворком.

Хочется сказать спасибо Павлу Дурову и его команде — благодаря возможности установки webHook, работать с ботом стало максимально просто и удобно. Все что необходимо это:

  • Создать своего бота при помощи интерфейса BotFather в клиенте телеграм и настроить его, следуя инструкциям папы бота

  • Установить webHook, используя свой token, который папа бот поможет вам получить. Для этого переходим по url: api.telegram.org/bot{{ token }}/setWebhook?url={{ url }}, где token — ваше кольцо аутентификации, а url — это ссылка, запрос на которую обрабатывает контроллер вашего телеграм бота. Отмечу так же, что использоваться может только https протокол, т.е. необходим SSL.

  • Создать контроллер, обрабатывающий url из пункта 2, создать бизнес логику для вашего бота. Привязать контроллер к обработчику url. В часть url необходимо так же добавить свой token чтобы обеспечить другие люди не могли слать запросы на этот адрес.

  • Добавить бота в свой список контактов. Это можно сделать через поиск в клиенте telegram или используя ссылку @{{ bot_name }}

Далее все сводится к простой схеме. Как только вашему боту приходит какое-то сообщение, на url, установленный в webHook приходит запрос с информацией об этом сообщении. В частности там есть информация о дате сообщения, об id чата отправителя, о самом отправителе. Эту информацию лучше сохранять в базу данных, чтобы случайно не потерять — с ней и нужно работать. Мы программируем бота таким образом, что если ему приходит сообщение, которое является командой — он выполняет какое-либо действие. Скажем, я хочу, чтобы бот отправлял мне сообщения в telegram с информацией о каждом запросе, что приходит на мой сайт. Для этого нужно задать ему всего две команды, например:

/requests и /stop_requests. Первая команда добавит в базу подписку на рассылку информации о запросах на сайт, вторая команда — удалит эту подписку. Далее необходимо создать свой context processor — это можно сделать в большинстве современных MVC фреймворков. В его коде необходимо обработать подписки на рассылку и далее отправить сообщения в чат с указанными id, который мы предварительно сохранили в базу, когда нам пришел запрос на наш webHook url. Так же мы можем оформлять подписки на абсолютно любые события на своем сайте: регистрации пользователя (удобно реализовывать через сигналы), комментарии, ошибки. Простор для творчества просто бездонный. На своем ресурсе born2fish, где можно редактировать информацию о реках и озерах Мира, я использовал бота для получения информации о том, когда сущность водоема кто-то изменял. Это помогает оперативно получать сообщения о водоемах, требующих проверки модератором.

Сама отправка сообщения зависит от реализации. На python она выглядит так:

def _send_msg(bot, chat_id, message):
    bot.sendMessage(chat_id=chat_id, text=message)

А вот так может выглядеть функция обработки подписок и отправки информации о запросе:

def send_requests_subscriptions(request, city):
    """ send Telegram messages to subscribed users """
    bot_message = request.META['HTTP_USER_AGENT'] + " request from " + get_client_ip(
        request) + " (" + str(city['city']) + ") url = [" + request.path_info + "]"
    subscriptions = RequestsSubscription.objects.all()
    for subscr in subscriptions:
        _send_msg(bot=bot, chat_id=subscr.chat_id, message=bot_message)

Этот метод позволяет отобразить пользователю помощь, которая считывается из файла help.md:

def _display_help():
    return render_to_string('help.md')

Вместо заключения


На словах все кажется очень простым, но отмечу, что таких ботов трудно тестировать. Оптимальным решением станет Unit Test, в котором вы будете симулировать запрос от telegram и проверять работу бизнес логики бота.

Что еще может пригодится? Не всегда информация в профиле пользователя telegram заполнена полностью, так что следует проверять значения на None перед сохранением в базу, чтобы не получить IndexError.

Вы можете добавить своего бота в группу. Это поможет не рассылать информацию каждому пользователю, а отправлять ее в единое место, откуда она уже будет доступна всем желающим. Сделать это можно через интерфейс клиента telegram, в настройках вашего бота и вашей группы.
В качестве примера хочу поделиться ссылкой на своего тестового бота: @born2fishBot, Напишите ему /help чтобы получить список возможных команд.

Телеграм — замечательное приложение, которое открывает новые горизонты программистам, администраторам да и простым пользователям. Используя нововведения, можно получить ощутимую выгоду от использования telegram ботов, при совсем небольших временных затратах на разработку. Получайте все самые свежие данные о состоянии вашего веб ресурса первым. И пусть эти новости будут только приятные.
Поделиться с друзьями
-->

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


  1. mihmig
    25.11.2016 17:04
    +3

    Можно исключить одно звено из Вашей цепочки, убрав нетривиальную настройку HTTPS и сертификата, а именно:
    При наступлении какого-либо события вызывать URL:
    https://api.telegram.org/botBOT_ID:BOT_TOKEN/sendmessage?chat_id=CHAT_ID&text=test *test* test&parse_mode=Markdown

    Некоторые сервисы мониторинга позволяют в случае «алерта» «дёргать» произваольный URL.


    1. born2fish
      26.11.2016 14:05

      Спасибо, об этом не знал — очень пригодится. Однако с установкой SSL сертификата я бы не советовал затягивать? т.к. в скором времени поисковые роботы будут применять санкции к сайтам не поддерживающим протокол https


  1. chemistmail
    25.11.2016 17:26
    +2

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

     $ cat .procmailrc                                                                                                                                                                                                                                                   [14:20:32]
    # send message to telegram
    #
    :0b:
    | $HOME/telegram
    
    chemist@monitoring: /opt/prometheus
     $ cat telegram                                                                                                                                                                                                                                                      [14:20:40]
    #!/bin/zsh
    #
    #
    DEVOPS="GROUPID"
    BOT=BOTID
    BOT_TOKEN=bot token here
    
    BODY=$(< /dev/stdin)
    
    alias urlencode='python -c "import sys, urllib as ul; print ul.quote(sys.argv[1])"'
    
    URL="https://api.telegram.org/${BOTID}:${BOT_TOKEN}/sendMessage?chat_id=${DEVOPS}&text=$(urlencode ${BODY})"
    
    /usr/bin/curl -i -X GET ${URL}
    


    1. born2fish
      26.11.2016 14:06

      спасибо, буду пробовать!
      zsh — интересная оболочка


    1. mihmig
      26.11.2016 21:58

      Про procmail поясните пожалуйста подробнее


      1. born2fish
        26.11.2016 22:48

        Ну отправил письмо на почту, сработало прерывание, выполнился скрипт telegram, в котором отработал запрос на url sendMessage…
        В файле procmailrc указано, какие действия надо предпринять после получения сообщения.
        Как-то так.


  1. Erelecano
    26.11.2016 11:56
    +2

    Есть замечательный https://github.com/ableev/Zabbix-in-Telegram от ableev, пишущий сообщения заббикса в Телеграм. Нужд изобретать какие-то еще велосипеды не вижу.


    1. born2fish
      26.11.2016 14:02

      Мой телеграм бот анализирует прогноз погоды на 24 часа, состоящий из 9 показателей. После этого он формирует прогноз клева рыбы на основе состояния этих показателей, нетрудных математических операций и собственного опыта, а следом отправляет этот прогноз всем, кто прежде отправил ему команду /forecast
      Что касается zabbix — я не сторонник аналогичных решений и это все же несколько иной функционал, нежели описан в статье. Те, кто отправил команду /requests боту @born2fishBot, начнут получать от него сообщения о каждом запросе на сайте born2fish.ru. Это не требует установки стороннего софта на сервер — достаточно создать бота и добавить отправку сообщения в context processor, как бы он у вас не выглядел. Это позволяет в режиме реального времени следить за индексацией сайта роботами, за брутфорсом http форм, за процессом регистрации пользователей, а так же еще много всего. По сути это аналог tail -f /var/log/nginx/access.log, который приходит вам в телеграм.


  1. Urn
    26.11.2016 22:18
    +2

    Если кому-то нужен мониторинг на основе телеграм бота, то я для себя и всех желающих сделал https://trafficrobot.tk/


    1. Angel2S2
      28.11.2016 10:26

      Классный бот у вас! Удобно использовать как обвязку для email уведомлений.
      А исходники, случаем, не открыты?


      1. Urn
        28.11.2016 14:43

        Хмм. Может открыть, действительно.


        1. Angel2S2
          28.11.2016 14:54

          А почему-бы и нет :) Если вам кода «не жалко» и/или не преследуете коммерческих целей почему бы не сделать вклад в сообщество.