Перейти к содержимому

Создание (регистрация) telegram-бота для отправки уведомлений из устройств умного дома и не только

Добрый день, уважаемые читатели!

В этой статье (и еще нескольких последующих) я хотел бы еще раз обратиться к теме отправки уведомлений в популярный мессенджер Telegram из “сетевых” микроконтроллеров ESP8266 и ESP32. Конкретно в данной статье обсудим только “теоретические” аспекты, регистрацию учетной записи для бота и очень вкратце работу с API (Application Program Interface). Практические способы реализации отправки уведомлений в Telegram изложены в отдельных статьях (можно перейти по ссылкам):

Если вы начинающий любитель-разработчик IoT устройств, то эта статья для Вас. Кроме того, статья может быть полезна не только любителям ковыряться в микроконтроллерах, но и всем разработчикам Telegram – ботов, в том числе и для “взрослых контуперов”. Прочитав эту  статью, вы узнаете:

  • Что такое telegram-бот и зачем нужен какой-то telegram API
  • Как зарегистрировать своего telegram-бота и научить его отправлять сообщения
  • Ради какого ххудожественного замысла добавлять бота в канал или группу
  • Как выяснить идентификатор пользователя (то есть Вас), группы или канала для программного взаимодействия через бота
  • Как форматировать отправляемые сообщения
  • Ну и само собой обсудим некоторые методы telegram API, необходимые в рамках данной статьи

Заметьте – я пока что сознательно избегаю темы обработки на микроконтроллерах команд, отправленных из Telegram, так как как эта тема достаточно сложная и обширная.

Предисловие или почему я опять взялся “за старое”?

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

Почему я выбираю для отправки уведомлений с “умных” устройств именно Telegram? Не sms или push-уведомления, ни Viber, ни Skype, ни Twiter (прости Господи), ни что-то ещё… Да просто потому, что отправка уведомлений через Telegram REST API – это самый простой, удобный и бесплатный способ отправки уведомлений откуда угодно, кому угодно и сколько угодно. Ни один мессенджер не создал такого удобного механизма, насколько мне известно. Ваши сообщения будут синхронно доставлены всем заинтересованным получателям – как на компьютер, как и на смартфон. И воспользоваться этим механизмом может любой желающий – абсолютно легально и бесплатно. Давайте это и обсудим поподробнее.

 


Принципы работы Telegram API

Telegram API (“Application Program Interface” или по-русски “Программный интерфейс для приложений”) – это набор методов на управляющих серверах мессенджера, вызывая которые мы можем выполнять те или иные действия: отправлять сообщения, файлы и картинки, а также получать ответы и обрабатывать их. Через это же API, насколько я могу понимать, работают все программы-клиенты на вашем смартфоне и компьютере.

Для работы с Telegram API не требуется выделенный “белый” IP-адрес (как утверждают некоторые знатоки). Доступ к Telegram API вполне возможен и из-за десятка NAT-ов и через любой 3G~5G-модем без каких-либо дополнительных настроек последних и “проброса портов”. 

Вся работа с Telegram API осуществляется путем отправки серверу HTTPS запросов – GET и POST (подробнее об HTTP(S) запросах вы можете почитать туточки). Внимание: не защищенные HTTP-запросы сервером Telegram REST API не обслуживаются! То есть вы должны “уметь в TLS/SSL“. При обмене любыми данными с сервером должна быть использована кодировка UTF-8. 

Как правило, отправка команд к API и получение ответов производится в JSON-формате. Но не всегда – например сообщение можно отправить серверу простым GET-запросом без каких-либо JSON-ов, но вот ответ от сервера придет всё равно в JSON. И если вы желаете наладить полноценную двухстороннюю связь с API, то вам придется эти ответы “парсить” (или по-русски “разбирать”). Но для простой отправки сообщений все это не требуется – если вам нужны только уведомления, пока забудьте эти страшные слова. 

API Telegram включает большое количество методов, которые позволяют:

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

Различают несколько разных Telegram API, нас в данном случае интересует только Telegram bots API. Да и из него нам будут интересны всего несколько методов:

  • sеndMessage для отправки ботом сообщений получателям (то есть вам)
  • getUpdates для получения списка сообщений или команд, отправленных боту (от вас)

Более подробно про эти методы я расскажу ниже по тексту. Ещё более подробно с Telegram bots API вы можете познакомиться из официальной документации.

Вызов любого необходимого метода REST API осуществляется так:

https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/Method

где:

  • 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 – токен авторизации бота (как его получить, я расскажу ниже)
  • Method – наименование вызываемого метода

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

 


Создание (регистрация) бота

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

Шаг 1. Откройте клиент Telegram и найдите в списке контактов BotFather (можно просто нажать на ссылку):

Шаг 2. Отправьте команду /newbot для создания нового бота, а затем укажите его желаемое понятное имя (понятное имя это НЕ логин):

Какое имя выбрать? Понятное вам и вашей семье. То есть здесь вы можете написать всё по-русски и как вы хотите, в том числе использовать эмодзи – они очень упрощают восприятие уведомлений. Но если вы будете использовать “одну учётку на всех”, то не стоит так украшать.

Шаг 3. Выберите логин для учётной записи бота

А вот тут уже строже: допускается только латиница и имя должно оканчиваться на bot. Если такой логин в базе телеги уже есть, то вам будет выдано соответствующее предупреждение:

Взамен вы получите сообщение, в котором содержится токен авторизации бота: 6778650076:AAHmUJd813aVcvThQLu3YvVKubZz2U5PDAU. Вот этот токен нам будет и нужен во всех последующих экспериментах – сохраните или запишите его в надежном месте. Показывать его публично строго не рекомендуется, но в рамках данной статьи это не страшно, так как к моменту её публикации бот будет удален и токен станет не действителен.

Теперь по желанию можно “доработать напильником” только что созданного бота. То есть добавить картинку, описание и прочую лабуду (впрочем, можно этот этап пропустить, на его работе это никак не отразится). Сделать это проще всего с помощью меню /mybots:

И отредактируйте необходимые поля, например так:

На этом регистрацию бота можно считать завершенной.

Как быть, если у вас есть или планируется несколько умных устройств на ESP? Создавать несколько учёток для ботов для каждого из них или достаточно одной на всех? Только для отправки уведомлений достаточно одной на всех. Но для полноценного двухстороннего “общения” с ботом потребуются индивидуальные боты (иначе API вернёт ошибку при вызове getUpdates). Впрочем, и для уведомлений удобнее иметь разные учётки для разных устройств, ниже я объясню почему. Но здесь есть ограничение: на одну учетную запись пользователя мы можете зарегистрировать не более 20 учёток для ваших ботов

 


Узнаем свой личный chat_id

В принципе, почти всё уже готово для отправки сообщений. Как я уже упоминал выше, для этого нам потребуется метод sеndMessage. Смотрим описание метода и видим, что первым делом нам нужен какой-то chat_id, и без него как без рук никак:

Что это за число или строка? Дело в том, что telegram нас всех посчитал. И присвоил всем и всему уникальные номера – идентификаторы. Как пользователям, так и каналам / группам / чатам. То есть по этому коду-номеру можно однозначно определить получателя сообщения. И это не логин, а именно номер (код). Формат – INT64 со знаком. Для пользователей коды обычно положительные, для групп / каналов – отрицательные. 

Где взять этот код? Хм. Сложный вопрос. Только через тот же самый Telegram API. Для этого воспользуемся другим методом – getUpdates:

https://api.telegram.org/bot6778650076:AAHmUJd813aVcvThQLu3YvVKubZz2U5PDAU/getUpdates

С помощью этого метода мы получаем все сообщения, которые были отправлены боту. Но здесь пока пусто.

Нужно вначале что-то отправить боту. Найдите его в вашем клиенте и нажмите кнопку “Запустить” или “Start”, а затем повторите запрос:

Вы найдете свой личный chat_id в поле message → chat → id (или в данном случае то же самое message → from → id) как на скриншоте выше. Запишите его. Точно так же можно и нужно узнать chat_id для всех родственников, коллег и т.д. (кому вы хотели бы отправлять уведомления).

Допустим, вам нужно будет отправить сообщение сразу 10 получателям. Заценили геморрой? А ведь этим списком получателей нужно еще и управлять (добавлять, удалять и т.д.). Ужос, ужос, ужос. Но не всё так страшно, но об этом ниже.

А пока попробуем что-то да отправить самому себе. Не спешите брать в руки ESP и открывать вашу любимую IDE. Попробуем опять так же – через браузер.

 


