# Webhook

出站 Webhook 用于把设备智能体或工作流产生的消息发送到外部服务。在 **设置 → Webhook** 中配置一次连接后，就可以在对话和工作流中按名称重复使用。

## 选择平台

| 平台 | 预设行为 |
| --- | --- |
| 飞书（兼容 Lark） | 按飞书或 Lark 自定义机器人格式发送文本，可选 Body 时间戳 HMAC 签名。 |
| 钉钉 | 按钉钉自定义机器人格式发送文本，可选 Query 时间戳 HMAC 签名。 |
| Slack | 按 Slack Incoming Webhook 格式发送文本。 |
| Discord | 按 Discord Webhook 格式发送文本。 |
| 自定义 Webhook | 可以配置 Headers、JSON Body 模板、签名和可选成功条件。 |

先在目标平台创建接收消息的 Webhook，再复制平台提供的 HTTPS URL；如果平台开启了签名校验，还需要复制签名 Secret。

## 创建并测试连接

1. 打开 **设置 → Webhook**。没有已保存连接时会直接显示表单；已有连接时点击 **新建**。
2. 填写唯一且容易识别的名称。Agent 和工作流图会用这个名称标识目标连接。
3. 选择平台，并粘贴 HTTPS Webhook URL。
4. 如果目标平台要求签名，选择匹配的签名方式并填写 Secret。
5. 填写测试消息，点击 **保存并测试**。
6. 确认 Device Agent 提示 HTTP 状态成功，并在目标平台收到消息。

**保存并测试** 会发送真实的出站请求。如果接收频道中有其他成员，请使用测试环境或标明“测试”的消息。

系统会先保存连接，再发送测试。即使测试失败，连接也会保留，可以编辑后重新测试。

![飞书 Webhook](../images/docs/integrations/webhooks/zh/01-feishu-webhook.png)

保存并测试成功后，飞书群中会收到机器人发送的测试消息。

![飞书收到 Webhook 消息](../images/docs/integrations/webhooks/zh/02-feishu-delivery.png)

## 配置自定义 Webhook

目标服务不适用预设格式时，选择 **自定义 Webhook** 并展开 **高级设置**。

| 配置 | 用途 |
| --- | --- |
| Headers | 值为字符串的 JSON Object，例如目标服务要求的认证 Header。不能覆盖 `Connection`、`Content-Length`、`Content-Type`、`Host` 和 `Transfer-Encoding`。 |
| 签名方式 | 不签名、Body 时间戳 HMAC 或 Query 时间戳 HMAC。 |
| Body 模板 | 发送给目标服务的 JSON Object。必须包含 <code v-pre>&#123;&#123;message&#125;&#125;</code>，且不支持其他变量。 |
| 成功条件 | 可选：把 `$.code` 等响应路径的值与字符串、数字、布尔值或 `null` 做精确比较。路径使用 `$` 和点分隔字段或数字索引；留空时只判断 HTTP 状态。 |

例如：

```json
{
  "event": "device_alert",
  "text": "{{message}}"
}
```

Agent 或工作流只提供消息文本；Webhook 连接会把文本替换到所有 <code v-pre>&#123;&#123;message&#125;&#125;</code> 位置，再发送渲染后的 JSON Body。

配置成功条件后，目标服务必须返回 `2xx`，并在 JSON 响应 Body 中提供对应路径。

![自定义 Webhook 设置](../images/docs/integrations/webhooks/zh/02-custom-webhook.png)

## 在对话中使用

已启用且已保存凭据的连接会作为内置 Webhook 能力提供给 Agent。发起请求时说明连接名称和消息内容：

```text
通过 operations-alerts Webhook 发送“温控器 01 已离线，请检查电源和网络”。
```

Agent 会根据名称选择已启用的连接。没有可用连接时，无法通过 Webhook 发送消息。

## 在工作流中使用

工作流可以在设备上报后发送固定消息，也可以让 Agent 步骤判断是否需要通知。先配置并测试连接，再在创建工作流时说明目标连接和消息：

```text
收到 battery_low_warning 且 payload.soc 小于 20 时，通过 operations-alerts Webhook 发送“设备 {{deviceId}} 电量低，当前 SOC 为 {{payload.soc}}%”。
```

工作流消息可以使用 <code v-pre>&#123;&#123;deviceId&#125;&#125;</code>、<code v-pre>&#123;&#123;eventName&#125;&#125;</code> 和 <code v-pre>&#123;&#123;payload.soc&#125;&#125;</code> 等事件字段。工作流会先渲染这些字段，再把结果作为 Webhook 连接的 <code v-pre>&#123;&#123;message&#125;&#125;</code>。完整示例见[工作流](../usage/workflows.md#发送-webhook)。

固定 Webhook 动作使用已选择的连接；Agent 步骤可以从已启用的连接中选择。HTTP 状态或投递错误可在工作流执行历史中查看。

## 管理连接

- 停用连接后，Agent、工作流和测试都不会再通过它投递，但配置仍会保留。
- 对已启用的连接点击 **测试**，可以再次发送一条真实测试消息。
- 只修改名称、消息 Body 或成功条件时，可以把 URL 留空并保留现有凭据。更换平台、签名方式或 Headers 时必须重新填写 URL；启用签名时还要重新填写签名 Secret。
- 工作流仍在引用某个连接时不能删除它，需要先修改或删除相关工作流。

## 安全与投递边界

- Webhook URL 必须使用 HTTPS，不能在 URL 中嵌入用户名和密码，也不能包含 Fragment。
- 请求由 Gateway 发出，也可以访问私有网络中的 HTTPS 地址。只有可信管理员可以配置目标；请把设置页和管理 API 放在可信网络或带身份认证的访问入口后。
- 请求固定使用 `POST` 和 `Content-Type: application/json`。
- 不要在截图、日志或共享消息中暴露 Webhook URL、Headers 或签名 Secret。
- 每次调用只发送一次 JSON `POST` 请求；不跟随重定向，目标返回 `3xx` 时请改用最终的 HTTPS URL。超时时间为 10 秒，请求和响应 Body 上限均为 64 KiB。
- 投递会同步执行，不会排队、自动重试，也不会保存独立投递历史。处理完目标服务故障后，可以手动重试或重新触发工作流。

## 故障排查

- **测试** 不可用时，确认连接已启用且凭据已经保存。
- HTTP 状态成功但测试仍失败时，检查响应路径和期望值。
- 工作流投递失败时，确认引用的连接仍处于启用状态，并先在 **设置 → Webhook** 中测试。
