Skip to content

入站配置(Inbound)使用指南

什么是入站配置?

入站配置(Inbound)允许你的接口(Endpoint)接收来自第三方系统的 Webhook 数据,并自动将其转换成标准的消息格式后推送到绑定的渠道。

简单来说:用于解决无法修改发送端消息结构内容的问题

典型使用场景

场景说明
Grafana 告警服务器异常时自动推送告警到微信
Prometheus 告警监控指标超阈值时发送通知
GitHub 事件PR 合并、Issue 创建时收到提醒
Emby 通知影视库播放、转码完成时推送消息

快速开始

第一步:创建接口并绑定渠道

  1. 进入「接口管理」页面,点击「新建接口」
  2. 设置名称(如"Grafana 告警"),系统会自动生成访问令牌
  3. 在渠道列表中勾选要接收消息的渠道(如企业微信、Telegram 等)
  4. 保存

第二步:开启入站配置

  1. 在接口卡片中点击「入站配置」
  2. 打开「启用入站接收」开关
  3. 选择数据来源类型
  4. 根据所选类型填写字段映射规则
  5. 点击「保存配置」

第三步:配置外部系统

将页面底部显示的接收地址填入第三方系统的 Webhook 配置中:

POST https://你的域名/api/inbound/你的令牌

完成!现在当第三方系统触发 Webhook 时,消息就会自动推送到你绑定的渠道了。


界面说明

开启入站后,你会看到以下配置区域:

数据来源类型

选择一个预设模板或选择「通用」进行完全自定义。每种模板对应一类常见的数据格式。

模板适用场景
GrafanaGrafana 告警通知
PrometheusPrometheus AlertManager 告警
GitHubGitHub Webhook 事件(PR、Issue 等)
EmbyEmby/Jellyfin 媒体库事件通知
通用其他任意格式的数据(需手动填写字段映射)

注意:选择「Grafana」「Prometheus」「GitHub」「Emby」等预设模板时,字段映射由系统自动处理,无需手动填写。只有选择「通用」时才会显示字段映射编辑区域。

字段映射规则(仅「通用」模式可见)

选择「通用」模板后,会出现三个输入项:

标题字段(多行文本框)

每行填写一条规则。最终结果由所有行的输出按顺序拼接而成。

内容字段(多行文本框)

与标题字段用法相同。

消息类型(下拉选择)

选项说明
纯文本 (text)默认选项,适合大多数推送渠道
Markdown支持 Markdown 格式的渠道可使用此选项
HTML支持 HTML 格式的渠道可使用此选项

填写规则

这是最核心的部分。文本框中的每一行会被独立处理,理解以下规则就能灵活配置任意格式。

规则总览

你填写的行内容系统如何处理说明
$.alerts[0].labels.alertname从原始数据的该路径提取值$. 开头 = JSONPath 提取
---告警详情---直接当作固定文字原样保留不以 $. 开头 = 字面量
\n产生一个换行转义字符,用于在行内插入换行
\t产生一个制表符(缩进)转义字符,用于对齐排版
(空行)自动忽略空内容不参与拼接

核心行为

每行独立处理,按书写顺序拼接成最终结果。

  • $. 开头的行 → 尝试从原始数据中取值,取到了就拼接,取不到就跳过该行
  • 不以 $. 开头的行 → 作为固定文字直接拼接(支持 \n \t 转义)
  • 最终结果 = 所有有效行的输出无缝连接

重要限制

不要在同一行内混写文字和路径。例如下面这种写法是错误的:

❌ 来自Grafana的告警:$.alerts[0].labels.alertname

这整行会被当作普通文字原样输出(因为不以 $. 开头),其中的 $.alerts... 不会被解析为路径。

正确做法是把它们分到不同的行:

✅ 来自Grafana的告警:
   $.alerts[0].labels.alertname

使用换行

由于每行的输出会无缝连接,如果你希望在不同信息之间换行显示,有两种方式:

方式一:用 \n 单独一行插入换行

主机: $.hostname
\n
指标: $.metric = $.value$.unit
\n
状态: $.status

结果:

主机: web-server-03
指标: disk_usage = 87%
状态: warning

\n 是转义字符,会被解析为真正的换行符。同样地,\t 会被解析为制表符。

