Перейти к основному содержимому

Webhooks

Webhooks позволяют церкви отправлять уведомления в реальном времени на инструменты третьих сторон — платформы автоматизации (Zapier, Make, n8n), CRM, системы учета или все, что принимает HTTP POST. Когда человек, группа или домохозяйство изменяется в B1, B1 отправляет подписанный JSON-payload на каждый URL, подписанный на это событие.

Перед началом

  • Администратор церкви с разрешением Редактировать параметры церкви регистрирует и управляет webhooks
  • Ваша конечная точка должна быть доступна через HTTPS по открытому адресу
  • Имейте способ безопасно хранить секрет подписания — он отображается только один раз

Обзор

Webhooks являются исходящими только: B1 вызывает вашу конечную точку, вы не вызываете B1. Каждый webhook — это подписка для каждой церкви, состоящая из URL назначения, секрета подписания и списка подписанных событий.

Доставка использует надежный outbox: когда происходит подписанное событие, B1 записывает строку доставки и фоновый рабочий процесс выполняет POST в течение примерно минуты. Неудачные доставки повторяются с экспоненциальной задержкой. Ничего не теряется, если доставка медленная или ваша конечная точка временно не работает.

Регистрация Webhook

В B1Admin

Перейдите в Параметры → Webhooks → Новый Webhook. Введите имя, URL-адрес полезной нагрузки и выберите события для подписки. При сохранении секрет подписания отображается один раз — скопируйте его немедленно и сохраните вместе с интеграцией. Он больше не отображается (вы можете повернуть его позже, но не можете получить оригинал).

Через API

Все конечные точки находятся под базовым путем модуля Membership /membership/webhooks и требуют либо JWT от администратора церкви с разрешением Settings / Edit, либо API ключ выпущенный с областью settings:write. Одни и те же маршруты принимают оба.

POST /membership/webhooks
Authorization: Bearer <jwt>
Content-Type: application/json

{
"name": "Zapier — новые члены",
"url": "https://hooks.zapier.com/hooks/catch/123/abc",
"events": ["person.created", "person.updated", "group.member.added"]
}

Ответ на создание включает secret:

{
"id": "a1b2c3d4e5f",
"name": "Zapier — новые члены",
"url": "https://hooks.zapier.com/hooks/catch/123/abc",
"events": ["person.created", "person.updated", "group.member.added"],
"active": true,
"secret": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822c"
}
Метод и путьНазначение
GET /membership/webhooksСписок webhooks церкви (секрет исключен)
GET /membership/webhooks/eventsКаталог допустимых названий событий
GET /membership/webhooks/:idЗагрузить один webhook
POST /membership/webhooksСоздать или обновить
POST /membership/webhooks/:id/regenerate-secretПовернуть секрет подписания
DELETE /membership/webhooks/:idУдалить webhook
GET /membership/webhooks/:id/deliveriesНедавние попытки доставки
GET /membership/webhooks/deliveries/:deliveryIdПолная полезная нагрузка и ответ
POST /membership/webhooks/deliveries/:deliveryId/redeliverПереставить в очередь

Каталог событий

Получите живой список из GET /membership/webhooks/events.

СобытиеПроисходит когда
person.createdЧеловек добавлен
person.updatedЗапись о человеке изменена
person.destroyedЧеловек удален
household.createdДомохозяйство добавлено
household.updatedДомохозяйство изменено
household.destroyedДомохозяйство удалено
group.createdГруппа добавлена
group.updatedГруппа изменена
group.destroyedГруппа удалена
group.member.addedЧеловек добавлен в группу
group.member.removedЧеловек удален из группы
donation.createdПожертвование записано
donation.updatedПожертвование отредактировано
attendance.recordedПосещение записано
session.createdНовая сессия создана
form.submission.createdФорма отправлена
event.createdСобытие добавлено
event.updatedСобытие отредактировано
event.destroyedСобытие удалено

Формат полезной нагрузки

Каждая доставка — это HTTP POST с телом JSON и заголовками:

ЗаголовокОписание
Content-TypeВсегда application/json
X-B1-EventНазвание события
X-B1-Delivery-IdУникальный id для дедупликации
X-B1-SignatureПодпись HMAC-SHA256
X-B1-TimestampUnix epoch секунды
User-AgentB1-Webhooks/1.0

Тело оборачивает ресурс в конверт:

{
"event": "person.created",
"churchId": "AbC123XyZ90",
"occurredAt": "2026-05-17T14:32:08.114Z",
"data": {
"id": "Pq7Rs2Tu4Vw",
"churchId": "AbC123XyZ90",
"name": { "display": "Jordan Rivera", "first": "Jordan", "last": "Rivera" },
"contactInfo": { "email": "jordan@example.com" }
}
}

Для событий *.destroyed data содержит только id и churchId.

Проверка подписей

Всегда проверяйте X-B1-Signature перед доверием. Подпись — это hex HMAC-SHA256 исходного тела, ключаемая вашим секретом.

Node.js

const crypto = require("crypto");

function isValid(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader || "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Python

import hashlib, hmac

def is_valid(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header or "")

Доставка и повторы

Ваша конечная точка должна ответить статусом 2xx быстро. Ответы без 2xx повторяются с экспоненциальной задержкой — 16 попыток примерно за 5 дней.

Доставка — по крайней мере один раз: используйте X-B1-Delivery-Id для дедупликации.

Требования к URL

URL webhook должен:

  • использовать https
  • не указывать на localhost или приватные IP адреса