Перейти до вмісту

Надійне приймання вебхуків Twilio

Цей гайд ставить Railhook між Twilio і вашим застосунком для інформаційних вебхуків Twilio, як-от status callbacks повідомлень. Twilio надсилає їх на джерело Railhook, яке перевіряє підпис, зберігає кожен у тому вигляді, в якому він надійшов, і пересилає на ваш сервіс із повторами.

Чому вебхукам Twilio потрібен буфер

Section titled “Чому вебхукам Twilio потрібен буфер”

За замовчуванням Twilio чекає 5 секунд на з’єднання й 15 секунд на відповідь і повторює вебхук один раз — лише коли не вдалося саме з’єднання. 5xx від вашого застосунку чи повільна відповідь не повторюються, якщо не додати до адреси connection overrides. (Twilio: Webhooks connection overrides)

Тож status callback, що надійшов під час перезапуску застосунку, зазвичай губиться, і ваші записи про доставлені повідомлення розходяться з даними Twilio. З Railhook попереду:

  • Twilio отримує відповідь, щойно callback збережено.
  • Ваш сервіс отримує до 5 спроб на кожне пересилання, з очікуваннями від 1 хвилини до 1 години, а те, що все одно не вдалося, потрапляє в «Невдалі пересилання».
  • На callback з I-Twilio-Idempotency-Token, який Railhook уже зберіг, відповідають збереженою копією, і його не пересилають удруге.

Знадобляться проєкт Railhook і API-ключ. Усе нижче також можна зробити в розділі Вхідні панелі керування.

Terminal window
export RAILHOOK_URL=https://railhook.io # or your own instance
export RAILHOOK_API_KEY=...
export PROJECT_ID=...
  1. Створіть джерело з вашим auth token із Twilio Console. Twilio підписує ним свої запити:

    Terminal window
    curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources" \
    -H "X-API-Key: $RAILHOOK_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"name":"Twilio","providerType":"TWILIO","verificationMode":"PROVIDER","hmacSecret":"'"$TWILIO_AUTH_TOKEN"'"}'

    Збережіть id і ingressUrl із відповіді.

  2. Додайте призначення — адресу вашого сервісу:

    Terminal window
    curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources/$SOURCE_ID/destinations" \
    -H "X-API-Key: $RAILHOOK_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"url":"https://api.example.com/webhooks/twilio","authType":"BEARER","authConfig":"{\"token\":\"...\"}","enabled":true}'
  3. Передайте адресу Twilio. Вказуйте ingressUrl точно так, як його показує джерело, скрізь, де Twilio приймає адресу status callback, наприклад у параметрі StatusCallback під час надсилання повідомлення. Залиште метод POST: інших ingress не приймає.

  4. Надішліть повідомлення. Його status callbacks з’являться в розділі Вхідні → Отримані, з одним пересиланням на кожне призначення.

Як перевіряється підпис

Section titled “Як перевіряється підпис”

X-Twilio-Signature від Twilio — це base64 HMAC-SHA1, обчислений з auth token. Для запиту у form-encoded він охоплює адресу, за якою йдуть усі параметри, відсортовані за назвою; для інших запитів — адресу, а параметр запиту bodySHA256 має збігатися з тілом. Запит, що не збігається, отримує 401 і не зберігається.

Тіло точно таке, яким його надіслав Twilio, байт у байт, з його form-encoded Content-Type, тож ваш сервіс розбирає його так само, як прямий callback. X-Twilio-Signature не пересилається, та й не пройшов би перевірку з вашою адресою: ваш сервіс автентифікує Railhook за обліковими даними призначення. Див. Призначення.

  1. Встановіть CLI й увійдіть, як описано в CLI, а потім відкрийте тунель до порту вашого застосунку:

    Terminal window
    railhook listen 3000
  2. Додайте джерелу друге призначення з виведеною публічною адресою й вашим маршрутом у кінці, наприклад https://<host>/tunnel/<slug>/webhooks/twilio. Запит потрапить на http://localhost:3000/webhooks/twilio.

  3. Надішліть тестове повідомлення з ingress-адресою як status callback, і кожен callback надійде у ваш локальний застосунок. Вимкніть це призначення, коли закриєте тунель.

Повтор подій після збою

Section titled “Повтор подій після збою”

Відтворіть те, що надійшло, поки ваш сервіс лежав. Кожен відтворений callback іде на кожне призначення джерела як нове пересилання:

Terminal window
curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-events/bulk-replay" \
-H "X-API-Key: $RAILHOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"sourceId":"'"$SOURCE_ID"'","from":"2026-09-18T10:00:00Z","to":"2026-09-18T14:00:00Z","verified":true}'

Повтор сягає так далеко, як довго зберігаються події: 7 днів у Railhook Cloud і скільки налаштуєте на власному сервері. Status callback описує стан, тож застосування того самого двічі має бути нешкідливим; переконайтеся, що ваш обробник поводиться саме так. Див. Повтор.