Найти в Дзене
automatization24

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

Оглавление

Есть частый кейс, когда мы хотим получать некоторые сообщения/уведомления в свой телеграмм. Например, наша программа отловила ошибку и остановилась, наступило некоторое важное событие, парсер нашел что-то интересное на сайте и хочется все оперативно увидеть в этом мессенджере. Есть несколько хороших питоновских библиотек для работы с telegram, но я не сторонник их использования по ряду причин. Основное - они являются оболочками для чистого апи. А зачем пользоваться надстройками, если можно убрать лишнее звено? Плюс для продуктовых задач гораздо лучше использовать не истории с бот-пуллингом, а создание приложений, работу в рамках вебхуков.

  1. Принцип взаимодействия с Telegram
  2. Отправка POST-запроса с сообщением пользователю
  3. Отправка через GET-запрос
  4. Отправка кнопок
-2

1. Принцип взаимодействия с Telegram

Всем айти-миром правят jsonы и http-запросы, в которых эти jsonы отправляются. С телеграммом - все то же самое. Он принимает на свои адреса запросы определенной структуры и отправляет свои запросы на ваши обработчики. Документации у него немало, в частности стоит изучить тут https://core.telegram.org/bots/api . Для работы с внешними обработчиками используются созданные в тг боты. И вот от имени бота пользователю, который на него подписан мы можем отправлять сообщения. А иногда и жестко спамить. Но не забываем, что у любых систем есть ограничения на число запросов. В явном виде в доке я таких ограничений не нашел, но на просторах интернета можно встретить такую формулировку:

Отправление ботом сообщений нескольким разным пользователям / в чаты, которые подключены к боту: до 30 сообщений с интервалом от 1 секунды.

В реальности просто между отправками сообщений использую интервалы от 5-10 секунд и пока не нарвался на блок. Для отправки http-запроса в питоне используется библиотека requests, работы с json - библиотека с похожим названием json. И иного нам не нужно. Только узнать из документации, какой метод отправляет сообщение и какие параметры он принимает. Это метод sendMessage. Для старта достаточно всего 2 параметра:

  • chat_id - айди чата, в случае с отправкой лично пользователю совпадает с айди пользователя, отправке в групповой чат/канал - уже их айди;
  • text - текст, который хотим отправить, можно даже вставлять эмодзи и форматирование.

Итого нам нужно:

1. Созданный телеграмм-бот через BotFather, токен от этого бота. Токен является своего рода ключом к взаимодействию. Поэтому храните их всегда в приватности и вне репозиториев.

-3

2. Пользователь, который подписан на этого бота.

-4
На этом этапе мы уже подписались на своего нового бота
На этом этапе мы уже подписались на своего нового бота

3. Узнать свой id в телеграмме. Когда уже будем принимать сообщения на свой обработчик, его легко увидеть по свойству user.id, а пока можно обратиться к какому-то уже готовому стороннему боту, возвращающему айди пользователя, но я предпочитаю покопаться в настройках самого ТГ в десктопной версии:

Пошагово активация настройки отображения id пользователя в tg
Пошагово активация настройки отображения id пользователя в tg

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

-7

2. Отправка POST-запроса с сообщением пользователю

Запрос должен быть отправлен на следующий адрес, показываю в виде f-строки, куда подставите токен:

url = f"https://api.telegram.org/bot{token}/sendMessage"

Адрес, токен бота, метод.

В теле запроса отправляется словарь. В нашем случае из 2х ключей:

txt = 'Текст из питоновского кода'
params = {"chat_id": 11111111111,
"text": txt,}

В chat_id подставим полученный ранее айди пользователя, а в text - то, что хотим отправить:

-8

Весь код отправки сообщения текста от бота в телеграмм может выглядеть очень компактно:

import json
import requests
token = "token"
url = f"https://api.telegram.org/bot{token}/sendMessage"
txt = 'Текст из питоновского кода'
params = {"chat_id": 11111111111,
"text": txt,}
response = requests.post(url, verify=True, data=params)
print(response)
print(response.json())

Если в словарик добавить параметр 'parse_mode': "HTML", то можно отсылать и форматированный текст:

-9

Примеры такого форматирования в доке.

3. Отправка через GET-запрос

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

https://api.telegram.org/bot{token}/sendMessage?chat_id={chat_id}&text={text}

И это можно прямо в браузере в адресной строке вызвать и получить сообщение в свой телеграмм:

-10
-11

Для наглядности тут сделал запрос через браузер, но делать его из кода аналогично, только указав requests.get. Со своей стороны рекомендую использовать все же post, с ним будет понадежнее)

4. Отправка кнопок

Что за бот, который не показывает кнопки? Это не бот) Для in-line кнопок используем в параметрах "reply_markup": buttons, а вот массив buttons опишем в таком виде для примера:

buttons = {"inline_keyboard":
[
[
{
"text": "1",
"callback_data": "1",
'resize_keyboard': True,
},
{
"text": "2",
"callback_data": "2",
'resize_keyboard': True,
},
{
"text": "3",
"callback_data": "3",
'resize_keyboard': True,
}
],
[{
"text": "4",
"callback_data": "3",
'resize_keyboard': True,
}],
[{
"text": "5",
"callback_data": "3"
},
{
"text": "6",
"callback_data": "3"
}
],
],
# 'is_persistent': True,
# 'resize_keyboard': True
}

И вот тут не забудем его перевести в текст:

buttons = json.dumps(buttons)

-12

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