1. 钉钉机器人 Stream 模式接入 OpenClaw 到底解决什么问题
钉钉机器人接入 OpenClaw 这件事,本质上是在解决一个很具体的痛点:企业内网环境里,怎么让钉钉群里的消息实时驱动一个本地或内网的 AI 网关,而不需要把服务暴露到公网。传统做法要么申请公网域名、配 HTTPS 证书、做备案,要么用内网穿透工具,运维成本高,安全边界也模糊。Stream 模式的出现把这条路彻底改写了——它用 WebSocket 长连接反向注册到钉钉开放平台,消息由钉钉侧主动推过来,你的 OpenClaw 网关只需要能出网就行,不需要任何入站端口。
我先把核心检索词讲清楚:钉钉机器人 Stream 模式,是钉钉开放平台为「企业内部应用」提供的一种消息接收方式,机器人不需要公网回调地址,通过长连接接收事件。OpenClaw 是一个可自托管的 AI 网关/Agent 运行环境,它内置了对钉钉渠道的适配,你只要把钉钉应用的 Client ID 和 Client Secret 填进去,它就能以机器人身份收发消息。适合谁?适合有钉钉企业账号、有开发者或管理员权限、想在内网跑 AI 助手又不想折腾公网暴露的团队和个人开发者。
整条链路的关键节点有三个:钉钉开放平台侧创建企业内部应用并开通机器人能力、选择 Stream 模式、发布版本拿到 Client ID 与 Client Secret;OpenClaw 侧把这两个凭证写进渠道配置;然后验证消息能不能双向跑通。很多人卡在第三步——凭证填了但收不到消息,或者收到消息但回复失败,报错信息又很含糊。这篇就按「配置—验证—排障」的顺序,把每一步的可复制片段和真实报错都摊开讲。
需要说明的是,OpenClaw 侧的模型调用可以走 TaoToken 的兼容接口,这样你既跑通了钉钉链路,又有一个稳定的模型出口。官网入口在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api ,后面配置里会用到。
2. TaoToken 前置准备:凭证、模型与 OpenClaw 渠道配置
在动钉钉后台之前,先把 OpenClaw 这一侧的地基打好,否则你拿到 Client ID 也不知道往哪填。OpenClaw 的渠道配置通常是一个 JSON 或 TOML 文件,不同发行版路径略有差异,但结构大同小异。你需要准备三样东西:钉钉的 Client ID、Client Secret,以及一个可用的模型出口。前两个从钉钉开放平台拿,第三个我建议用 TaoToken 的 API Key,这样模型调用和钉钉渠道解耦,后面换模型不用动钉钉配置。
先说 TaoToken 这一侧。进入控制台创建 API Key,地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,创建后复制那串以 sk- 开头的 Key。模型 ID 你可以先用 claude-sonnet 这类通用对话模型,具体可用列表在文档里查:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。如果你打算长期跑编码类 Agent,可以看 Coding Plan 页面:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
OpenClaw 的渠道配置里,钉钉部分一般长这样(以 JSON 为例,路径按你的实际安装目录调整,常见是config/channels.json或data/config.json):
{ "channels": { "dingtalk": { "enabled": true, "mode": "stream", "clientId": "dingxxxxxxxxxxxxxxxx", "clientSecret": "你的ClientSecret", "robotCode": "dingxxxxxxxxxxxxxxxx", "cardTemplateId": "", "model": { "baseUrl": "https://taotoken.net/api", "apiKey": "sk-你的TaoTokenKey", "modelId": "claude-sonnet" } } } }注意几个细节:mode必须是stream,这是整条链路的核心;clientId和robotCode在钉钉新版权限体系里通常是同一个值,但有些老版本配置项分开写,填一样即可;baseUrl结尾不要带/v1,TaoToken 的兼容层会自动处理路径。如果你用的是 TOML 格式,等价写法是:
[channels.dingtalk] enabled = true mode = "stream" clientId = "dingxxxxxxxxxxxxxxxx" clientSecret = "你的ClientSecret" robotCode = "dingxxxxxxxxxxxxxxxx" [channels.dingtalk.model] baseUrl = "https://taotoken.net/api" apiKey = "sk-你的TaoTokenKey" modelId = "claude-sonnet"配置写完后不要急着启动,先做一次语法校验。JSON 可以用python -m json.tool config/channels.json,TOML 用python -c "import tomllib;tomllib.load(open('config.toml','rb'))"。我见过太多人因为多了一个逗号或者中文引号,导致 OpenClaw 启动时静默失败,日志里只报一句channel init failed,排查半天。校验通过再往下走。
3. 钉钉开放平台侧:Client ID 与 Client Secret 获取全流程
这一节是拿 Key 的部分,但我会把和 OpenClaw 对接强相关的配置项一并说清楚,避免你拿完凭证回去发现模式选错了。登录钉钉开发者后台 https://open-dev.dingtalk.com ,用有开发者或管理员权限的企业账号进入。在「应用开发」里选择「企业内部应用」,点创建应用,填应用名称和描述,图标和预览图按 240×240、1:1、2MB 以内的要求准备,格式 JPG 或 PNG,不要带圆角。
应用创建后进入能力面板,找到「机器人」能力,点添加。这一步是前提,没开机器人能力后面拿不到 Stream 相关配置。添加后进入机器人配置页,消息接收模式这里必须选Stream 模式,页面上会明确写「无需公网域名」。如果你看到的是「HTTP 回调模式」并要求填 URL,说明你选错了,退回去改。机器人名称、简介按需填,消息预览图上传符合规格的素材。
配置完机器人信息后,关键动作是发布版本。钉钉的规则是:所有配置修改必须发布新版本才生效,未发布的改动只停留在开发态。进入「版本管理与发布」,填版本号和描述,可用范围测试阶段建议选「仅我可见」,避免影响同事。点保存并发布。发布成功后,回到「凭证与基础信息」页面,这里能看到两个核心参数:
- Client ID(旧称 AppKey):格式类似
dingxxxxxxxxxxxxxxxx,是一串以 ding 开头的标识。 - Client Secret(旧称 AppSecret):一长串随机字符,点「查看」并复制。
复制时用鼠标从第一个字符拖到最后一个字符,不要双击(双击可能只选中一段),也不要多带空格。我踩过的坑就是 Secret 末尾多了一个换行符,粘到配置里后 OpenClaw 报invalid credential,肉眼完全看不出来,最后用cat -A才看到$前面有个^M。建议复制后先粘到纯文本编辑器里检查一遍。
把这两个值填进上一节的clientId和clientSecret字段。如果你同时用 Cline MCP 或 Codex 的auth.json做本地 Agent,记住三件套要写全:Base URL 填https://taotoken.net/api,Key 填 TaoToken 的 sk- Key,Model ID 填你选的模型名。这三者缺一不可,只填 Key 不填 Base URL 会走到默认端点,报 401 或 404。
4. 验证请求:从消息连通性测试到成功结果确认
配置写完、凭证填好,接下来是验证。先启动 OpenClaw 网关,观察日志里钉钉渠道的初始化输出。正常情况你会看到类似dingtalk stream connected或channel dingtalk registered的字样。如果看到stream connect failed,先别慌,对照下一节的报错表排查。
第一步验证是出站连通性:确认 OpenClaw 所在机器能访问钉钉的 Stream 接入点。用curl -I https://api.dingtalk.com看返回码,200 或 401 都说明网络通(401 是因为没带鉴权,正常)。如果超时,检查防火墙出站规则,Stream 模式只需要出站 443。
第二步验证是消息接收:在钉钉里找到你刚发布的机器人,给它发一条「你好」。观察 OpenClaw 日志是否出现received message以及消息内容。如果日志有但机器人没回复,问题在模型调用侧;如果日志完全没有,问题在 Stream 连接或凭证。
第三步验证是模型调用:单独测一下 TaoToken 的接口,排除模型侧干扰。用 curl 发一个最小请求:
curl -X POST https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的TaoTokenKey" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet", "messages": [{"role": "user", "content": "ping"}] }'返回里如果有choices数组且content有内容,说明模型出口正常。如果返回 401,检查 Key 是否复制完整;如果返回model not found,去文档页核对模型 ID 拼写。
三步都通过后,回到钉钉发一条稍微复杂的问题,比如「帮我总结一下今天的待办」。正常结果是你会在几秒内收到机器人的回复,OpenClaw 日志里能看到完整的请求-响应链路。到这一步,端到端就跑通了。如果想让机器人支持更复杂的卡片交互,可以在配置里加cardTemplateId,但那是进阶内容,先把纯文本跑通再说。
5. 本篇常见错排查:401、local proxy failed 与 reading choices
这一节按真实报错来。第一个高频错误是401 Unauthorized。出现在两个位置:一是 OpenClaw 调 TaoToken 时,说明apiKey不对或baseUrl写错。检查baseUrl是不是误写成了https://taotoken.net/api/v1(多了/v1),以及 Key 有没有多余空格。二是钉钉 Stream 连接时返回 401,说明 Client ID 或 Client Secret 错误,或者应用版本没发布。回到钉钉后台确认版本状态是「已发布」而非「开发中」。
第二个错误是local proxy failed或stream connect timeout。这通常不是凭证问题,而是网络出站被拦。OpenClaw 所在环境如果有出站白名单,需要放行api.dingtalk.com和taotoken.net。注意这里说的是出站放行,不是让你配代理,企业网络里找运维加白名单即可。另外检查系统时间是否准确,WebSocket 握手对时间偏差敏感,偏差超过几分钟会直接失败。
第三个错误是reading choices: unexpected end of JSON input或类似解析错误。这个报错说明请求发出去了,但返回体不是预期的 JSON,常见原因是baseUrl指向了一个返回 HTML 的地址(比如误填了官网首页),或者模型 ID 不存在导致服务端返回了错误页。核对baseUrl必须是https://taotoken.net/api,模型 ID 从文档页复制。还有一种可能是请求体里messages格式不对,检查是不是漏了role字段。
第四个错误是OAuth 相关报错,比如oauth token exchange failed。这在钉钉侧出现时,多半是 Client Secret 复制错误或应用权限范围没配。回到「凭证与基础信息」重新复制 Secret,并确认应用可用范围包含了你测试的账号。如果同时用 Claude Code 做本地润色或编码,注意它的配置和 OpenClaw 是独立的,不要混用同一份凭证文件。
最后一个隐蔽的坑:配置改了但没重启 OpenClaw。很多渠道配置是启动时加载的,热更新不一定生效。改完配置后养成重启习惯,再看日志确认新配置被读取。如果重启后仍报旧错误,检查是不是有多个配置文件,OpenClaw 实际读的是另一个路径。
6. 跑通之后:把钉钉机器人接到你的日常流程里
链路跑通只是起点。接下来你可以把 OpenClaw 的钉钉渠道接到实际业务里,比如让机器人处理群里的工单查询、会议纪要整理、代码片段解释。模型出口继续用 TaoToken 的兼容接口,需要换模型时只改modelId一个字段,钉钉侧配置完全不用动。如果你要长期跑 Agent 类任务,Coding Plan 的额度模型更适合高频调用,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
日常维护上,建议把clientSecret和 TaoToken Key 放在环境变量里而不是明文写进配置文件,OpenClaw 支持${ENV_VAR}形式的引用。这样配置文件可以进版本库,密钥不会泄露。另外钉钉后台的 Client Secret 支持重置,如果怀疑泄露,重置后同步更新 OpenClaw 配置并重启即可。
验证模型对话效果可以直接在 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 里试,确认模型行为符合预期再接到钉钉。API Key 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。遇到 Stream 连接类问题优先查文档里的排障章节,比在群里问快得多。