Skip to content

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 дословно:

json
{
  "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:

text
X-Ongrid-Signature: sha256=<hex>

Где <hex> — это hex(HMAC-SHA256(secret, body)) поверх точных байтов запоста. Signer — это signGenericWebhook.

Верификация на стороне получателя

python
# 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
// 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-Typeapplication/json
User-Agentongrid-notify/1.0
BodyJSON формы notify.Message
Sig headerX-Ongrid-Signature: sha256=… (только при secret)
TimeoutPer-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.

Настройка

  1. Поднимите HTTP-эндпоинт, который принимает POST + application/json. Выберите сильный secret, которым поделитесь с Ongrid.
  2. В Ongrid: Settings → Channels → New → Provider = webhook → Endpoint = ваш URL → Secret = shared secret.
  3. Кликните Test. Тестовое сообщение — синтетический notify.Message{Severity: "info", Subject: "Ongrid test", …}. Верифицируйте signature header в логах вашего получателя.

Рецепты

Microsoft Teams (incoming webhook)

Incoming webhook Teams принимает другую форму payload (a MessageCard). Самый простой путь — поставить крошечный adapter между Ongrid и Teams:

python
# 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 для источника правды. Стабильные поля:

ПолеТипЗаметки
severitystringcritical / warning / info.
subjectstringИмя правила + target — одна строка.
bodystringMulti-line детали. Может содержать переводы строк.
sourcestringalert / test / etc.
labelsmap[string]stringrule, incident_id, device_id, custom.
dedupe_keystringpipeline:rule:label-set. Стабильный per identity.
occurred_atRFC3339 stringUTC. Момент срабатывания alert evaluator.

Новые поля аддитивны — получатели должны игнорировать неизвестные ключи.

Связанное