方式二:在固定文本行末尾写 \n

--- 告警详情 ---\n
$.alerts[0].annotations.message
\n--- 请及时处理 ---

JSONPath 语法基础

JSONPath 路径用于从原始数据中定位并提取值。

基本写法

填写的内容含义
$.title取顶层的 title 字段
$.name取顶层的 name 字段
$.alerts[0]alerts 数组的第 1 个元素
$.alerts[0].labels.alertname取第 1 个告警的 alertname 标签
$[0].Title取数组的第 1 个元素的 Title 属性
$.sender.loginsender 对象下的 login 字段

数组索引从 0 开始

$.alerts[0]   ← 第 1 条告警
$.alerts[1]   ← 第 2 条告警
$.alerts[2]   ← 第 3 条告警

支持多层嵌套,没有深度限制。


配置示例

示例一:最简单的单字段映射

假设外部系统发送的数据如下:

json
{
  "title": "服务器异常",
  "message": "CPU 使用率达到 95%"
}

在界面中的填写方式:

标题字段(填一行):

$.title

内容字段(填一行):

$.message

消息类型:纯文本 (text)

最终推送结果:

  • 标题:服务器异常
  • 正文:CPU 使用率达到 95%

示例二:多路径提取

假设你希望从多个可能的字段中提取内容,只要有值的都会被拼接到一起:

json
{
  "alert_name": "磁盘满",
  "summary": "磁盘使用率超过 98%",
  "body": "请立即清理"
}

内容字段(填多行,每行一个路径):

$.summary
$.body
$.message

处理过程:

  • $.summary → 找到值 "磁盘使用率超过 98%" → 保留
  • $.body → 找到值 "请立即清理" → 保留
  • $.message → 数据中没有这个字段 → 跳过

最终结果:磁盘使用率超过 98%请立即清理

每条路径独立判断,能取到值的就拼上,取不到的不影响其他行。不是"取第一个就停止",而是"全部都尝试,有效的全拼接"。


示例三:添加前缀(文字与路径分行)

你希望在动态值前面加上固定的前缀文字:

json
{
  "alerts": [
    {
      "labels": { "alertname": "HighCPU" }
    }
  ]
}

标题字段(分两行填写):

来自Grafana的告警:
$.alerts[0].labels.alertname

结果:来自Grafana的告警:HighCPU

关键点

  • 第一行不以 $. 开头 → 作为固定文字
  • 第二行以 $. 开头 → 从数据中提取值
  • 两行按顺序无缝拼接

对比例二:如果这里只有一行写了 $.alerts[0].labels.alertname,结果就是纯净的 HighCPU;加上第一行前缀后变成 来自Grafana的告警:HighCPU


示例四:组合多个字段 + 换行排版

假设收到以下监控数据:

json
{
  "hostname": "web-server-03",
  "metric": "disk_usage",
  "value": 87,
  "unit": "%",
  "status": "warning"
}

标题字段

磁盘警告:
$.hostname

内容字段

主机:
$.hostname
\n
指标:
$.metric
=
$.value
$.unit
\n
状态:
$.status

推送结果:

  • 标题磁盘警告: web-server-03
  • 正文
    主机: web-server-03
    指标: disk_usage = 87%
    状态: warning

每行之间用 \n 分隔,产生换行效果。


示例五:带换行的复杂格式

同样的数据,这次让排版更清晰:

json
{
  "alerts": [
    {
      "labels": { "alertname": "HighCPU", "instance": "server-01" },
      "annotations": { "message": "CPU 超过 90%" }
    }
  ]
}

标题字段

[紧急] 
$.alerts[0].labels.alertname
 - 
$.alerts[0].labels.instance

内容字段

--- 告警详情 ---\n
$.alerts[0].annotations.message
\n--- 请及时处理 ---

推送结果:

  • 标题[紧急] HighCPU - server-01
  • 正文
--- 告警详情 --
CPU 超过 90%
--- 请及时处理 ---

每一行都是独立处理的单元:

  • --- 告警详情 --- → 不以 $. 开头,作为固定文字
  • $.alerts[0].annotations.message → 提取动态值
  • --- 请及时处理 --- → 固定文字

