消息推送
消息推送流程把外部 HTTP 请求转成 Soln 通知。外部系统向流程 Webhook 发送 JSON 报文,流程把报文渲染成消息,再投递到应用消息或群聊。
消息推送流程归属某个 OpenLink 系统,与入站、出站流程的区别:
- 不绑定表单,也不会新增、修改或删除本地表单记录
- 画布只包含一个开始节点、一个或多个消息节点和一个结束节点;不允许出现源、转换、目标、分支、查询节点
- 触发方式固定为
webhook,不支持轮询、推送和服务调用 - 消息节点之前可以放智能体执行节点;有智能体执行时,智能体的输出作为消息正文
消息节点配置
在设计画布中选中消息节点,配置通知的发送方式。
| 配置项 | 说明 |
|---|---|
| 发送方式 | 应用消息 发送站内消息;群聊消息 发送到群聊 |
| 消息通道 | 仅应用消息。接收消息的非 Luna 应用通道 |
| 消息模板 | 仅应用消息。需要启用中的站内信模板;消息推送流程没有表单绑定,因此不能使用表单记录类模板 |
| 接收人 | 仅应用消息。固定成员、表单成员字段,或从请求体解析出的成员 |
| 发送智能体 | 仅群聊消息。提供群聊中的发送身份,消息节点不会执行该智能体 |
| 目标群聊 | 仅群聊消息。目标群聊中必须已包含该发送智能体 |
| 执行时机 | 始终、成功时 或 失败时;当前面没有智能体执行节点时生效 |
消息正文
| 场景 | 消息正文 |
|---|---|
| 消息前有智能体执行节点 | 智能体输出的文本,原样发送 |
| 没有智能体节点且执行失败 | 失败原因 |
没有智能体节点、报文顶层有 markdown 字符串 | 该 Markdown,原样发送 |
| 没有智能体节点且没有失败 | 由 Webhook 报文或上游结果渲染出的 Markdown |
Markdown 渲染会把对象转成 - **字段**: 值 列表,把对象数组内联为 - **code**: A · **qty**: 2,跳过空值,并对过长正文做截断。群聊里的发送智能体只是载体:没有智能体执行节点时,流程不会调用 AI 生成内容。
如何请求
| 项目 | 取值 |
|---|---|
| 方法 | POST |
| 地址 | <your-runtime-origin>/api/open-link/message-push/<flowCode> |
| 内容类型 | application/json;其他类型会返回 OPEN_LINK_CONTENT_TYPE_INVALID |
| 请求头 | X-Idempotency-Key 可选;其余按该系统的入站鉴权配置,详见入站鉴权 |
| 请求体 | 一个 JSON 对象,参数见下表;不是 JSON 对象(数组或单个值)时返回 OPEN_LINK_EXECUTION_PAYLOAD_INVALID |
<your-runtime-origin> 是工作空间 Runtime 的地址,也就是你在浏览器里打开 Soln 的那个地址,例如 https://runtime.example.com。<flowCode> 是流程记录上的流程编码,形如 open_link_flow_889b5ea7abae,不是流程定义的 UUID。设计画布的开始节点会显示该流程的完整地址,直接复制即可:
https://runtime.example.com/api/open-link/message-push/open_link_flow_889b5ea7abae
消息推送使用独立接口:入站 Webhook 地址只服务入站流程,调用消息推送流程会被拒绝。
请求参数
请求体的参数都是可选的,按消息节点的发送方式选用;同一个请求可以同时带上多种参数。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
markdown | string | 否 | 群聊消息的自定义正文,原样按 Markdown 发送 |
memberIds | string[] | 否 | 请求体传入的接收人,成员 UUID 或外部成员标识,例如 ["1001"],详见下文 |
message | object | 否 | 应用消息的模板变量,键名与模板变量名一致 |
| 其他字段 | 任意 | 否 | 供智能体执行节点分析,或供节点输入映射按 input.*、record.data.* 读取 |
请求示例
群聊消息,自己写 Markdown 正文(消息节点的发送方式必须是群聊消息):
curl --request POST \
'https://runtime.example.com/api/open-link/message-push/notification-push' \
--header 'Content-Type: application/json' \
--header 'X-OpenLink-Token: ${OPENLINK_TOKEN}' \
--header 'X-Idempotency-Key: notification-001' \
--data '{
"markdown": "> 生活是一大堆无聊的时间,欢乐的玫瑰难得点缀其中;\n> 谁想第一个得到欢乐的玫瑰,谁就最先被它的荆棘扎痛。\n\n— 托·穆尔"
}'
群聊消息,正文由报文生成,接收人由 memberIds 传入:
curl --request POST \
'https://runtime.example.com/api/open-link/message-push/order-alert-push' \
--header 'Content-Type: application/json' \
--header 'X-OpenLink-Token: ${OPENLINK_TOKEN}' \
--data '{
"memberIds": ["1001"],
"stage": "review",
"owner": "A. Lee",
"tags": ["draft", "review"]
}'
应用消息,模板变量放在 message 里(示例模板声明了 quote、signature 两个变量):
curl --request POST \
'https://runtime.example.com/api/open-link/message-push/quote-push' \
--header 'Content-Type: application/json' \
--header 'X-OpenLink-Token: ${OPENLINK_TOKEN}' \
--data '{
"message": {
"quote": "我从来不认为人的自由在于想做什么就做什么,而是在于想不做什么就不做什么",
"signature": "------让·雅克·卢梭 <一个孤独者漫步者的遐想>"
}
}'
X-OpenLink-Token 只在 OpenLink 配置了共享令牌入站鉴权时发送,请求头名称以安全配置为准;配置的是签名校验时,改为发送 App ID、时间戳和 HMAC 签名请求头,签名原文必须包含本次请求的原始 JSON。
请求说明
群聊消息正文。 取值顺序是:智能体执行节点的输出 → 执行失败原因 → 报文里的 markdown → 由报文渲染的 Markdown。报文没有 markdown 字段时按字段渲染:每个字段一行 - **字段**: 值,嵌套对象渲染成缩进子项,对象数组内联为 - **date**: 2026-09-15 · **hours**: 2,空值跳过,超过 3800 字符截断。例如:
{ "stage": "review", "owner": "A. Lee", "tags": ["draft", "review"] }
- **stage**: review
- **owner**: A. Lee
- **tags**
- draft
- review
正文不能超过群聊消息 4000 字符上限,超出报 WORKFLOW_GROUP_CHAT_BODY_TOO_LONG。消息节点前有智能体执行节点时,智能体的输出始终作为群聊正文,即使请求里带了 markdown;此时请求体里放的是给智能体分析的字段。
应用消息模板。 模板变量在消息节点上用「请求体」映射方式取值,按 input.message.<变量名> 解析,映射键名必须与模板变量名完全一致。上面的示例模板正文写成 {{input.quote}} 和 {{input.signature}},收到的就是普通文案,不是字段清单:
我从来不认为人的自由在于想做什么就做什么,而是在于想不做什么就不做什么
------让·雅克·卢梭 <一个孤独者漫步者的遐想>
请求体缺少被映射的字段时执行失败,执行日志会记录缺失路径,例如 RUNTIME_CONTEXT_PATH_NOT_FOUND:input.message.quote。
请求体传入接收人。 在消息节点上打开配置接收人,切到请求体传入,勾选成员组,请求体传入的接收人就与固定接收人一样直接生效:请求体解析出谁,消息就发给谁。memberIds 里的值先按该 OpenLink 系统的组织映射解析成成员,例如 1001 已映射为 00000000-0000-4000-8000-000000000010,消息就发给该成员;映射不到、也不是成员 UUID 的值会被跳过。接收人不会从其他字段推断,全部解析不到时执行失败,日志报 MESSAGE_APP_CHANNEL_TARGETS_UNRESOLVED。
请求被接受的前提:OpenLink 系统为 active、流程已 published、调用方通过该系统配置的入站鉴权与白名单,并且请求计入入站限流与并发保护。
响应
执行排入队列后接口返回 202 Accepted,消息是异步投递的。
{
"accepted": true,
"duplicate": false,
"logId": "00000000-0000-4000-8000-000000000001",
"traceId": "00000000-0000-4000-8000-000000000002",
"status": "queued",
"definitionId": "00000000-0000-4000-8000-000000000003",
"flowCode": "order-alert-push",
"workflowId": "open-link:...",
"workflowStartDeferred": false,
"callbackRequested": false,
"statusQueryUrl": null
}
| 字段 | 说明 |
|---|---|
accepted | 请求已被接受执行 |
duplicate | 相同幂等键已受理时为 true,此时返回原有的 logId、traceId |
logId / traceId | 执行标识,用于在执行日志中定位本次运行 |
status | 初始执行状态,queued |
definitionId / flowCode | 受理该请求的流程 |
callbackRequested / statusQueryUrl | 消息推送固定为 false 和 null:该接口不创建异步回执 |
用返回的 logId 打开流程执行日志,确认消息是否投递成功、失败时查看失败原因。流程运行期间产生的错误(例如解析不到接收人)记录在执行日志里,不会通过 HTTP 响应返回。
常见错误
| 错误码 | 含义 |
|---|---|
OPEN_LINK_FLOW_DEFINITION_NOT_FOUND | 没有匹配该流程编码的流程 |
OPEN_LINK_FLOW_DEFINITION_NOT_PUBLISHED | 流程存在但尚未发布 |
OPEN_LINK_SYSTEM_NOT_ACTIVE | OpenLink 系统未启用 |
OPEN_LINK_FLOW_EXECUTION_TYPE_INVALID | 该流程不是消息推送流程;应改用入站 Webhook 或查询接口 |
OPEN_LINK_CONTENT_TYPE_INVALID | 请求内容类型不是 application/json |
OPEN_LINK_JSON_VALUE_INVALID | 请求体不是合法 JSON |
OPEN_LINK_PAYLOAD_TOO_LARGE | 请求体超过大小限制 |
OPEN_LINK_WEBHOOK_AUTH_INVALID / OPEN_LINK_WEBHOOK_TIMESTAMP_EXPIRED | 入站鉴权校验失败 |
OPEN_LINK_WEBHOOK_SOURCE_DENIED | 白名单规则拒绝该调用方 |
OPEN_LINK_INBOUND_RATE_LIMIT_EXCEEDED / OPEN_LINK_INBOUND_CONCURRENCY_LIMIT_EXCEEDED | 被入站限流或并发保护拒绝 |
OPEN_LINK_IDEMPOTENCY_KEY_CONFLICT | 该幂等键已被其他流程使用 |
MESSAGE_TEMPLATE_REQUIRED_INPUT_MAPPING_MISSING:<变量名> | 模板的必填变量在消息节点上没有配置输入映射(发布时报错) |
MESSAGE_TEMPLATE_INPUT_MAPPING_UNKNOWN:<键名> | 映射键名和模板变量名不一致(发布时报错) |
MESSAGE_TEMPLATE_INPUT_MAPPING_PATH_INVALID:<变量名> | 映射路径不是允许的上下文路径(发布时报错) |
RUNTIME_CONTEXT_PATH_NOT_FOUND:input.message.<变量名> | 请求体里没有映射要读取的 message 字段(日志报错) |
MESSAGE_APP_CHANNEL_TARGETS_UNRESOLVED | 消息节点既没有固定接收人,也没有从请求体解析出的成员(日志报错) |
消息推送流程与其他流程一样,在流程列表里创建发布,或使用 Openlink 系统命令参考中的 Runtime 命令创建发布。
推荐配置流程
- 创建或选择通知所属的 OpenLink 系统
- 为该配置入站鉴权与白名单规则
- 通过 Runtime 命令或流程列表创建消息推送流程
- 进入设计画布,添加并配置消息节点;需要分析内容时,在消息节点之前添加智能体执行节点
- 保存、发布并启用流程
- 从外部系统调用
POST /api/open-link/message-push/<flowCode>,并在执行日志中核对结果