Отправляем сообщение от имени бота

Как я уже и писал, воспользуемся методом sеndMessage. Обязательных поля здесь два – chat_id и text. Давайте попробуем вначале “по простому” безо всяких премудростей и JSON:

https://api.telegram.org/bot6778650076:AAHmUJd813aVcvThQLu3YvVKubZz2U5PDAU/sendMessage?chat_id=40?????5&text=test

где:

  • chat_id=40?????5 – это и есть тот самый код, который мы вызнали выше
  • text – текст сообщения (здесь тонкость – в браузере вы можете писать все кириллицей с пробелами, и все будет правильно, но вот на ESP такое не всегда прокатит)

Если вы нигде не ошиблись, то результат будет следующий:

Ура! Заработало!


Добавляем бота в канал или группу

Как я уже упомянул выше – прямая отправка сообщений пользователям крайне не удобна. Это не только затратно по ресурсам и времени, так и перепрошивать вашу ESP придется всякий раз, когда вы пожелаете добавить или удалить получателя уведомлений.

Но есть очень практичный и удобный выход! Заключается он в том, что вы можете создать приватную группу или канал, в которых вы добавите нужных вам пользователей и самого бота. В этом случае бот будет отправлять одно единственное сообщение в группу или канал, а все подписчики одновременно его получат. Все управление списком получателей сводится к управлению списком подписчиков канала или чата. Точно так же работает и обратное управление – любой из членов приватного чата может отправить команду боту и тот её прочитает.

Что выбрать – группу или канал? Если управление ботом не планируется (только уведомления), то можно создать и канал. В противном случае – создайте группу. В любом случае группа всегда удобнее, но это на мой взгляд.

Идентификатор группы или канала вы можете узнать точно так же, как и в предыдущем случае, но теперь строго в message → chat → id. Скорее всего, там будет отрицательное число (но не факт). Но прежде чем делать запрос к API, не забудьте добавить бота в администраторы:

 


Метод sendMessage более подробно

Правильнее всё-таки отправлять сообщения POST – запросом с использованием формата JSON. Для этого потребуется вначале сформировать строку такого вида:

{
  "chat_id":40?????5,
  "text":"Текст сообщения"
}

или, например, так:

{
  "chat_id":40?????5,
  "parse_mode":"HTML",
  "disable_notification":0,
  "text":"Текст сообщения"
}

а потом отправить её тому же самому методу sеndMessage, но уже POST-запросом. Как это сделать в коде Arduino или ESP-IDF, я расскажу в следующих статьях, а пока обсудим дополнительные и не обязательные поля метода sеndMessage:

  • chat_id (обязателен) – Уникальный идентификатор целевого чата или имя пользователя целевого канала
  • text (обязателен) – Текст отправляемого сообщения, 1-4096 символов после анализа сущностей
  • message_thread_id – Уникальный идентификатор целевой ветки сообщений (темы) форума; только для супергрупп форума
  • parse_mode – Режим разбора сущностей в тексте сообщения. Дополнительные сведения см. ниже.
  • entities – Сериализованный в формате JSON список специальных объектов, которые появляются в тексте сообщения и которые можно указать вместо parse_mode.
  • disable_web_page_preview – Отключает предварительный просмотр ссылок в этом сообщении.
  • disable_notification – Отправляет сообщение молча. Пользователи получат уведомление без звука.
  • protect_content – Защищает содержимое отправленного сообщения от пересылки и сохранения.
  • reply_to_message_id – Если текущее сообщение является ответом на другое сообщение, то укажите здесь идентификатор исходного сообщения.
  • allow_sending_without_reply – Передайте значение True, если сообщение должно быть отправлено, даже если указанное сообщение с ответом не найдено.
  • reply_markup – Объект, сериализованный в формате JSON, для встроенной клавиатуры или настраиваемой клавиатуры ответа. Очень интересная опция, которая служит для создания кнопочных меню в чате Telegram.

Применительно к отправке уведомлений меня интересуют два параметра: parse_mode и disable_notification. Всем остальным я обычно не пользуюсь. С disable_notification и так всё ясно, а вот на parse_mode стоит остановиться поподробнее. Эта опция используется для указания способа форматирования сообщения.

 

Форматирование сообщений

