Webhook
Generic webhook-канал — fallback. Когда вам нужно пушить алерты на chat-поверхность, ticketing-систему или in-house relay, который Ongrid не говорит нативно (Microsoft Teams, Mattermost, Rocket Chat, OpsGenie, PagerDuty, ваш собственный router), направьте generic webhook на него, и конвейер алертов запостит канонический JSON-сообщение Ongrid.
Используйте выделенный канал, когда он есть
Для Slack / Feishu / DingTalk / WeCom / Telegram выделенные каналы рендерят более богатые payload (Slack attachments, signing). Тянитесь к generic webhook только когда нет выделенного канала.
Payload
Тело — каноническая форма notify.Message, JSON-encoded дословно:
{
"severity": "critical",
"subject": "node-01 swap_high",
"body": "swap_in_pages > 1000 for 5m",
"source": "alert",
"labels": {
"rule": "swap_high",
"incident_id": "1234",
"device_id": "7",
"host": "node-01"
},
"dedupe_key": "alert:swap_high:device=7",
"occurred_at": "2026-05-30T14:02:35Z"
}Без envelope, без msgtype, без flattening. Получатель получает ровно поля, которые произвёл конвейер алертов. Собирается NewGenericWebhookSender.
Опциональная подпись HMAC
Когда вы заполняете поле Secret, каждый запрос несёт header X-Ongrid-Signature:
X-Ongrid-Signature: sha256=<hex>Где <hex> — это hex(HMAC-SHA256(secret, body)) поверх точных байтов запоста. Signer — это signGenericWebhook.
Верификация на стороне получателя
# Python receiver
import hmac, hashlib
def verify(secret, body_bytes, header):
expected = "sha256=" + hmac.new(
secret.encode(), body_bytes, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, header)// Go receiver
func verify(secret string, body, header []byte) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
expected := []byte("sha256=" + hex.EncodeToString(mac.Sum(nil)))
return hmac.Equal(expected, header)
}Всегда верифицируйте подпись, когда endpoint публичен
Generic webhook URL без подписи открыт для любого, кто узнаёт URL. Signature header — единственное, что аутентифицирует «это от Ongrid».
Форма запроса
| Свойство | Значение |
|---|---|
| Метод | POST |
Content-Type | application/json |
User-Agent | ongrid-notify/1.0 |
| Body | JSON формы notify.Message |
| Sig header | X-Ongrid-Signature: sha256=… (только при secret) |
| Timeout | Per-request http.Client timeout (по умолчанию 15с) |
Критерий успеха
Sender трактует HTTP 2xx (200–299) как успех. Всё остальное — включая 3xx редиректы, 4xx, 5xx — это unexpected status: … и считается failed delivery для конвейера дампенинга. Body ответа не парсится; Ongrid всё равно, какой JSON ваш relay эхает обратно.
Retry и дампенинг
Retry-семантика принадлежит конвейеру алертов, не Sender. Sender постит ровно один раз на вызов Send(ctx, msg). Конвейер решает:
- Окно дампенинга. Per-rule, по умолчанию 5 минут. Тот же dedupe key срабатывает максимум один раз за окно.
- Repeat-on-still-firing. По умолчанию 1 час. Если инцидент всё ещё открыт после этого окна, канал получает re-notify, чтобы он не был потерян в истории чата.
- Recovery-сообщение. Срабатывает, когда алерт снят.
Работа Sender — пушить байты. Работа конвейера — решать когда.
Нет автоматического retry на transport failure
Если получатель недоступен в момент, когда Sender постит, сообщение потеряно (логируется как delivery error, поднимается в per-channel delivery stats). Конвейер не очередит и не пытается заново. Рассуждение: 5-минутно-устаревший алерт, доставленный через три минуты после восстановления, более запутывает, чем отсутствующий. Используйте надёжный получатель или наложите свою очередь между Ongrid и flaky downstream.
Настройка
- Поднимите HTTP-эндпоинт, который принимает
POST+application/json. Выберите сильный secret, которым поделитесь с Ongrid. - В Ongrid: Settings → Channels → New → Provider =
webhook→ Endpoint = ваш URL → Secret = shared secret. - Кликните Test. Тестовое сообщение — синтетический
notify.Message{Severity: "info", Subject: "Ongrid test", …}. Верифицируйте signature header в логах вашего получателя.
Рецепты
Microsoft Teams (incoming webhook)
Incoming webhook Teams принимает другую форму payload (a MessageCard). Самый простой путь — поставить крошечный adapter между Ongrid и Teams:
# server.py - listens on /ongrid-to-teams
@app.post("/ongrid-to-teams")
def relay(msg: dict):
teams_url = os.environ["TEAMS_WEBHOOK"]
card = {
"@type": "MessageCard",
"@context": "https://schema.org/extensions",
"themeColor": {"critical":"D92F2F","warning":"F2C037","info":"36A64F"}.get(msg["severity"], "6F7A87"),
"title": msg["subject"],
"text": msg["body"],
}
requests.post(teams_url, json=card)Направьте Ongrid webhook-канал на https://your-relay/ongrid-to-teams.
PagerDuty Events API v2
Тот же паттерн: маленький relay, который переводит {severity, subject, body, dedupe_key} в payload PagerDuty events.v2. Поле dedup_key PD мапится 1:1 в dedupe_key Ongrid, так что тот же инцидент в Ongrid — это тот же алерт в PD.
Splunk HEC / Elastic ingest
Направьте канал на HEC-эндпоинт со Splunk-токеном в URL. Splunk принимает канонический Ongrid JSON; индекс на severity и labels.rule для downstream-поиска.
Справочник полей
См. Message для источника правды. Стабильные поля:
| Поле | Тип | Заметки |
|---|---|---|
severity | string | critical / warning / info. |
subject | string | Имя правила + target — одна строка. |
body | string | Multi-line детали. Может содержать переводы строк. |
source | string | alert / test / etc. |
labels | map[string]string | rule, incident_id, device_id, custom. |
dedupe_key | string | pipeline:rule:label-set. Стабильный per identity. |
occurred_at | RFC3339 string | UTC. Момент срабатывания alert evaluator. |
Новые поля аддитивны — получатели должны игнорировать неизвестные ключи.
Связанное
- Обзор каналов
- Схема правила алерта — для того, что
labels.ruleзначит и как dedupe key строятся.