Найти в Дзене

Массовая рассылка сообщений через Telegram бота

На одном из проектов мне необходимо было выполнять рассылку сообщений очень большому кол-ву пользователей, порядка 20к. При массовой рассылке я столкнулся с ограничением на кол-во сообщений в секунду. В посте я расскажу, что это за ограничение и как я решал данную проблему. У Telegram существует мифическое ограничение, которое необходимо учитывать. В документации сказано про некое ограничение в ~30 сообщений в секунду, иначе получишь ошибку HTTP [429] Too Many Requests: Unfortunately, at this moment we don't have methods for sending bulk messages, e.g. notifications. We may add something along these lines in the future. In order to avoid hitting our limits when sending out mass notifications, consider spreading them over longer intervals, e.g. 8-12 hours. The API will not allow bulk notifications to more than ~30 users per second, if you go over that, you'll start getting 429 errors. Также там отмечается, что на данный момент у Telegram нет решения для массовой рассылки. Я допол
Оглавление

Введение

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

Проблема

У Telegram существует мифическое ограничение, которое необходимо учитывать. В документации сказано про некое ограничение в ~30 сообщений в секунду, иначе получишь ошибку HTTP [429] Too Many Requests:

Unfortunately, at this moment we don't have methods for sending bulk messages, e.g. notifications. We may add something along these lines in the future.
In order to avoid hitting our limits when sending out mass notifications, consider spreading them over longer intervals, e.g. 8-12 hours. The API will not allow bulk notifications to more than ~30 users per second, if you go over that, you'll start getting 429 errors.

Также там отмечается, что на данный момент у Telegram нет решения для массовой рассылки.

Я дополнительно заглянул в чат по разработке ботов и нашел сообщение, где говорится примерно следующее: нечего заниматься ерундой и отправлять 100500 сообщений 😂

Решение проблемы

Я решил реализовать рассылку следующим образом:

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

2. Далее я сохранял в специальную таблицу ID этих пользователей и информацию о задаче на рассылку:

> user_id: Идентификатор пользователя
> type: Тип сообщения. Например, «contest» (конкурс), «prize» (приз)
> is_sent: флажок статуса доставки

3. Сделал отдельную задачу, по которой бот раз в 4-5 сек забирает из этой таблички пачку из 30 ID пользователей, у которых флажок is_sent равен NULL, проставляет флажку значение FALSE и начинает процесс рассылки. После удачной отправки сообщения пользователю, флажок is_sent становится равен TRUE. Если по той или иной причине сообщение не удалось доставить (например, пользователь заблокировал бота), то флажок is_sent остается в значении FALSE. Таким образом задача не будет взята в обработку повторно и после рассылки можно будет посмотреть кому не удалось отправить сообщение и далее уже разбираться в причинах. А что с медиафайлами и документами?

Отправка медиафайлов и документов в рассылке

В некоторых рассылках необходимо было отправлять медиафайл/документ + текст.

Здесь я реализовал отдельный механизм загрузки медиафайлов/документов в БД: Присылал боту необходимые файлы и он сохранял их ID в БД. Делалось это для того, чтобы файл хранился на серверах Telegram и в дальнейшем его можно было получить по ID в любой момент. Таким образом нет необходимости хранить лишние файлы на сервере и не надо постоянно обращаться к диску, чтобы получить файл.

Как именно хранить информацию в БД о загруженных файлах?

Я думаю здесь все индивидуально. Для некоторых типов рассылки я создавал отдельную табличку:

> user_id: Идентификатор пользователя
> type: Тип сообщения. Например, «contest» (конкурс), «prize» (приз)
> file_id: ID файла, который необходимо отправить
> is_sent: флажок статуса доставки

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

Итоги

Немного статистики:

~360 пользователей в минуту и ~55 минут на 20к пользователей.

Так как сама рассылка не подразумевала срочности доставки, то такое решение получилось вполне приемлемым. То есть в течение 1 часа все пользователи получили свое сообщение.

#develop #telegram_bot_api #broadcasting