Bot API поддерживает базовое форматирование сообщений. В сообщениях ваших ботов вы можете использовать жирный, курсив, подчеркнутый, зачеркнутый текст, а также ссылки и предварительно отформатированный код. Клиенты Telegram будут отображать их заданным вами образом. Вы можете указать текстовые объекты напрямую или использовать форматирование в стиле markdown или HTML.

Сущности форматирования сообщений могут быть вложенными друг в друга при условии соблюдения следующих ограничений:

  • Если две сущности имеют общие символы, то одна из них должна полностью содержаться внутри другой.
  • Объекты жирного шрифтакурсиваподчеркиваниязачеркивания и спойлера могут содержать и быть частью любых других объектов, кроме pre и code.
  • Все остальные стили не могут содержать друг друга.

Соответственно parse_mode задает правила распознавания форматирования текста:

  • MarkdownV2 – стиль разметки, который очень удобно использовать при ручном наборе в клиенте telegram: *bold text*,  _italic text_
  • HTML –  стиль разметки, принятый на сайтах: <b>bold text</b>,  <i>italic text</i>
  • Markdown –  устаревший стиль, не рекомендуется к использованию

Лично я предпочитаю HTML, но это дело вкуса.

 


Метод getUpdates более подробно

Метод getUpdates мы использовали только для того, чтобы узнать идентификатор целевого чата. Но вообще этот метод предназначен для того, чтобы бот мог получать команды и текст в обход NAT-ов. У него так же есть несколько параметров (все опциональные):

  • offset – Идентификатор первого возвращаемого обновления. Должно быть на единицу больше последнего идентификатора ранее прочитанных сообщений. По умолчанию возвращаются обновления, начиная с самого раннего неподтвержденного обновления. Обновление считается подтвержденным, как только вызывается getUpdates со смещением выше, чем его update_id. Отрицательное смещение можно указать для получения обновлений, начиная с -offset с конца очереди обновлений. Все предыдущие обновления будут пропущены.
  • limit – Ограничивает количество получаемых обновлений в одном ответе сервера. Принимаются значения от 1 до 100. По умолчанию 100.
  • timeout – Тайм-аут в секундах для опроса сервера с ожиданием поступления новых сообщений. По умолчанию 0, т.е. обычный короткий опрос. Короткий опрос следует использовать только в целях тестирования.
  • allowed_updates – Сериализированный в формате JSON список типов обновлений, которые необходимо получать вашему боту. Например, укажите [“message”, “edited_channel_post”, “callback_query”], чтобы получать обновления только этих типов.

В ответ REST API вернет вам сериализированный в формате JSON список обновлений (сообщений, файлов, изображений, и т.д.), которые вам необходимо будет распарсить (разобрать на составные элементы), проанализировать и сформировать какую-либо реакцию. Сама себе “разборка” полученного JSON не совсем тривиальная задача, поэтому лучше всего воспользоваться готовыми библиотеками. 


Ограничения Telegram API

Telegram устанавливает следующие лимиты на отправку сообщений ботом (в целях борьбы со спамом):

  • Отправка сообщений конкретному пользователю: не чаще раза в секунду. 
  • Отправка сообщений в группу: не чаще 20 сообщений в минуту
  • Кратковременный лимит сообщений: не чаще 30 сообщений в секунду
  • Бот может прочитать сообщения (команды), с момента отправки которых прошло меньше 24 часов
  • Боты не могут взаимодействовать друг с другом: то есть бот не может писать другому боту напрямую и бот не видит сообщения от других ботов в группе

Отправлять сообщения можно и чаще раза в секунду, но спустя какое-то время после такого баловства API вернет ошибку “Слишком много сообщений” и заблокирует отправку на какое-то время (~ 5 минут). Поэтому если нужно отправить сразу несколько сообщений – можно попытаться, но не увлекайтесь. Иначе просто ничего не дойдёт до получателя.

На этом обзорную часть по Telegram API можно закончить. В следующих сериях я поведаю вам о том, как добавить отправку уведомлений к проекту телеметрии на ESP8266 и MQTT, про который я писал ранее, а так же постараюсь не забыть и о ESP-IDF:

1. Отправка сообщений в Telegram из ESP8266 с использованием фреймворка Arduino

Засим прощаюсь, с вами был Александр aka kotyara12.

 


💠 Полный архив статей вы найдете здесь


Пожалуйста, оцените статью:
[ 5 из 5, всего 1 оценок ]

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *