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


Довольно простым решением данной проблемы мне показалось для включения отладки бота открыть адрес в браузере, который переведет бота на сервере в отладочный режим, позволяя используя вкладку браузера как промежуточное звено получать ответы уже с рабочей машины.


Под катом Вы найдете ссылку на код, написанный на PHP, но описывать я буду только алгоритм действий, не приводя самого кода.


Проект можно найти на GitHub. Файлы проекта необходимо скопировать себе на сервер, а подключается отладчик к коду бота всего одной строчкой:


include_once( "telegramDebug/debug.inc" );

Этот код должен быть указан до начала любой деятельности самого бота. Лучше всего самой первой строкой веб-хука. В файле index.html необходимо указать локальный путь до веб-хука.


На чём основан принцип отладки


Когда сервер Telegram присылает обновление, то ему совершенно не интересно, что вернет ему веб-хук, потому что для любой операции (отправка сообщения пользователю и т.п.) веб-хук должен сделать запрос к API Telegram. Это очень сильно помогает, потому что в таком случае запрос к API может выполнять не веб-сервер, а рабочая машина, на которой ведется разработка бота. Нужно только заставить рабочую машину сделать этот самый запрос к API, вместо веб-сервера и в отличие от Telegram нам будет очень интересно что вернет веб-хук, потому что он может вернуть предупреждение или сообщение об ошибке, которые помогут отлаживать бота.


Алгоритм работы отладчика


  1. Получаем сообщение от сервера Telegram прежде самого бота.
  2. Если для чата из которого получено сообщение включена отладка, то помещаем сообщение в очередь на отправку на рабочую машину и прекращаем работу веб-хука.
  3. Открытая в браузере вкладка используя long-pooling получает от отладчика сообщение, ранее помещенное в очередь, и перенаправляет его веб-хуку, который расположен на локальной машине.
  4. Локальный веб-хук будет обрабатывать это сообщение точно так же, как он бы сделал это находясь на боевом сервере, никаких специальных изменений в код не требуется.

Алгоритм действий для включения отладки


1. Открываем в браузере адрес веб-хука по протоколу http (не https), добавив к нему адресу параметр debug=manage в результате увидим страницу (может меняться со временем в лучшую сторону):



2. Если не знаем свой ID, то просто пишем что-нибудь боту в Telegram:



3. Включаем режим отладки, указав конкретные ID, разделенные ;, для которых этот режим будет работать. Таким образом пользователи бота будут продолжать получать сообщения от "боевой" версии бота, а мы от разрабатываемой версии.


4. Пишем боту в Telegram, отлаживаем код бота не затрагивая при этом "боевой" сервер. Пусть всё прошло без ошибок, тогда видим:



5. Попробуем в коде бота на рабочей машине вызвать несуществующую функцию create_message_help:




Если Вам это пригодится, но хотелось бы что-то улучшить- приглашаю присоединиться к проекту на ГитХаб.

