Безопасность и обработчик
Безопасность
Каждый исходящий вебхук защищён с помощью подписи, основанной на хешировании содержимого. Подпись HMAC с использованием алгоритма SHA256 вычисляется из тела запроса и передаётся в заголовке Pachca-Signature.
В теле вебхука также содержится поле webhook_timestamp — метка времени в формате UNIX, указывающая момент отправки вебхука. Рекомендуется проверять, что это значение находится в пределах одной минуты от времени получения запроса, чтобы предотвратить атаки повторной отправки (replay attacks).
Проверьте подпись
Для проверки подписи необходимо вычислить её самостоятельно, используя секрет вебхука Signing secret с вкладки «Исходящий вебхук» в карточке бота. Через API он приходит в поле webhook.secret_token метода GETИнформация о боте. Рекомендуется использовать сырой (raw) контент тела запроса для вычисления хеша, так как при JSON-парсинге содержимое может быть изменено.
Проверьте IP-адрес отправителя
Кроме подписи стоит проверять, с какого адреса пришёл запрос. Пачка отправляет вебхуки с адресов 37.200.70.177, 185.209.115.174 и 135.106.159.61 — разрешите все три. Актуальный список — в справке Пачки, в статье Порты и адреса для корректной работы Пачки.
Реализация webhook handler
Полный пример обработки вебхуков на TypeScript (Express.js) и Python (Flask) с проверкой подписи, защитой от replay-атак и обработкой всех типов событий.
TypeScript (Express.js)
Python (Flask)
Идемпотентная обработка
Одно и то же событие изредка может прийти дважды, поэтому обработчик должен быть идемпотентным:
Доставка и повторы
Пачка ждёт ответа на событие 5 секунд. Повторно событие отправляется, только если к серверу не удалось подключиться: Пачка пробует ещё до трёх раз с паузами. Если сервер ответил ошибкой или не уложился в 5 секунд, повтора не будет, какой бы код он ни вернул. Ответа на нажатие кнопки Пачка ждёт до 30 секунд, а на отправку формы — 3 секунды: подробнее в разделе Обработка форм.
- Отвечайте
200 OKсразу, а тяжёлую обработку выносите в фоновую очередь. - Чтобы не терять события, пока сервер недоступен, включите историю событий — подробнее в разделе Поллинг.