Вебхуки звонков: проверка подписи
Обновлено: 9 октября 2026 · 4 мин чтения
Проверяйте, что запрос действительно пришёл от Clomni, секретным ключом вебхука. Ключ показывается при создании вебхука, а потом есть в окне его редактирования.
Шаги
-
1
Заголовки
X-ChatX-Delivery: id отправки, совпадает сdelivery_idв теле.X-ChatX-Timestamp: время отправки в секундах Unix.X-ChatX-Signature:sha256=и подпись HMAC-SHA256.
-
2
Как считается подпись
Подпись считается от строки
<timestamp>.<тело>секретным ключом вебхука. Не разбирайте JSON и не собирайте его заново: проверяйте исходное тело в том виде, в каком оно пришло. Не принимайте запрос, время которого старше 5 минут. При повторной отправке время и подпись считаются заново,delivery_idостаётся прежним. -
3
Node.js
const crypto = require('crypto'); function verify(rawBody, headers, secret) { const timestamp = headers['x-chatx-timestamp']; const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex'); const given = headers['x-chatx-signature'] || ''; const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300; return fresh && given.length === expected.length && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected)); } -
4
Python
import hashlib, hmac, time def verify(raw_body: bytes, headers, secret: str) -> bool: timestamp = headers["X-ChatX-Timestamp"] expected = "sha256=" + hmac.new(secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256).hexdigest() fresh = abs(time.time() - int(timestamp)) < 300 return fresh and hmac.compare_digest(headers.get("X-ChatX-Signature", ""), expected)