Поделиться с друзьями
-->

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


  1. centur
    03.01.2017 08:49

    А читать\переписывать запросы в Fiddler не помогает?


    Открываем фиддлер, нажимаем Ctrl+R, находим


     static function OnBeforeRequest(oSession: Session) {

    И добавляем туда что-то типа


    if (oSession.host.toLowerCase() == "myServerWithWebHook.com") {oSession.host = "localhost"; }

    теперь все запросы к myServerWithWebHook.com будут перенаправляться к localhost, на лету, можно и по https (Фиддлер умеет mitm https со своими сертификатами).


    Уверен что под не-Windows платформы есть не менее продвинутые перехватчики http запросов где можно сделать то же самое. Весело и кроссплатформено, не зависит от языка разработки и сторонних скриптов.


    1. ReinRaus
      03.01.2017 09:33

      Не совсем понял на каком этапе будет стоять фиддлер:


      1. Пользователь пишет что-нибудь в приложение Telegram.
      2. Приложение отправляет запрос серверу Telegram
      3. Сервер Telegram отправляет запрос веб-хуку.
      4. Веб-хук отправляет запрос API Telegram
      5. Telegram возвращает ответ в приложение.

      Это стандартная цепочка, без всяких отладчиков. На каком этапе должен быть встроен фиддлер?


      1. centur
        04.01.2017 01:17

        Если вы пишите что получаете запрос на локальную копию приложения ( у вас на машине) — значит где-то у вас уже есть прохождение пакетов через машину разработчика. Если оно уже есть — все манипуляции можно делать через переписывание сетевого траффика в том числе и в https


        Если просто хотите увидеть что приходит в вебхуке или проиграть его на копии своего приложения запущенного локально — http://requestb.in/
        https://zapier.com
        и десятки других сервисов которые это делают проще и удобнее
        Это все можно настроить так чтобы вебхуки прилетали не только в основное рабочее приложение, а их копии куда-либо записывались или на отладочный сервер постоянно шли.


      1. centur
        04.01.2017 01:21

        Почитал еще комментарии ниже — Zapier на веб-хуках и забыть про языкозависимые велосипеды.


        1. ReinRaus
          04.01.2017 03:30
          -2

          А напишите статью, как легко и просто отлаживать телеграмм? С удовольствием почитаю.


        1. ReinRaus
          04.01.2017 03:39
          -2

          Введите в гугле «Отладка бота telegram» или «telegram bot debug». Там такая ниша для написания статей — ведь по запросу все ссылки ведут на мой способ и на жутко неудобные реверс прокси.


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


  1. madmages
    03.01.2017 10:27
    +1

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


    1. ReinRaus
      03.01.2017 10:31

      То есть Вы направляете веб-хук на рабочую машину и таким образом ничего не подозревающие пользователи бота получат отладочный код бота и локальную базу данных (если бот использует бд)?
      Для использования в быту мой способ заключен в двух действиях:


      1. Открыть вкладку в браузере
      2. Нажать кнопку «Применить».

      Буду рад услышать подробнее про Ваш способ, который проще этих двух действий.


      1. madmages
        03.01.2017 10:35
        +1

        ни разу не нуждался в том чтобы дебажить на живье. А вам часто нужно?


        1. ReinRaus
          03.01.2017 10:46

          Ну так опишите Вашу схему. Мне самому интересно.
          У меня всё происходит по цепочке: рабочая машина — GIT — деплой на боевой сервер, то есть любое минимальное изменение кода бота должно быть зафиксировано в git.
          Жутко неудобно.
          Начал искать по запросу «отладка бота telegram» увидел советы только для одного способа:
          Указывать в качестве веб-хука нечто вроде https://noip.com/hook.php и настроить на noip.com форвард на локальную машину.
          Считаю этот способ не удобным:


          1. В качестве веб-хука задан «левый» адрес
          2. Форвардинг происходит для всех пользователей бота, если хочется тестировать, то надо завести еще одного бота, исключительно для тестов.

          Поделитесь своей схемой отладки. Если я не вижу очевидного- буду рад, чтобы мне это показали.


          1. madmages
            03.01.2017 11:03

            Есть тестовая среда — тестовый бот, локальная машина, разработка бота идет только одним человеком.
            Есть боевая среда — боевой бот, гит и прочее.

            Наредактировал на локальной машине, пуш на боевую.

            На локальной машине динамический айпи был и у меня провайдер который мне давал хост по умолчанию типа [my-ip].mega-xxx-provider.ru. В начале разработки запускал скрипт который генерил сертификат и пушил в телеграм новый вебхук на текущий хост. Было нормально, раз запускаешь в начале разработки и хватает до следующего реконекта к провайдеру(очень редко бывает). Но щас еще проще. Статический айпи и это звено выпало.
            В итоге просто тестовая и продакшн среды.

            В общем только щас сообразил что у вас такого может и не быть и такая ситуация специфична в моем случае;)


            1. ReinRaus
              03.01.2017 13:22

              Собственно, я так и представлял в общих чертах. Мне удобнее открыть вкладку в браузере. Первоначальная настройка происходит всего один раз, потом нет необходимости в действиях, кроме описанных чуть выше двух простых шагов.


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


  1. tmnhy
    03.01.2017 10:50

    > Когда сервер Telegram присылает обновление, то ему совершенно не интересно, что вернет ему веб-хук

    Соврамши. Он ждет HTTP 200.

    > Отладка бота Telegram на localhost

    Используем реверс прокси. Я не думаю, что ваш сервис, обрабатывающий хуки, голой частью тела смотрит в инет?


    1. ReinRaus
      03.01.2017 13:41

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


      Реверс-прокси это ровно то же, о чем говорит madmages, а значит обладает теми же недостатками:


      1. Необходимость в отдельном боте для тестов
      2. Невозможность увидеть ошибки и нотификации, которые вернул веб-хук.

      Особых преимуществ перед моим способом нет, или я их не вижу.
      Буду рад конструктивно обсудить недостатки моего способа в сравнении с реверс-прокси. Результаты обсуждения потом внесу в текст статьи.


      1. tmnhy
        03.01.2017 13:51

        > даже если веб-хук упадет с фатальной ошибкой- разработчик этого никак не увидит

        А telegram продолжит долбить сообщениями, пока не получит 200 в ответ или какие у него там лимиты на рассылку updates… Так что, наверное, ему всё-таки интересно что вернет сервис.

        > 1. Необходимость в отдельном боте для тестов

        А как иначе?

        > 2. Невозможность увидеть ошибки и нотификации, которые вернул веб-хук.

        Кому как, вот мне привычнее логгирование в файл.

        > Буду рад конструктивно обсудить недостатки моего способа

        Вы нетрадиционно смешиваете рабочую и тестовую среду.


        1. ReinRaus
          03.01.2017 14:29

          А еще есть нотификации, которые чаще всего являются потенциальной ошибкой, но скрипт завершается с кодом 200.


          1. Можно без него.
          2. Кому как. Мне удобнее переключиться с вкладки веб-телеграмм на вкладку отладки, чем открывать файл с логом.
          3. Смеси не происходит, если создавать в git отдельную ветку для внесения изменений в код бота, на боевой сервер деплоить только master.

          В-целом Вы правы, есть что-то ненормальное в том, что боевой код вместо себя вызывает тестовый. Это (лично для меня) адекватная цена за более удобную отладку.


          1. tmnhy
            04.01.2017 10:00

            > А еще есть нотификации, которые чаще всего являются потенциальной ошибкой, но скрипт завершается с кодом 200.

            Я не очень понял, что вы хотите сказать…
            Серверу telegram надо знать доставил он обновления или нет, всё остальное на совести вашего обработчика. Поэтому важно возвращать HTTP 200, если вы не хотите повторной доставки, независимо от внутреннего состояния вашего обработчика.

            По остальному, вы почему-то упираете на технические детали. А по сути, если у вас рабочий вариант — его уже не нужно дебажить. Если у вас проект в разработке, то занимайтесь отладкой локально, зачем деплоить и тем более пускать в эксплуатацию сырой проект.

            Хинт. Назовите свой метод и статью «Мониторинг состояния telegram-бота...» и некоторые вопросы о целесообразности отпадут.


      1. bohdan4ik
        04.01.2017 01:25

        > ему все-равно что содержится в теле ответа

        Нет.

        Он ожидает увидеть корректный вызов метода API, что, теоретически, может позволить отодвинуть лимит сообщений/с. А ещё, да, ожидает HTTP Status OK.

        https://core.telegram.org/bots/api#making-requests-when-getting-updates


  1. madmages
    03.01.2017 11:01

    del


  1. Devgru
    03.01.2017 11:56

    А чем поллинг хуже веб-хука для бота? Задержки?


    1. ReinRaus
      03.01.2017 13:32

      Не понял вопроса. Лонг поллинг в данном случае служит для доставки пришедшего сообщения с хука-на-сервере хуку-на-локалхосте.
      Скорость отклика бота уменьшается на: 100мс (частота проверки, что появились новые сообщения) + пинг (сервер-локалхост)+пинг (локалхост-сервер телеграмм). При самых худших условиях обработка сообщения на локальной машине за счет сетевых задержек будет примерно на полсекунды дольше, чем это сделал бы веб-хук на сервере. Эту задержку видит только разработчик, она мала, поэтому не критично.


      1. Devgru
        03.01.2017 14:04

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


        1. ReinRaus
          03.01.2017 14:16

          Согласен. Если использовать запрос к апи вместо веб-хука, то можно отлаживать более удобным способом, но тогда появляется задержка. Веб-хуки дают более быстрый отклик бота.
          Статья начинается со слов «Когда для бота Telegram установлен веб-хук...»


  1. Artyushov
    03.01.2017 13:57

    A ngrok.com — это не то, что идеально подходит для изначальной задачи?


    1. ReinRaus
      03.01.2017 14:11

      А как Вы узнаете, что веб-хук выдал нотификацию или ошибку?


      1. Artyushov
        03.01.2017 14:51

        Я не понял ваш вопрос, но на всякий случай поясню свой комментарий.

        Если вы хотите подебажить бота с веб-хуком:

        1. Запускаете бота на локальной машине
        2. Прокидываете туннель с помощью ngrok, получаете публичный url для бота
        3. Настраиваете веб-хук на этот url
        4. Все уведомления для бота приходят на локальную машину

        Это не позволит вам в один клик включить отладку для production бота, зато реализуется очень просто и не требует никакого дополнительного кода.


        1. ReinRaus
          03.01.2017 15:22
          -1

          Отладка включается не для production бота, а для тестового на локальной машине.
          Несомненно Ваш способ проще, чем открыть вкладку в браузере.