Уведомления в Telegram Mini App: как слать пуши через бота
У Mini App нет собственных пушей: уведомления приходят как сообщения бота, а писать пользователю можно только после его запуска бота или запроса разрешения requestWriteAccess. Чтобы открыть нужный экран, используйте кнопку web_app или прямую ссылку с параметром startapp. Пользователей, заблокировавших бота, нужно отмечать и не беспокоить.
Mini App открывается внутри Telegram, но собственных push-уведомлений у него нет. Всё, что пользователь получает «вне приложения», это сообщения от бота. Разберём, как это устроено и какие ошибки чаще всего мешают.
Как работают уведомления
Mini App всегда привязан к боту. Когда нужно уведомить пользователя (появился новый объект, цена упала, заказ готов), ваш сервер вызывает метод sendMessage Bot API от имени бота. Сообщение приходит в личный чат с ботом, и Telegram показывает обычное уведомление.
Чтобы бот мог писать пользователю, выполняется одно из условий:
- пользователь запускал бота (нажал «Start»);
- Mini App запросил разрешение на сообщения от бота и пользователь согласился.
Как получить разрешение из Mini App
Если пользователь открыл приложение по прямой ссылке и бота не запускал, у него может не быть разрешения писать. В данных пользователя из initData есть признак allows_write_to_pm. Если он не установлен, запросите разрешение:
const tg = window.Telegram.WebApp;
if (!tg.initDataUnsafe.user?.allows_write_to_pm) {
tg.requestWriteAccess((granted) => {
// granted === true: можно отправлять сообщения
});
}
Метод requestWriteAccess доступен в версиях Bot API 6.9 и новее. Проверьте поддержку в клиентах пользователей и предусмотрите запасной вариант: кнопку «Включить уведомления», которая открывает диалог с ботом.
Не просите разрешение при первом открытии. Лучше всего сделать это в момент, когда оно понятно: после нажатия «Подписаться на новые объявления» или «Сообщить о цене».
Отправка уведомления
Идентификатор личного чата с пользователем совпадает с его user_id. Сервер вызывает:
import requests
def notify(token: str, user_id: int, text: str, app_url: str) -> bool:
r = requests.post(
f"https://api.telegram.org/bot{token}/sendMessage",
json={
"chat_id": user_id,
"text": text,
"reply_markup": {"inline_keyboard": [[
{"text": "Открыть", "web_app": {"url": app_url}}
]]},
},
timeout=10,
)
return r.ok
Кнопка с web_app открывает приложение прямо из сообщения. Токен бота храните на сервере и не отдавайте в приложение.
Как открыть нужный экран
Чтобы уведомление вело на конкретный объект, есть два способа:
- Адрес в кнопке
web_app: добавьте в URL параметры (?item=123), и приложение откроет нужную карточку. Не доверяйте им без проверки на сервере. - Прямая ссылка Mini App вида
https://t.me/<бот>/<приложение>?startapp=item_123. Значение параметра доступно в приложении какstart_paramвinitData.
Ошибки и ограничения
- Пользователь заблокировал бота. Telegram вернёт ошибку (код 403). Пометьте такого пользователя как отписанного и не пытайтесь слать снова.
- Лимиты. Не отправляйте сообщения слишком часто: по правилам Telegram есть ограничения по скорости. Для массовых рассылок используйте очередь и паузы.
- Дубли. Храните, что уже отправлено каждому, чтобы повторный запуск воркера не слал одно и то же. Подробности про защиту от дублей: как не публиковать повторы.
- Частота. Объединяйте события в один дайджест, а не шлите по сообщению на каждое.
- Тихие уведомления. Для неважных событий используйте параметр
disable_notification, чтобы сообщение приходило без звука. - Согласие. Давайте простой способ отключить уведомления прямо в сообщении или приложении.
Где применено
Так работают подписки в наших проектах: пользователь сохраняет критерии в Mini App, а бот присылает уведомление, когда появляется подходящий вариант. Подробнее в разборе архитектуры каталога и в проектах Da Nang House и HotTrip. Услуга: «Telegram-боты и Mini App».
Частые вопросы
Может ли Mini App отправить push сам, без бота?
Нет. Уведомления отправляет бот, к которому привязано приложение.
Нужно ли пользователю нажимать Start, чтобы получать сообщения?
Нужно либо запустить бота, либо дать разрешение на сообщения через `requestWriteAccess`. Без этого бот не сможет написать первым.
Как проверить, что пользователь заблокировал бота?
По ошибке при отправке: Telegram вернёт отказ с кодом 403. После этого не отправляйте ему сообщения и пометьте подписку неактивной.
Как передать данные из уведомления в приложение?
Через параметры адреса в кнопке `web_app` или через параметр `startapp` прямой ссылки. На сервере всегда проверяйте, что пользователь имеет право видеть эти данные.
Версия для ИИ и чтения без оформления: Markdown.