Вебхуки
Определение
Вебхуки — это способ максимально оперативно получать уведомления о смене статуса вашего прогноза. Использовать его довольно просто - укажите конечную точку при создании запроса в заголовке X-Webhook-URL. Как только прогноз сменит статус на ["Succeeded", "Failed"] мы отправим POST запрос на этот URL.
Использование вебхука:
curl https://connecte.ai/api/v1/openai/whisper \
--request POST \
--header "X-Webhook-URL: https://your-app.ru/connecte-url" \
--header "Authorization: Bearer $CONNECTE_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"audio" : "https://site.ru/audio.mp3"
}'
Вебхуки не являются строго обязательными они лишь предоставляют удобный инструмент оперативного получения уведомлений о смене статуса. Для получения выходных данных вы можете опрашивать API с использованием ID прогноза или использовать синхронные запросы.
События вебхуков
Мы будем отправлять уведомления методом POST всякий раз когда ваш прогноз будет переходить в статус succeeded или failed. Для всех других событий вебхук не предусмотрен. Вебхук выглядит точно также как и обычный ответ на запрос создания прогноза, значение output будет содержать выходные данные модели, давайте рассмотрим.
{
"id":"d5a46834-c430-4342-9779-4ea5e76d057d",
"input":{
"audio":"https://your-app.ru/audio.mp3",
"model":"large-v3-turbo",
"diarize":false,
"language":"auto",
"speakers":1,
"word_timestamp":false
},
"status":"succeeded",
"output":{
"segments":{...},
"transcirption":{...},
"translation":{...},
"detected_language":{...}
},
"source":"api",
"runtime":35.4,
"created_at":"2024-06-26T05:26:31.974000Z"
}
Повторные отправки
Отправляя вебхук мы ожидаем, что ваше приложение ответит кодом состояния 2xx, обозначая, что вебхук корректно принят и обработан. В случае если нам не удается доставить (получаем ошибку 4xx или 5xx, ответ не получен в течение 10 секунд) вебхук до вашего приложения мы будем повторять попытку до 3-х раз пока не получим статус 2xx.
Для предотвращения повторной обработки дублирующих вебхуков необходимо обеспечить идемпотентность в вашем приложении.
Проверка подписи
Проверка webhooks важна для защиты от поддельных запросов. Чтобы предотвратить несанкционированные попытки мы используем HMAC-подписывание. Перед обработкой вебхука вы можете проверять подпись используя секретный ключ, доступный в личном кабинете на вкладке "Вебхуки", это позволит вам убедиться, что webhook действительно отправлен с наших серверов, а не злоумышленником, пытающимся выдать себя за сервис.
Каждый вебхук содержит 3 заголовка - X-Webhook-ID, X-Webhook-TIMESTAMP, X-Webhook-SIGNATURE. Рассмотрим каждый из них.
- X-Webhook-ID - уникальный идентификатор, при повторных попытках ID не меняется, вы можете использовать это для настройки идемпотентности
- X-Webhook-TIMESTAMP - метка времени в формате Unix-время отправки вебхука. Используйте для сверки времени отправки и получения, разница должна находится в разумных пределах.
- X-Webhook-SIGNATURE - сигнатура, которую можно сверять для проверки подлинности запроса. Используем алгоритм HMAC-SHA256 для создания подписи, полученную подпись кодируем в Base64 для удобства передачи. Подпись формируется строго по заданному шаблону:
signed_content = f"{webhookID}.{timestamp}.{body}"
Пример как можно вычислить подпись на Python.
SECRET_KEY = "your_secret_key_here"
def verify_signature(signature, webhookID, timestamp, body):
message = f"{webhookID}.{timestamp}.{body}"
expected_signature = base64.b64encode(
hmac.new(
SECRET_KEY.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
).digest()
).decode('utf-8')
return hmac.compare_digest(signature, expected_signature)
@app.route('/webhook', methods=['POST'])
def webhook():
webhookID = request.headers.get('X-Webhook-ID')
timestamp = request.headers.get('X-Webhook-TIMESTAMP')
signature = request.headers.get('X-Webhook-SIGNATURE')
body = request.get_data(as_text=True)
if not webhookID or not timestamp or not signature:
abort(400, "Missing required headers")
if not verify_signature(signature, webhookID, timestamp, body):
abort(401, "Invalid signature")