Вебхуки

Получайте уведомления о смене статуса ваших прогнозов

Определение

Вебхуки — это способ максимально оперативно получать уведомления о смене статуса вашего прогноза. Использовать его довольно просто - укажите конечную точку при создании запроса в заголовке 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")


Загрузка...

Предыдущая
Прогнозы
Следующая
Playground
Была ли статья полезна?
Содержание: