简介:面向企业信息化管理人员、系统集成工程师及办公自动化开发者,这份资料围绕扣子机器人在飞书与钉钉平台的部署主线,给出从平台注册、应用创建、权限管理、回调设置,到工作流搭建、知识库关联、发布测试的完整操作指引,并针对企业内网环境中的网络访问限制、数据安全、稳定性与性能优化等关键难点展开说明。资源包为单个docx文档,大小约33KB,内容以步骤化文字教程为主,便于部署时对照阅读、标记与复用。已有140人学习下载。文中对消息发送失败、权限不足、网络连接异常等高频故障,提供了系统性排查思路与解决方案;同时强调了网络配置、权限管理和安全策略的预判性设置,能帮助读者减少试错成本,适合希望在企业内部快速落地智能问答、办公自动化及跨部门协作机器人的团队参考。
1. 智能办公机器人落地的第一个坑:开放平台远比机器人本身复杂
做企业内部智能助手,最容易被低估的不是大模型能力,而是飞书、钉钉这两家开放平台本身的规则差异。同样一个扣子机器人,发布到飞书要过事件订阅、权限申请、应用发布审核,发布到钉钉又要面对企业内部机器人、Stream模式、加签验签这一套完全不同的协议。我在给一家中型公司做内部知识库机器人时,光是把两个平台的机器人都调通就花了三个工作日,其中至少一半时间在跟回调地址、Token校验和权限点较劲。
这份资源解决的是“扣子平台编排好的智能体,如何稳定地挂到飞书和钉钉上”这件事。它覆盖了从创建扣子工作流、配置飞书自建应用、配置钉钉企业内部机器人,到消息收发调试、多维表格读写、卡片交互回调的全流程。适合两类人:一类是公司内部做IT支持、想给团队加一个能查数据、能跑审批流程的机器人的工程师;另一类是接外包项目、需要在两个办公平台上交付智能助手的开发者。如果你以为把扣子机器人发布到飞书钉钉就是点几个按钮的事,那这份资源能帮你把预期拉回现实。
2. 扣子平台的关键机制:工作流、插件与发布渠道的解耦逻辑
2.1 扣子机器人的本质:一个被封装成HTTP服务的Agent
扣子平台(Coze)本身提供了完整的智能体编排能力,包括人设与回复逻辑、工作流、知识库、插件、触发器、数据库等模块。但很多第一次接触的人会误以为“在扣子上建了一个Bot,就等于在飞书/钉钉上有了一个机器人”,这个认知是错的。实际上,扣子上的机器人只是你在扣子云端定义的一个逻辑体,它自身不负责处理办公平台的消息推送和回调。飞书或钉钉收到用户消息后,会先触发各自开放平台的事件订阅或Webhook机制,再把消息内容通过扣子开放API转发给你的智能体,拿到回复后再调用飞书/钉钉的消息发送接口把结果发回去。
这个链路意味着,你要先理解扣子机器人的“发布”机制。在扣子控制台,每个Bot都有一个“发布”按钮,发布时需要选择一个渠道,比如“API服务”或“微信公众号”。其中飞书、钉钉这两个渠道在扣子平台上是原生支持的,这是它比自建Agent服务省事的地方。但你仍然需要去飞书开放平台或钉钉开发者后台创建对应的应用,拿到App ID、App Secret、验证Token、加密Key,再把扣子发布配置里的回调地址填到开放平台的事件订阅URL里。
用一句话概括这层关系:扣子管“大脑”,开放平台管“神经”,开发者管“搭桥”。这份资源的绝大部分篇幅,就是在教你如何把这座桥搭稳。
2.2 为什么选扣子而不是自建服务:状态管理与多轮对话的取舍
企业在二选一时经常纠结:是用扣子这种低代码Agent平台,还是直接基于大模型API自建一个机器人服务?我的看法是,看你的对话复杂度。如果你的机器人只需要“查一下排班表”“找一下制度文档”这种单轮或简单多轮对话,扣子平台的工作流编辑器和知识库组件能让你在半天内搭出一个可用的版本。但如果你的业务涉及复杂的状态机,比如审批流中要等待用户上传多个附件、根据上一轮结果动态生成下一步选项,那么扣子工作流的节点编排会更难维护,自建服务的上下文管理反而更灵活。
扣子平台还有一个值得注意的特性:消息上下文是托管在平台侧的。你在工作流里配置的“历史消息轮数”会影响机器人对多轮对话的感知能力。实际操作中,我一般会把“最多记住最近10轮”作为一个安全值,设太大会导致Token消耗飙升,设太小则用户说“刚才那个”时机器人会断片。
发布到飞书、钉钉时要注意一个关键差异:飞书支持长连接模式(WebSocket),钉钉企业内部机器人现在推广Stream模式。这两种模式都不需要公网回调地址,特别适合企业内网环境。而老式的Webhook模式要求你的服务器能接收飞书/钉钉主动推送的HTTPS请求,这就意味着你必须有一个公网可达的HTTPS端点,或者在内网网关做反向代理。在扣子平台上发布时,选择“API服务”方式,扣子会生成一个公网可访问的Bot URL,飞书事件订阅把消息推进这个URL,扣子再响应回来。如果企业内网策略禁止出方向访问外部服务,那这条链路就会断掉,这是我在实际部署中遇到过的第一个大坑。
2.3 扣子发布配置参数速查
在扣子Bot的“发布”页面里,配置飞书和钉钉渠道时,有几个关键参数需要你提前准备好。下面这个表是我每次部署前都会先列出来的清单:
| 参数 | 飞书渠道 | 钉钉渠道 | 说明 |
|---|---|---|---|
| 应用凭证 | App ID + App Secret | AppKey + AppSecret | 在各自开发者后台创建企业内部应用后获取 |
| 事件订阅URL | 扣子生成的回调地址 | 钉钉Stream模式无需URL,Webhook模式需要 | 两者都是HTTPS前缀 |
| 验证Token | 由你自定义并填写到双方后台 | 钉钉为加签密钥(Secret) | 用于校验消息来源 |
| 加密方式 | AES加密密钥(可开启) | 加签(时间戳+nonce+密钥SHA256) | 飞书推荐开启加密,钉钉加签必配 |
| 权限配置 | 读消息、发消息、读多维表格、上传资源 | 机器人发送消息、读取消息、日程读写 | 漏配权限是最常见的“不响应”原因 |
以上参数在扣子发布成功后会生成一个“智能体ID”或“Bot ID”,这个ID在后续调试API时要用到。下一章我会以飞书为例,把从创建应用到发送第一条消息的完整链路展开。
3. 飞书机器人全流程部署:从自建应用到多维表格读写
3.1 飞书开放平台侧配置:自建应用的三步走
飞书的后台逻辑是“应用”为中心。你要在飞书开放平台创建一个“企业自建应用”,然后在这个应用里启用机器人能力、配置事件订阅、申请权限,最后发布版本。只有审核通过的应用,机器人才能真正在飞书工作区里被搜索到并私聊或群聊。
第一步是创建应用。进入飞书开放平台,点击“创建企业自建应用”,填入应用名称和描述。这个名称会显示在飞书工作台的“机器人”列表里,建议直接用业务名,比如“订单查询助手”“人事制度助手”,别用“扣子测试Bot”这类名字,因为审核时会被要求补充用途说明。创建完成后,在“凭证与基础信息”页面复制App ID和App Secret,这两个值稍后要填到扣子发布配置里。
第二步是开启机器人能力。在应用功能里找到“机器人”,打开开关。这里有个细节:飞书的机器人分为“应用机器人”和“回调机器人”两种使用形态,企业自建应用默认启用应用机器人,它会以“应用名”的身份出现在聊天里。你随后要做的,是在事件订阅页面里添加一个事件,名叫“接收消息”。如果不添加这个事件,飞书根本不会把用户发来的消息推送到你的回调地址,机器人就会一直沉默。
第三步是申请权限。飞书对权限点的粒度划分非常细。发送消息对应im:message:send_as_bot,读取用户发给单聊机器人的消息对应im:message:readonly,读取多维表格对应bitable:app:readonly。常见做法是,先在权限管理里搜索“机器人”和“多维表格”,把读写相关的权限全部勾上,再在创建版本后提交审核。企业自建应用的审核一般由企业管理员在管理后台处理,如果管理员是自己,直接在开发者后台的“版本管理与发布”页签提交并审核通过,整个过程不需要飞书官方介入,这一点比钉钉要轻量。
3.2 扣子侧发布配置:把回调地址交给飞书
回到扣子控制台,进入你的Bot,点击“发布”,渠道选择“飞书”。扣子会要求你填写两部分信息:一部分是飞书应用的App ID和App Secret,另一部分是你自定义的验证Token和加密Key。填完后扣子会生成一个回调URL形如https://www.coze.cn/api/feishu/callback,把这个URL完整复制到飞书开放平台的“事件订阅-请求地址”里。
飞书为了验证这个回调地址是你的,会立刻向它发一个带Challenge参数(URL验证请求)的GET请求。你需要确保扣子那边的回调端点是正常运行的。在扣子上,只要你填写的Token和飞书后台的验证Token一致,这个Challenge校验会自动通过。这里最容易翻车的地方是:你在飞书后台填写的验证Token,和你在扣子发布配置里填写的Token,必须一字不差。Token不一致时,飞书会提示“验证URL失败”,不会给你任何额外的排查日志。
验证通过后,把“事件订阅”里的加密策略打开。飞书的事件推送支持明文和加密两种模式,扣子侧会自动适配,但建议你把飞书后台的“加密策略”设为“使用加密”,并在扣子发布配置里填入相同的加密Key。这个Key要求是16位或24位或32位的字符串,随便生成一段即可,例如abcdef1234567890这样的长度必须合规。加密模式下,飞书推送的JSON里会多出一个encrypt字段,解密后才是真实消息体,不配置的话扣子解析不到消息内容,表现为“事件订阅验证成功,但机器人收不到消息”。
3.3 用一段Python验证飞书消息链路是否打通
配置完双方后台后,我习惯先不急着在飞书里发消息,而是用飞书开放API做一次主动消息推送,验证App ID和App Secret的有效性,以及机器人是否具备发消息权限。下面是我平时用来做“发消息”链路自检的一段脚本:
import json import requests app_id = "cli_xxxxxxxxxxxxxxxx" app_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 步骤1:获取 tenant_access_token url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" resp = requests.post(url, json={ "app_id": app_id, "app_secret": app_secret }) resp.raise_for_status() token = resp.json().get("tenant_access_token") if not token: print("获取token失败,检查App Secret是否正确") exit(1) # 步骤2:把消息主动推给某个用户的单聊 chat_id = "ou_xxxxxxxx" # 对应某个用户的open_id send_url = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id" headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json" } payload = { "receive_id": chat_id, "msg_type": "text", "content": json.dumps({"text": "连通性测试:如果你是手动看到这条消息,说明机器人链路正常。"}) } resp2 = requests.post(send_url, headers=headers, json=payload) result = resp2.json() if result.get("code") == 0: print("发送成功,msg_id:", result["data"]["message_id"]) else: print("发送失败,错误码:", result.get("code"), result.get("msg"))这段脚本里最关键的是获取tenant_access_token的接口路径。它跟获取user_access_token的接口不同,后者需要OAuth授权跳转,而机器人调用API只靠App ID和App Secret即可换到tenant_access_token。换到Token后,发消息接口要求指定receive_id_type,常用的是open_id或user_id。从飞书管理后台的“成员管理”里能查每个用户的open_id,但更常见的做法是在事件订阅里把用户的sender_id记录下来。
这个链路验证通过后,再回到飞书客户端里直接给机器人发消息,看扣子是否正常回复。如果客户端消息不走,问题大概率出在事件订阅的“事件类型”没勾选,或者机器人能力开关没打开。下一步我们要去处理那些“配置看起来都对,但就是不响应”的诡异情况,这在钉钉侧表现得更明显。
4. 钉钉机器人部署实战:Stream模式与卡片消息的坑
4.1 钉钉机器人的三种形态,你该选哪一种
钉钉的开放平台跟飞书有个显著区别:它把“机器人”拆成了至少三种形态,选错形态会让你后面每一步都走不顺。
第一种是“企业内部机器人”,也叫“应用机器人”。你在钉钉开发者后台创建一个企业内部应用,然后在“机器人”页签里启用机器人,配置消息接收地址。这种机器人可以出现在单聊和群聊里,支持在消息卡片上添加按钮交互,是部署扣子智能助手的推荐形态。
第二种是“自定义机器人”,通过群聊里的“智能群助手”添加,本质上是一个Webhook机器人。它只能往群里发消息,收不了用户消息,所以扣子智能助手如果要实现“问答”而不是“定时推送”,用这个形态根本跑不通。很多业务方上来就说“我们在钉钉群里加一个自定义机器人就行”,如果你做的是客服或问答场景,一定要在第一轮打消这个想法。
第三种是Stream模式机器人。这是新版本钉钉主推的形态,机器人不需要配置公网回调URL,而是通过长连接主动连上钉钉服务器接收消息。这个模式在扣子平台上也支持。如果你所在企业网络环境里没有可对外的HTTPS端口,Stream模式是唯一行得通的路。
4.2 钉钉企业内部机器人配置:加签、Stream与权限
以企业内部机器人为例,完整的配置流程是这样。先在钉钉开放平台创建“企业内部应用”,拿到AppKey和AppSecret。然后在“机器人”页签中,机器人协议建议选“Stream模式”,这样不需要填写消息接收地址,扣子侧的发布配置也会相应简化。
如果你坚持用Webhook模式,那就要在机器人配置里填一个消息接收地址,并打开“消息加签”开关,拿到一段加签密钥。钉钉的事件推送会在HTTP头里带timestamp和sign两个字段,签名算法是Base64(HmacSHA256(把timestamp + "\n" + secret作为待签名字符串))。扣子平台处理钉钉Webhook时已经内置了验签逻辑,你不需要自己实现,但如果你打算在自建服务里调试钉钉回调,这一段就是检验消息是否合法的关键。
权限方面,钉钉的命名是“权限点”,你需要在应用的能力配置里至少启用“消息接收”和“发送消息”。如果你的机器人要读多维表格——钉钉体系里叫“多维表”,同一份权限需要单独申请。这里有个跟飞书不同的规则:钉钉的权限点除基础沟通类权限外,多数在发布后需等待官方审核,审核时间通常为半天到两个工作日。企业内网项目如果急着上线,建议提前申报而不是等到部署当天。
4.3 用Python验证钉钉机器人:Stream模式消息收发
对于Stream模式的钉钉机器人,你用Requests直接调API就能体验完整的“收消息-回消息”闭环。下面这段脚本是一个最小可运行的钉钉Stream模式示例,核心思路是:应用启动后,用WebSocket连接到钉钉的消息通道,监听robot类型的消息,然后调用发送消息API回复固定内容。
import requests import json app_key = "ding_xxxxxx" app_secret = "xxxxxxxxxxxxxxxx" # 获取企业内部应用的access_token token_url = "https://api.dingtalk.com/v1.0/oauth2/accessToken" resp = requests.post(token_url, json={ "appKey": app_key, "appSecret": app_secret }) token = resp.json()["accessToken"] # 向指定会话发送消息 # conversationId 可以是单聊会话ID,也可以是群会话ID send_url = "https://api.dingtalk.com/v1.0/robot/groupMessages/send" headers = { "x-acs-dingtalk-access-token": token, "Content-Type": "application/json" } payload = { "msgKey": "sampleText", "msgParam": json.dumps({ "content": "钉钉机器人连通性测试:收到这条消息说明应用凭证可用。" }), "openConversationId": "cid_xxxxxxxxxxxxxx" # 群会话的conversationId } resp2 = requests.post(send_url, headers=headers, json=payload) if resp2.json().get("code") == "0": print("发送成功") else: print("发送失败:", resp2.text)注意这段代码里我用的是openConversationId而不是老的conversationId,这是钉钉开放平台升级后的字段名。在群聊场景下,这个值的获取方式是:先让机器人加入某个群,再通过事件订阅里的conversationId字段拿到,或者从群里发一条消息后从回调日志里提取。
钉钉和飞书在消息类型上的差异也值得注意:飞书的content是一个JSON字符串,而钉钉的msgParam也是JSON字符串,但msgKey决定了解析方式。比如sampleText对应纯文本,sampleMarkdown对应Markdown,sampleActionCard对应带按钮的卡片。如果你要做的是多轮对话式助手,建议直接用sampleText就好,因为扣子返回的答案大多是文本。但如果你要把机器人的输出包装成“连续对话卡片”,就得在扣子工作流的最后一步加一个“代码执行”节点,把文本转成钉钉卡片所要求的JSON结构。
4.4 钉钉卡片消息:按钮交互的回调闭环
钉钉最让人头疼的,是卡片消息里的按钮回调节点。流程是:机器人发一张带“同意”“拒绝”按钮的卡片,用户点按钮,钉钉把按钮点击事件回调到你的服务或扣子工作流的“事件接收”节点。这个回调的URL需要跟消息接收地址保持一致,并且在钉钉“事件与回调”页面里单独注册一个事件类型叫“机器人卡片回调”。
在扣子侧处理这个回调时,我一般会在工作流的开头加一个“条件判断”节点,判断messageType是text还是action_card。如果是action_card,就从消息体里取用户点击按钮的value字段,再根据value值决定下一步走哪个分支。这个字段在钉钉推送的JSON里叫params,结构是一个字典,业务自定义的键值都在里面。
做这个设计时最需要留神的是:卡片回调的消息体和普通文本消息结构完全不一样。如果只按普通消息的解析逻辑来处理,你会发现用户点了按钮后机器人没有任何反应,但抠出来的日志明明显示消息已收到。这个坑十个人里有八个会踩,我们在第5章专门列出来。
5. 部署避坑指南:飞书钉钉调试中最常见的五个翻车现场
5.1 事件订阅验证成功,但机器人不回复任何消息
现象:在飞书后台点击验证URL,提示“URL验证通过”,但在飞书客户端给机器人发消息,它完全沉默,扣子后台运行日志也空无一物。
原因:事件订阅验证成功只代表你的回调地址能被飞书访问到,并不代表飞书会把消息事件推给你。你没有在“事件订阅”页面里添加“接收消息”事件类型,飞书默认只推送你订阅过的事件。钉钉侧类似的坑是:你配置了Stream模式,但没有把“机器人消息”事件关联到应用上,同样导致消息进不来。
解决:飞书开放平台进入应用的事件订阅页面,点击“添加事件”,在“消息与群组”分类下勾选“接收消息(im.message.receive_v1)”。保存后重新执行一次“推送调试”,飞书会模拟一条消息事件推送到你的回调地址。钉钉侧在应用开发的“事件与回调”里注册“机器人消息回调”,并确认回调方式与你在机器人协议里选择的模式保持一致。
5.2 飞书后台提示“token校验失败”,但你的Token明明没填错
现象:配置扣子发布渠道时,把扣子生成的验证Token填到飞书后台,点击验证时提示校验失败。
原因:飞书的验证Token机制分为两层。第一层是飞书后台自己生成的“验证Token”字段,当事件订阅开启加密后,飞书实际上用的是“Encrypt Key”做签名校验,而不是那个明文Token。第二层是扣子侧在发布渠道配置时填写的自定义Token,它只参与扣子到飞书之间的连接校验。很多开发者把扣子填的Token复制到了飞书后台的“Encrypt Key”字段里,导致校验失败。
解决:飞书后台的“验证Token”:保持默认值,不要动。“Encrypt Key”:填一个你自己生成的16/24/32位字符串。扣子平台发布配置里:填的Token与飞书后台一致(复制同样的字符串),加密Key也保持一致。最终以“Encrypt Key”为准,不是“验证Token”。
5.3 钉钉加签一直失败:你拼的签名字符串顺序不对
现象:在钉钉开发者后台测试回调时,后台提示“签名校验失败,请检查签名是否正确”。
原因:钉钉Webhook的签名算法要求先取timestamp和nonce,然后把它们与加签密钥拼接成一个字符串,具体格式是timestamp + "\n" + secret作为待签名字符串,再进行HMAC-SHA256运算,最后Base64编码。但钉钉文档中还有另一种历史遗留的签名规则,部分开发者按照老版本文档拼接了secret + "\n" + timestamp,导致签名对不上。
解决:统一按timestamp + "\n" + secret的顺序来。如果你用扣子平台,这一步不需要你手动实现,但如果你是用代码调试钉钉Webhook,就把GetSign函数的参数严格定义为timestamp、secret两个值。确认时间戳用的是毫秒级还是秒级——钉钉推送的timestamp是毫秒,但有些SDK自带的签名工具用秒,差了这一个单位,签名结果完全不同。
5.4 机器人能发消息,但无法读取飞书多维表格数据
现象:机器人可以正常回复用户文本消息,但当用户问到“查一下表格里的排班情况”时,扣子工作流报错无权限,日志里出现403。
原因:扣子的知识库工作流通过飞书API读取多维表格时,要求应用具备bitable:app:readonly及以上权限点。你只开了消息类的权限,没开多维表格权限,或者开了权限但没有等待权限生效。飞书的权限点不是即时生效的,需要发布新版本且管理员审批后才会在API层面放开。
解决:进入飞书开发者后台,在“权限管理”里搜索“多维表格”,勾选bitable:app:readonly和bitable:app:write,然后重新创建版本并提交发布。在管理后台审核通过后,等待两分钟让权限缓存刷新,再在扣子工作流里测试同样的请求。这里有个窍门:你先用飞书开放平台的“调试工具”直接调用一次查询表格记录API,如果调试工具里返回正常,那就说明App自身权限没问题,问题出在扣子侧传参不正确;如果调试工具都返回403,那一定是权限点还没生效。
5.5 钉钉卡片按钮唤起的手填地址是回调,用户点完没反应
现象:在扣子里配好了带按钮的钉钉卡片,用户点击按钮后,卡片上的文字变成了“已处理”,但扣子工作流没有任何反应,机器人也没有后续回复。
原因:钉钉的卡片按钮有两种动作:一种是自定义跳转URL,另一种是卡片回调。你配置成跳转URL后,按钮点击只会打开一个外部链接,不会触发机器人逻辑。更隐蔽的问题是:你在钉钉后台注册了按钮回调事件,但扣子工作流没有在消息入口节点区分text和action_card两种消息类型,导致回调消息被当成普通文本消息处理,解析失败后静默丢弃。
解决:钉钉卡片消息在扣子侧的工作流入口增加一个“分支判断”节点。判断依据是消息对象里是否包含params键。如果包含,说明是卡片回调,从params里取出按钮对应的value,再拉取当前消息的open_id具体字段名要看钉钉推送的实际JSON。这个方案有三种变体,下面用一个最小示例演示其中一种:
message = { "msgtype": "action_card", "params": {"action": "approve", "task_id": "T1001"} } if "params" in message: action = message["params"].get("action") task_id = message["params"].get("task_id") print(f"收到卡片回调,动作={action},任务编号={task_id}") # 在这里把业务状态更新到数据库,再发一条新卡片 else: print("收到普通文本消息,走普通问答流程")参数说明:params字段只在卡片回调场景下存在,普通文本消息不会携带。钉钉对卡片回调有一个额外的要求:回复消息时必须在原消息conversationId上回复,否则会出现“用户看到新消息,但不在同一个会话线程里”的割裂现象。
6. 一套工作流同时适配飞书和钉钉:渠道差异封装技巧
部署完成两个平台之后,最常见的需求是“同一个智能助手,两边都要上”。如果你直接把扣子的工作流分别发布到两个渠道,会遇到一个麻烦:飞书传过来的消息格式和钉钉传过来的格式在字段名上完全不同,工作流里每个解析节点都要写两套逻辑,维护成本翻倍。
我目前比较推荐的做法是在扣子工作流里加一个“渠道适配”节点组,放在消息入口之后、业务逻辑之前。这个节点组的职责就是把不同平台的消息体统一成内部标准的格式。比如飞书的event.message.content是一个JSON字符串需要先解析,而钉钉的text.content是纯字符串,你在适配节点里把两者都转成一个统一的{sender_id, text_content, message_type}结构。这样后面的业务节点只需要处理一种数据格式,不管消息来自哪个平台,逻辑都一样。
具体实现可以在扣子里拖一个“代码执行”节点,用Python写一个normalize_incoming_message函数。以下是我在一个项目里用过的简化版:
def normalize(message: dict, channel: str) -> dict: if channel == "feishu": # 飞书事件订阅推送中,消息内容在 event.message.content 字段 raw = message["event"]["message"]["content"] import json content = json.loads(raw) return { "sender_id": message["event"]["sender"]["sender_id"]["open_id"], "text_content": content.get("text", ""), "message_type": "text" } elif channel == "dingtalk": # 钉钉消息内容在 text.content 字段,纯字符串 return { "sender_id": message["senderId"], "text_content": message["text"].get("content", ""), "message_type": "text" } else: raise ValueError(f"未知渠道: {channel}")注意这里有个隐藏细节:飞书事件订阅推送过来的JSON,有时候是加密的,你需要先decrypt再执行上述解析;而钉钉走Stream模式推送的消息时,消息体已经是明文。为了统一处理,最好在扣子发布配置里查看一下当前渠道是否开启加密,如果开启,就在适配节点之前单独加一个“解密预处理器”。
验证工作流是否适配成功的方法也很简单:在飞书里发一句测试消息,再在钉钉里发同一句,看两侧的回复是否一致。如果一致,说明逻辑层已经统一;如果一侧正常一侧报错,先查看扣子工作流日志里报错节点的输入,比较两个渠道消息体在那一节点的实际结构差异——90%的情况是某个字段名为空或类型不一致。
我能给你的最后一条经验是:别急着把扣子上的旧版本覆盖发布。每当你改完一个渠道的配置并测试通过后,在扣子发布页面保留上一版本作为“回退点”。这个习惯救过我一次——当时我改钉钉卡片的回调逻辑时不小心动了飞书的发布配置,导致飞书机器人崩了,我直接回退到上一个版本,十分钟内恢复正常。从那以后,我每次部署完一个平台都要先手动把版本号记下来,再继续下一个平台的调优。希望这片笔记能帮你把两个平台的部署路径一次走通。
本文还有配套的精品资源,点击获取