三者的输出按顺序无缝拼接成最终内容。


示例六:容错性演示

假设某个字段名在不同版本的 API 中可能不同,你想兼容多种可能:

json
{
  // 版本A 的数据格式
  "alert_name": "内存溢出"
}

// 或者版本B的数据格式
{
  "name": "内存溢出"
}

标题字段

$.alert_name
$.name
新消息

遇到版本 A 数据时:

  • $.alert_name → 找到 "内存溢出" → 保留
  • $.name → 找不到 → 跳过
  • 新消息 → 固定文字 → 保留

结果:内存溢出新消息

遇到版本 B 数据时:

  • $.alert_name → 找不到 → 跳过
  • $.name → 找到 "内存溢出" → 保留
  • 新消息 → 固定文字 → 保留

结果:内存溢出新消息

可以看到最后一行固定文字始终会出现在结果末尾。如果想去掉它,删除最后一行即可。


预设模板的行为说明

选择预设模板(非「通用」)时,字段映射由系统自动完成,同时会对消息做额外的内容丰富

模板自动追加的信息
Grafana / Prometheus在正文末尾追加告警标签(如 alertname=xxx, instance=xxx)、摘要和当前状态
GitHub在正文末尾追加操作者账号和触发的分支名
Emby在正文末尾追加事件类型、用户名、服务器名称和级别

这些信息会拼接到已提取的内容后面,让你在不修改配置的情况下获得更完整的上下文。

如果不需要这些额外信息,可以选择「通用」模板自行配置纯净的字段映射。


兜底机制

当所有字段映射都无法提取到有效值时,系统有以下保障:

  • 正文为空:整个原始数据的 JSON 内容将作为正文发送,确保不丢失信息
  • 标题为空:自动使用默认标题 新消息
  • 消息类型无效:自动回退为 text(纯文本)

调试方法

使用入站配置面板内的测试功能

入站配置面板底部自带「测试请求」区域:

  1. 切换不同的数据来源类型时,测试数据区会自动填充对应的示例 JSON
  2. 也可以粘贴你自己实际的 Webhook 数据
  3. 点击「发送测试请求」,消息会立即通过该接口的绑定渠道发出
  4. 观察收到的消息是否与你预期的格式一致

推荐调试流程

  1. 先用示例数据 + 你的字段映射配置 → 点测试 → 看效果
  2. 调整映射规则直到输出符合预期
  3. 保存配置后,再把入站地址填入第三方系统
  4. 用真实 Webhook 触发一次验证

常见问题

Q:为什么选择预设模板后看不到字段映射输入框?

这是正常设计。预设模板(Grafana、Prometheus、GitHub、Emby)已经内置了推荐的映射规则,无需手动配置。只有选择「通用」时才需要自己填写。

Q:标题或正文显示了整个 JSON?

说明字段映射没有匹配上原始数据的结构。检查以下几项:

  • JSONPath 路径拼写是否正确(区分大小写)
  • 数组索引是否越界
  • 使用调试功能粘贴实际数据,逐步验证每条路径是否能取到值

Q:我想同时包含固定文字和动态值?

可以,但必须把它们写在不同的行。固定文字单独一行,$. 路径单独一行。不要写在同一行里。

Q:多行路径之间是什么关系?

对于同一个目标字段的多行内容:

  • $. 开头的行:独立提取,找到值的保留,找不到的跳过
  • 不以 $. 开头的行:作为固定文字直接保留(\n 会变成换行符,\t 会变成制表符)
  • 所有有效行按书写顺序拼接为一个字符串

Q:如何在不同信息之间换行?

每行的输出默认无缝连接。要插入换行,有两种写法:

方法一:单独一行写 \n

主机: $.hostname
\n
指标: $.metric

方法二:在文字末尾追加 \n

--- 告警详情 ---\n
$.alerts[0].annotations.message

支持的转义字符:

输入效果
\n换行
\t制表符(Tab 缩进)
\\反斜杠本身

Q:为什么我的前缀没有生效?

检查是否把前缀文字和 $. 路径写在同一行了。正确做法是分两行写:

❌ 错误:前缀文字: $.path.field
✅ 正确:
   前缀文字:
   $.path.field

基于 MIT 许可证开源