Як надійно отримувати вебхуки GitHub
GitHub надсилає вебхуки на джерело Railhook. Джерело перевіряє підпис, зберігає кожну доставку такою, якою вона надійшла, і пересилає її у ваш сервіс із повторними спробами. Поки сервіс лежить, вебхуки чекають у Railhook.
Чому вебхукам GitHub потрібен буфер
Section titled “Чому вебхукам GitHub потрібен буфер”GitHub не доставляє невдалі вебхуки повторно автоматично. Повторити доставку можна вручну або через API, але лише за останні 3 дні. (GitHub: Handling failed webhook deliveries, Redelivering webhooks) Ваш сервер має відповісти 2xx протягом 10 секунд. (Best practices for using webhooks)
Деплой, падіння чи повільний обробник у невдалий момент губить подію push, pull request чи issue. Коли попереду стоїть Railhook:
- Railhook відповідає GitHub, щойно збереже доставку, задовго до спливу 10 секунд.
- Ваш сервіс отримує до 5 спроб на кожне пересилання з інтервалами від 1 хвилини до 1 години.
- Те, що так і не вдалося доставити, потрапляє в «Недоставлені пересилання», а будь-яку збережену доставку можна відтворити, доки зберігаються події.
- Повторна доставка від GitHub має той самий ідентифікатор
X-GitHub-Delivery. Railhook його розпізнає, відповідає202зі збереженою копією і вдруге її не пересилає.
Підключення GitHub
Section titled “Підключення GitHub”Знадобляться проєкт Railhook і API-ключ. Ті самі кроки є в панелі керування, у розділі «Вхідні».
export RAILHOOK_URL=https://railhook.io # or your own instanceexport RAILHOOK_API_KEY=...export PROJECT_ID=...-
Виберіть секрет. У GitHub секрет вебхука ви задаєте самі:
Terminal window export GITHUB_WEBHOOK_SECRET=$(openssl rand -hex 32) -
Створіть джерело з цим секретом:
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":"GitHub","providerType":"GITHUB","verificationMode":"PROVIDER","hmacSecret":"'"$GITHUB_WEBHOOK_SECRET"'"}'Збережіть
idіingressUrlіз відповіді. -
Зареєструйте вебхук у GitHub. У репозиторії чи організації відкрийте Settings → Webhooks → Add webhook. Вставте
ingressUrlу поле Payload URL, у Content type виберітьapplication/json, у Secret вставте той самий секрет і позначте потрібні події. -
Додайте призначення, URL вашого сервісу:
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/github","authType":"BEARER","authConfig":"{\"token\":\"...\"}","enabled":true}' -
Перевірте ping. Під час створення вебхука GitHub надсилає подію
ping. Вона з’явиться в Railhook у розділі «Вхідні» → «Отримані».
Як перевіряється підпис
Section titled “Як перевіряється підпис”Railhook читає X-Hub-Signature-256 (sha256=, а за ним HMAC-SHA256 необробленого тіла в hex) і порівнює його з підписом, який сам обчислив із секретом джерела. На запит, що не збігається, Railhook відповідає 401 і не зберігає його. Підпис, який уже траплявся в межах вікна захисту від повторного використання (типово 5 хвилин), теж відхиляється, якщо тільки запит не є повторною доставкою того, що Railhook уже зберіг.
Що отримує ваш сервіс
Section titled “Що отримує ваш сервіс”Тіло точно таке, яким його надіслав GitHub, байт у байт. Оскільки push та issue за тілом не розрізнити, Railhook передає далі заголовки подій GitHub: X-GitHub-Event, X-GitHub-Delivery, X-GitHub-Hook-ID, X-GitHub-Hook-Installation-Target-Type і X-GitHub-Hook-Installation-Target-ID. X-Hub-Signature-256 не пересилається: ваш сервіс автентифікує Railhook за обліковими даними призначення, тож секрет GitHub йому не потрібен. Див. Призначення.
Локальна розробка з CLI
Section titled “Локальна розробка з CLI”-
Встановіть CLI й увійдіть, як описано в CLI, а потім відкрийте тунель до порту вашого застосунку:
Terminal window railhook listen 3000 -
Додайте джерелу друге призначення: публічну адресу, яку вивела команда, з вашим маршрутом у кінці, наприклад
https://<host>/tunnel/<slug>/webhooks/github. Запит потрапить наhttp://localhost:3000/webhooks/github. -
Зробіть push або відтворіть збережений
pingу Railhook. Повторна доставка з боку GitHub тут не спрацює: вона має той самийX-GitHub-Delivery, тож Railhook відповість збереженою копією і не перешле її. Перевірений вебхук надійде у ваш локальний застосунок із заголовкомX-GitHub-Event. Коли закриєте тунель, вимкніть це призначення.
Відтворення після збою
Section titled “Відтворення після збою”Кожна відтворена доставка піде на кожне призначення джерела як нове пересилання:
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}'Тут немає обмеження в 3 дні: відтворити можна все, що ще зберігається: 7 днів у Railhook Cloud і скільки налаштуєте на власному сервері. Зробіть обробник ідемпотентним за X-GitHub-Delivery, бо відтворення може надіслати доставки, які ваш сервіс уже обробив. Див. Відтворення.