触发器
在状态转变或负载匹配时调用外部系统的按监控自动化。出站调用会经过验证并设有上限,以防止不安全的目标和失控的循环。
触发器类型
- Webhook:带 HMAC-SHA256 签名标头的固定 JSON 结构。当接收方期望 KEEPitALIVE 格式时选择它。
- HTTP Request:带占位符变量、完全自定义的方法、标头和主体模板。用于定制集成。
- Notify:通过你已配置的告警渠道(Email、Discord、Slack 等)以自定义标题/正文模板发送通知。
- Incident:当负载条件匹配时开启 outage/degraded 事件,随后当某个事件清除条件时(或当你禁用/删除触发器时)自动解决它。完全静默的源不会自动解决 - 参见“条件”。

事件
九种事件:down、recovered、degraded、flapping_start、flapping_stop、maintenance_start、maintenance_end、signal 和 payload。 signal 针对 Event-Receiver 心跳而触发。payload 针对捕获了响应负载的检查而触发,尤其是 API 监控。

模板变量
在 HTTP Request 的主体/标头/URL 和 Notify 标题模板中使用这些:
{{monitor.id}} {{monitor.ref}} {{monitor.name}} {{monitor.url}} {{monitor.type}}
{{event.id}} - stable per-fire id (same value across the retry; use it to dedupe)
{{event.type}} {{event.status}} {{event.latency_ms}}
{{event.status_code}} {{event.error}} {{event.timestamp}}
{{check.id}} - id of the originating check (omitted for synthetic events)
{{payload}} - full check payload as raw string
{{payload.KEY}} - dot-path into the JSON payload (e.g. {{payload.status}})注意:monitor.id 和 monitor.ref 都解析为公开的监控引用 - 绝不是内部数据库 id。请以它作为你下游系统的键。
{
"source": "keepitalive",
"monitor": "{{monitor.name}}",
"event": "{{event.type}}",
"status": "{{event.status}}",
"latency_ms": "{{event.latency_ms}}",
"error": "{{event.error}}",
"at": "{{event.timestamp}}"
}条件
触发器可用针对已存储检查负载的表达式来限制触发。语法:==、!=、>、<、>=、<=、contains、exists、and、or、not、括号、点路径。示例:payload.failed_jobs > 0 and payload.status == "error"。 Incident 触发器需要条件。当表达式匹配时开启事件,当表达式不再匹配时解决它。 解决的原理:当后续的检查或负载重新评估同一触发器且表达式现在为 false 时,事件自动解决。当你禁用或删除触发器时也会立即关闭。重要:静默不是恢复。如果源完全停止发送负载/心跳,就没有事件来清除条件,因此事件会保持打开,直到有新事件到达或你手动解决。这是有意为之 - 我们绝不把“无数据”当作“已恢复”,因为对于负载/信号源来说,静默可能才是真正的故障。

Heartbeat / event receiver - your posted JSON stays at the top:
payload.failed_jobs, payload.status
What we observed sits under beat, so it cannot shadow yours:
payload.beat.received_at, payload.beat.exit_code,
payload.beat.duration_ms
(those three are also copied flat when you do not use the name)
API monitor - the response is wrapped:
payload.body.<what the server returned>
payload.status_code, payload.headers, payload.assertions
So an API check of a status endpoint reads
payload.body.status.indicator - not payload.status.indicator.Open degraded incident when:
payload.failed_jobs > 0 or payload.status == "error"
Auto-resolves when a later event makes that expression false,
or when you disable/delete the trigger.
A source that goes fully silent will NOT auto-resolve.WEBHOOK 负载结构
Webhook 触发器会 POST 这个固定的 JSON 主体。请以 event_id(去重)和 monitor.ref(标识)作为你处理器的键:
{
"event_id": "9f2c1ab4e5d6...", // stable per fire, repeats on retry
"event": "down",
"monitor": {
"id": "mon_abc123", "ref": "mon_abc123",
"name": "API", "url": "https://api.example.com", "type": "http"
},
"check": {
"id": 84213, "status": "down",
"latency_ms": 234, "status_code": 503, "error": "...",
"payload": { }
},
"timestamp": "2026-06-27T12:00:00Z"
}签名验证(WEBHOOK)
当 Webhook 触发器带有密钥时,每次投递都会携带 X-Timestamp 和 X-Signature-256。重新计算并比对以拒绝伪造的调用:
signed = X-Timestamp + "." + raw_request_body
expected = "sha256=" + hex(hmac_sha256(secret, signed))
reject unless constant_time_equals(expected, X-Signature-256)
// optional: reject if X-Timestamp is older than a few minutes投递语义
- 幂等性:X-KEEPitALIVE-Event-ID(在主体中也作为 event_id / '{{event.id}}')在每次触发时生成一次,并在多次重试间复用。请据此去重,以免在缓慢的首次尝试之后到达的重试被处理两次。
- 重试策略:网络触发器可以以 5-600 秒的延迟重试 0-3 次。Notify 触发器不重试,以避免用户可见的重复通知。
- 不跟随重定向:3xx 响应计为一次投递失败。请将 URL 指向最终目的地。
- 循环断路器:出站投递会携带 X-KEEPitALIVE-Depth。回发到事件接收器的一次心跳会传播 depth+1,网络触发器在 depth 3 停止触发 - 因此触发器 -> 事件接收器链条被限制为 3 跳。
集成配方
n8n / Make / Zapier:创建一个 Webhook(n8n)或 Custom Webhook catch hook(Make/Zapier),将其 URL 粘贴到 HTTP Request 或 Webhook 触发器中。对于 Webhook 触发器,在执行动作前于 Function/Code 步骤中验证 X-Signature-256;按 '{{event.type}}' 分支并按 event_id 去重。
Method: POST
URL: https://api.cloudflare.com/client/v4/zones/<ZONE_ID>/purge_cache
Headers: Authorization: Bearer <API_TOKEN>
Content-Type: application/json
Body: { "purge_everything": true }
// Tip: gate on {{event.type}} == recovered to purge after a deploy recovers.Method: POST
URL: https://<HA_HOST>/api/webhook/<WEBHOOK_ID>
Body: { "monitor": "{{monitor.name}}", "status": "{{event.status}}",
"event": "{{event.type}}", "event_id": "{{event.id}}" }Method: POST
URL: https://ops.example.com/hooks/restart
Headers: X-Auth-Token: <TOKEN>
Body: { "service": "{{monitor.name}}", "reason": "{{event.error}}",
"ref": "{{monitor.ref}}", "event_id": "{{event.id}}" }
// Make the receiver idempotent on event_id so a retry never double-restarts.安全
- 断路器在 10 次连续失败后禁用触发器(所有者会收到应用内通知)。
- 抖动策略:同样的 10 分钟内 4 次规则按触发器应用。
- Notify 触发器会在执行日志中记录每个渠道的投递结果(delivered / partial / failed)。
- Webhook 密钥在创建/轮换时显示一次;在之后的所有响应中都会被隐去。