Use the generic Callback notification channel to POST alert events as JSON to any custom Webhook URL — for IM bots, ITSM systems, in-house ops platforms, etc.

Overview

Callback is a generic HTTP Webhook notification channel that POSTs alert events from Nightingale to any URL as JSON. Beyond built-in channels (DingTalk, WeCom, Feishu, etc.), most custom integrations can be done via Callback: hooking into your internal ITSM/ticketing system, an in-house ops platform, a self-built bot, log pipelines such as Logstash/Loki, or forwarding events to downstream alerting platforms like Flashduty or PagerDuty.

  • Use case: integrate with any HTTP endpoint and receive the full alert event JSON.
  • Prerequisites: an HTTP/HTTPS URL reachable from Nightingale (filled per rule, switchable rule by rule).
  • The whole setup has two steps: ① Keep the default callback channel (or create a new one) → ② Fill callback_url in the notification rule.

Unlike DingTalk, WeCom and similar channels, Callback does not render the message template by default — the request body is just {{ jsonMarshal $events }}, the raw JSON array of events. If your downstream needs the template-rendered Markdown text, switch to variables like {{$tpl.content}} in the body — see “Customize the request body” below.

Step 1: Confirm or create a Callback notification channel

A built-in channel named Callback ships with Nightingale and usually works as-is. Create another one only if you need to separate Callbacks by business (e.g. one for ITSM, one for the in-house platform):

  1. Sign in to Nightingale → left menu Notify → Notification Channels.

  2. In the channel-type panel on the left, click Callback to enter the create page (URL /notification-channels/add?ident=callback).

    Channel entry

  3. Most fields are pre-filled. Just change the “Name”:

    Callback channel form

    Section Field Change? Notes
    Basic Name Yes e.g. Internal ITSM Callback. This is what you see when picking the channel in a rule.
    Basic Enable Keep on When off, this channel will not send.
    Variables Contact method Optional Callback rarely needs per-user routing; if you need to inject a phone/email into the body, pick the field here.
    Variables Parameter config Keep defaults, do not delete Pre-populated with callback_url and note; the actual target URL is filled per rule.
    HTTP URL Keep default {{$params.callback_url}} — replaced with the value filled in the rule.
    HTTP Method POST Default; can be PUT / GET.
    HTTP Headers Content-Type: application/json Pre-filled. Add auth headers (Authorization: Bearer ...) if needed.
    HTTP Timeout / Concurrency / Retry Usually keep defaults Default 10s timeout, 5 concurrency, 3 retries with 100ms interval.
  4. Scroll down to “Request body” — this is the heart of Callback:

    HTTP config and request body

    The default request body is a single line:

    {{ jsonMarshal $events }}
    

    Meaning: serialize all events in this batch into a JSON array and POST as the body. The downstream gets every field on the events (id, rule_name, severity, tags, annotations, first_trigger_time, last_eval_time, is_recovered, …) and can parse them as needed.

  5. Click Save at the bottom-left — a “Callback” channel is created.

Note: Nightingale v8 no longer stores the target URL on the channel itself. One Callback channel can be reused by many notification rules, each rule filling its own callback_url.

Step 2: Fill callback_url in the notification rule

  1. Left menu Notify → Notification Rules → Add (or edit an existing rule).

  2. In the “Notification config” section:

    Filling Callback URL in the rule

    • Channel: pick the Callback channel you just created (or the built-in one).
    • Message template: the default body does not use $tpl, so any template works — leave blank or pick Default. If you switched the body to use {{$tpl.title}}/{{$tpl.content}}, pick the matching template here.
    • Callback Url: the destination URL, e.g. https://itsm.example.com/api/v1/n9e/webhook. Must start with http:// or https://.
    • Note: optional comment, not part of the request.
    • Severity / time window / labels: filter which events get notified.
  3. After saving, click “Notification test” — the downstream endpoint should receive a JSON array.

Default $events JSON structure (excerpt)

[
  {
    "id": 12345,
    "rule_id": 100,
    "rule_name": "CPU usage too high",
    "severity": 2,
    "is_recovered": false,
    "first_trigger_time": 1714377600,
    "last_eval_time": 1714377900,
    "trigger_value": "85.6",
    "tags": ["ident=host01", "region=cn-bj"],
    "tags_json": {"ident": "host01", "region": "cn-bj"},
    "annotations": "{\"summary\":\"...\"}",
    "target_ident": "host01",
    "cluster": "default"
  }
]

The full schema is models.AlertCurEvent. If your downstream only needs a few fields, see the next section to trim the body.

Customize the request body

The default body is {{ jsonMarshal $events }}. You can replace it with any JSON / form layout and embed Nightingale’s built-in variables:

Variable Meaning
$events The current batch of events as an array (use with jsonMarshal).
$event The first event in $events (single-event scenarios).
$tpl Template-rendered content, e.g. {{$tpl.title}}, {{$tpl.content}}.
$params Custom parameters filled in the rule, e.g. {{$params.callback_url}}, {{$params.note}}.
$sendto, $sendtos Target recipients (phone, email). Only injected when the channel is bound to a “contact method”.

Example 1: Render Markdown to a Slack-compatible endpoint

{
  "text": "{{$tpl.title}}\n{{$tpl.content}}"
}

Example 2: Forward as a Flashduty-style event

{
  "event_status": "{{if $event.IsRecovered}}Ok{{else}}Critical{{end}}",
  "alert_key": "{{$event.Hash}}",
  "title_rule": "{{$event.RuleName}}",
  "description": "{{$tpl.content}}"
}

Example 3: Bulk push to an in-house system

{{ jsonMarshal $events }}

The right body depends on what the downstream expects. If it expects a form, switch Content-Type to application/x-www-form-urlencoded and write key1=val1&key2=val2.

FAQ

Q1: It looks like nothing was sent — how do I debug?

A: Open the alert event detail page in Nightingale and inspect the notification record — you can see the HTTP status code and response body for each callback. Common causes:

  • URL missing the protocol (must start with http:// / https://);
  • The server requires auth — add an Authorization header;
  • The server’s IP allowlist doesn’t include Nightingale’s egress IP;
  • Request times out — raise Timeout in the HTTP config.

Q2: My downstream wants a single event, not an array?

A: The default body {{ jsonMarshal $events }} sends an array. To send a single event, change the body to {{ jsonMarshal $event }}, and disable batch sending (or lower the aggregation granularity) in the rule so each callback carries one event.

Q3: Can one Callback channel send to different URLs for different businesses? A: Yes. No need to create new channels — just add another notification rule and fill a different callback_url.

References

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云