from maxo.bot.methods.base import MaxoMethod
from maxo.bot.methods.markers import Body
from maxo.omit import Omittable, Omitted
from maxo.types.simple_query_result import SimpleQueryResult
[документация]
class Subscribe(MaxoMethod[SimpleQueryResult]):
"""
Подписка на обновления о новых событиях через Webhook
Метод настраивает доставку событий бота через Webhook - основной механизм получения событий в продуктовых интеграциях. При активной подписке Long Polling не работает
> !
> - Для повышения безопасности **с 25 мая** прекращается поддержка получения вебхуков по HTTP, а также самоподписных сертификатов. Рекомендуем заранее перейти на HTTPS и сертификаты от доверенных центров. Чтобы обновить подписку на события, используйте текущий метод
> - Получение обновлений с помощью [Long Polling](https://dev.max.ru/docs-api/methods/GET/updates) ограничено по скорости и сроку хранения событий - этот способ не подходит для production-окружения. Рекомендуем на всех этапах работы использовать [Webhook](https://dev.max.ru/docs-api/methods/POST/subscriptions)
## Модель доставки событий
После вызова метода `POST /subscriptions` события отправляются на указанный Webhook-endpoint в виде HTTPS POST-запросов с объектом [`Update`](https://dev.max.ru/docs-api/objects/Update)
Как обрабатывается событие:
1. При наступлении события выполняется вызов Webhook-endpoint
2. Выполняется TLS-валидация целевого endpoint для безопасной передачи данных
3. На endpoint отправляется HTTPS-запрос
4. Если при создании подписки указан `secret`, проверяется заголовок `X-Max-Bot-Api-Secret`
5. При успешной валидации возвращается HTTP `200 OK`
6. Выполняется обработка события
7. Инициируются вызовы MAX API
## Требования к Webhook-endpoint
### URL и порт
Webhook-endpoint должен быть доступен по HTTPS на порту 443. Ваш сервер должен прослушивать этот порт. Порт в URL не указывается:
```
https://your-domain.com/webhook
```
> Поддерживается только порт 443. Если endpoint недоступен, события не доставляются
### Безопасность соединения (TLS)
Перед отправкой событий устанавливается HTTPS-соединение, и Webhook-endpoint проверяется на соответствие следующим требованиям безопасности соединения:
- Webhook-endpoint удостоверен TLS-сертификатом, выданным доверенным центром сертификации. Самоподписанные сертификаты не поддерживаются
- Доменное имя в URL Webhook-endpoint совпадает с CN или SAN сертификата
- Сервер предоставляет полную цепочку сертификатов
> Если проверка не пройдена, события не доставляются
### Обработка запросов
Webhook-endpoint должен возвращать **HTTP 200** в течение 30 секунд. Любой другой код ответа или превышение тайм-аута считается ошибкой доставки
#### Пример запроса:
```bash
curl -X POST "https://platform-api.max.ru/subscriptions" \
-H "Authorization: {access_token}" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-domain.com/webhook",
"update_types": ["message_created", "bot_started"],
"secret": "your_secret"
}'
```
### Политика повторных попыток
Если доставка не удалась, выполняется до 10 повторных попыток с экспоненциально растущим интервалом:
- 1-я попытка: через 60 секунд
- 2-я попытка: через 150 секунд (60 × 2,5)
- 3-я попытка: через 375 секунд (150 × 2,5)
- и так далее
> Если в течение 8 часов от Webhook-endpoint не получен успешный ответ, бот автоматически от него отписывается
## Безопасность Webhook-запросов
Параметр `secret` позволяет убедиться, что Webhook-запросы приходят от MAX, а не от третьей стороны. Это необязательный параметр, но мы настоятельно рекомендуем указывать его. Проверяйте значение заголовка `X-Max-Bot-Api-Secret` на Webhook-сервере и отклоняйте запросы при несоответствии
Если `secret` указан при создании подписки, он передаётся в заголовке `X-Max-Bot-Api-Secret` каждого Webhook-запроса
---
## Формат и типы событий
Webhook-запрос содержит объект [`Update`](https://dev.max.ru/docs-api/objects/Update)
Полный список типов событий и структура объекта описаны в разделе [Update](https://dev.max.ru/docs-api/objects/Update)
Args:
secret: Cекрет, который должен быть отправлен в заголовке `X-Max-Bot-Api-Secret` в каждом запросе Webhook. Разрешены только символы `A-Z`, `a-z`, `0-9`, и дефис. Заголовок рекомендован, чтобы запрос поступал из установленного веб-узла
update_types: Список типов событий, которые хочет получать ваш бот. Полный список смотрите в описании объекта [Update](https://dev.max.ru/docs-api/objects/Update)
url: URL HTTPS-endpoint вашего бота. Должен начинаться с `https://`
Источник: https://dev.max.ru/docs-api/methods/POST/subscriptions
"""
__url__ = "subscriptions"
__method__ = "post"
url: Body[str]
"""URL HTTPS-endpoint вашего бота. Должен начинаться с `https://`"""
secret: Body[Omittable[str]] = Omitted()
"""Cекрет, который должен быть отправлен в заголовке `X-Max-Bot-Api-Secret` в каждом запросе Webhook. Разрешены только символы `A-Z`, `a-z`, `0-9`, и дефис. Заголовок рекомендован, чтобы запрос поступал из установленного веб-узла"""
update_types: Body[Omittable[list[str]]] = Omitted()
"""Список типов событий, которые хочет получать ваш бот. Полный список смотрите в описании объекта [Update](https://dev.max.ru/docs-api/objects/Update)"""