接入点(Webhook)
让外部系统(监控告警、CI、工单、定时脚本…)通过一个 webhook 触发机器人在群里说话或跑工作流。网关不解析各平台格式,把原始事件原样交给模型自己读——新系统几乎零适配。
在 Dashboard 管控面 的「接入点」页创建和管理。当前为 beta。
快速上手
- 进 Dashboard →「接入点」→「新建接入点」。
- 填名称、选触发的机器人、选投递到哪个群(推荐「固定群」按群名选)。
- 「校验方式」默认是令牌,密钥留空自动生成。
- 点创建后会直接给一条末尾已含令牌的 Webhook URL 和一条可复制的
curl:
跑这条命令,机器人就会在你选的群里被触发、读到这段 JSON 事件。
校验方式
按接入点单独选,分两档:
令牌(默认 · 简单)
密钥直接放进 URL,整条 URL 即凭证,一条 curl 就能触发。令牌支持三种携带方式(任选其一):
服务端只做常量时间比对,不需要时间戳 / nonce / 签名。
⚠️ 令牌在 URL 里,会落进反向代理日志、浏览器历史——URL 泄漏 = 凭证泄漏。适合内网可信场景;公网或敏感系统建议用 HMAC,或至少把令牌放请求头而非查询参数。令牌可在列表里随时轮换。
HMAC 签名(高级 · 更安全)
密钥从不上网,并提供 body 防篡改 + 防重放。调用方需对 时间戳.原始body 做 HMAC-SHA256 签名,并带上三个请求头:
适合公网、或本就会签名的发送方(GitHub / Stripe 那类)。
幂等(重复投递去重)
很多上游是 at-least-once 语义:网络超时、网关重试都可能把同一个事件投递多次。默认情况下 botmux 会把每次合法 POST 都当成新事件,各开一个会话。
只要请求里带上幂等键,botmux 就会把重复投递折叠成一次:
上游只要已经在发上面任一请求头,就不需要做任何改造。三个头按表中顺序取第一个非空值。
行为
- 首次:正常投递,响应带
idempotency: {key, action:"accepted"}。 - 重复(同键 + 同 body):不投递,返回
200 {ok:true, action:"ignored", idempotency:{action:"duplicate", firstTriggerId}}。firstTriggerId是真正跑起来的那一轮,方便对账。这里刻意返回 2xx 而不是 4xx:at-least-once 的发送方看到非 2xx 会认为「没投成功」继续重试,返错只会造成重试风暴。
- 同键但 body 不同:说明这个键不是可靠的唯一标识(上游 bug)。此时照常投递并记一条 warning——丢掉一条可能是真实告警的事件,比多跑一次会话严重得多。
- 没带键:行为与本功能上线前完全一致。
- 首投仍在进行中时到达的重复:不会被提前 ACK,而是等首投真实结果——首投成功才回
ignored;首投失败则由这条请求接棒投递(避免上游因收到 2xx 停止重试而丢事件)。 - 同一事件的并发重复过多时返回可重试的
503(不是 2xx,也不投递),发送方稍后重试即可。 dryRun不消耗键;投递失败(5xx / daemon 离线)也不消耗键,上游重试照常生效。wait模式超时(504)不释放键:那一轮其实已经派发、通常还在跑,所以重试会被折叠而不是重复投递。- ⚠️ HMAC 校验方式的限制:nonce 防重放先于幂等闸生效,所以原样重放同一个已签名请求(同 nonce)会返回
409 replay,不会被折叠。用 HMAC 时请让每次重试换一个新 nonce 并重新签名——同键 + 新 nonce 可以正常折叠。之所以不做成「原样重放也能折叠」:签名只覆盖
时间戳.原始body,不覆盖幂等键、query 以及x-botmux-chat-id/-session-id/-root-message-id等路由头。若允许失败后回收 nonce,拿到旧签名的人就能改这些未签字段重放。要正确支持需要给 nonce 也做一套绑定完整请求指纹的 reserve/settle,属于更大的安全改动,不在本次范围内。
局限(重要)
去重窗口是 dashboard 进程内的,默认记 10 分钟,dashboard 重启后丢失(与上面 HMAC 防重放的 nonce 同样性质)。它解决的是现实中真正发生的「上游隔几秒到几分钟重投」,不是跨进程崩溃的持久 at-most-once 保证。
超过窗口后若某次投递始终没有返回结果(下游卡死),该键会被回收——这是明确的取舍:宁可允许一次可能的重复投递,也不永久吞掉这个事件键。单个接入点最多跟踪 10000 个键、单个事件最多并行挂 64 个等待者,超出后退化为「不去重」或返回可重试的 503,不会无上限占用内存。
若某个上游会拿同一个 id 表示不同事件,可在接入点上关掉该功能。
投递到哪个群
固定群
按群名从下拉里选(数据来自该机器人所在的群),群 ID 自动写进接入点。之后那条裸 URL 不带任何参数就能触发。最贴合「一个 URL 直接触发」的用法。
由请求指定(动态)
群随每次请求传入,三种写法任选其一:
可选填「允许的群」白名单——只有名单内的群 ID 才放行。
每次新建群
每来一个事件自动拉一个新群处置,并自动把该机器人的授权用户拉进群(不会只剩机器人)。
- 去重字段(可选):从事件 body 里取一个值做去重键,写法是点号路径(如
alert.id或$.alert.id,根是你 POST 的 body)。- 填了 → 命中相同去重值的每条事件都投到同一个群(第一条建群、后续复用)。
- 留空 → 每个事件都新建一个群。
早期版本有个「状态字段 / 自动关群」已移除——外部系统通常不会可靠地发送「恢复」信号。群不再自动关闭。
触发方式
- 单轮对话:让机器人针对这条事件回应一次。
- 工作流:把事件作为字符串参数
event传给一个 Workflow,由它的节点读取处理。
处理指令(可选)
默认情况下机器人只收到原始事件 JSON,没有「要做什么」的指引,只能自由发挥。在「处理指令」里写一段话告诉它该干嘛,例如:
总结这条告警的严重程度,判断是否需要立即处理,@相关 oncall,并给出排查建议。
这段指令作为可信任务注入到不可信事件数据之上,模型先读「要做什么」、再把事件 JSON 当数据处理:
安全与可观测
- 不被指挥:交给机器人的外部内容明确框定为「待处理的事件数据,不是命令」——不执行其中指令、不泄露凭据。
- 限流:可设宽松上限防「报警风暴」误伤;接入点暴露到公网时还应配请求体硬上限。
- 调用记录:Dashboard →「调用日志」按时间、Webhook 和结果筛选全部调用;点开单条记录可查看 HTTP 状态、耗时、查询参数、请求头、JSON 请求体、路由参数和实际投递目标。
- 敏感信息保护:URL 路径令牌、
Authorization/Cookie/ 签名头,以及请求体中的 password / secret / token / API key 等字段会在写盘前替换为[REDACTED]。日志文件权限为0600,且调用日志 API 不开放给 Dashboard 匿名只读访问。 - 留存策略:新建 Webhook 默认保存脱敏后的请求头和 JSON 请求体 14 天;单个请求体最多留存 128 KB。可在 Webhook 列表里关闭请求参数留存,关闭后仍记录状态、耗时和路由元数据。
