Skip to content

docs(chat-skill): 建号改用服务端 API + Stream 建联,下线扫码 device-auth#407

Open
PeterGuy326 wants to merge 10 commits into
DingTalk-Real-AI:mainfrom
PeterGuy326:feat/chat-bot-provisioning-openclaw
Open

docs(chat-skill): 建号改用服务端 API + Stream 建联,下线扫码 device-auth#407
PeterGuy326 wants to merge 10 commits into
DingTalk-Real-AI:mainfrom
PeterGuy326:feat/chat-bot-provisioning-openclaw

Conversation

@PeterGuy326
Copy link
Copy Markdown
Collaborator

@PeterGuy326 PeterGuy326 commented Jun 4, 2026

背景

机器人 provisioning 原走「扫码 device-auth」(npx -y @dingtalk-real-ai/dingtalk-connector install),交互式、需人工扫码。本 PR 改为服务端 API 一次建号 + DWClient Stream 建联,并下线扫码老逻辑

改了什么

provisioning recipe 重构为三段链路:

  1. ① 建号 — 服务端 API POST /v1.0/microApp/agent/create 一次拿 robotCode / clientId / clientSecret,无需扫码、可无人值守。
  2. ② Stream 建联 — 拿 clientId/secret 起 DWClient 订阅 TOPIC_ROBOT,agent 收→回(运行时两条对等路径:openclaw/plugin-sdk 契约 / OpenAI-compatible endpoint 保持不变,机制概念 + 指向 dingtalk-openclaw-connector)。
  3. ③ 审批 + 验证qyapi_robot_sendmsg 审批闸门(建号≠可用)+ 真实发消息探测 + chat bot search 交叉验证(保留)。

删除所有「扫码 / 二维码 / device-auth / connector install」表述。best_practices 新增 provision-bot recipe 行。

涉及文件

  • skills/mono/references/products/chat.mdskills/multi/dingtalk-chat/references/chat.md — 主 recipe 重写
  • skills/multi/dingtalk-chat/SKILL.md — 意图表 + 跨产品协作两处
  • skills/mono/references/best_practices/01-messaging.mdskills/multi/dingtalk-chat/references/01-messaging.md — 新增 provision-bot 行

⚠️ 已知过渡风险(请评审知悉)

新的 API/MCP 建号路径尚未上线(MCP 工具上游待建)。本 PR 合并后到工具上线前,skill 内建号步骤不可直接闭环——存在过渡真空期。文档已明确标注「目标态,依赖上游 MCP 工具上线」,并给出临时 dws api 裸调验证方式(需调用者自带带建号 scope 的创建者凭证),不写 discovery 里不存在的幽灵命令

落地分工:建号 API 封成服务端 MCP 工具(含调用方授权校验)在上游服务端;CLI 侧只承接 overlay 入口 + 本文档。


更新(2026-06-04):建号命令落地为「异步两步 + 轮询」,端到端验证通过

dws chat bot create 已落地并在预发真机验证。相比上文初始的同步 API 设计有两点调整 + 一个关键修复:

① 接口改为异步两步(上游为「避免重复建号」重新设计):

  • submit_robot_create_task → 返回 taskId / status / interval / expiresIn / retryCount,corpId/userid 系统注入,支持传原 taskId 重试
  • query_robot_create_result → 按 taskId 轮询,WAITING / SUCCESS / FAIL / EXPIRED;SUCCESS 返回 agentId / robotCode / clientId / clientSecret

命令行为:内部 submit 拿 taskId → 按返回的 interval 阻塞轮询 query 至终态;FAIL/EXPIRED 带 taskId 返回,新增 --task-id 重试避免重复建号;端点保持命名别名 /server/op-app(按登录态归属,不写死 ?key= 密钥)。

② 关键修复(commit c6d95ae:服务端返回是 content → result 两层壳,轮询取 taskId/status 时原代码只解一层 → taskId 读空 → 轮询空转、命令只返回首个 WAITING。已改为依次解包 contentresult

③ 端到端验证(预发,临时把端点指向上游 ?key= server 实跑)

  • submit → 轮询 query → status=SUCCESS,真建出机器人(agentId=4644737015robotCode/clientId=dingkgggfexxdojase8b、返回 clientSecret)
  • 用该凭证起 DWClient Stream:connect success、订阅 TOPIC_ROBOT,建联闭环通
  • go build / go vet / 轮询单测(mock 还原真实嵌套壳 + 负向验证可兜回归)/ helpers 全量单测 全过

④ 待上游:正式 op-app 路径需服务端把 submit_robot_create_task / query_robot_create_result 挂到 /server/op-app 并刷新 market_mcp_tools;挂好后跑 op-app 路径端到端即彻底闭环。

dws chat bot can only search/add-to-group bots, not create one. When a
user asks "give me a bot / 接入 OpenClaw", the agent had no guided path.

Add a "创建新机器人" recipe to the chat product reference (mono + multi)
and wire trigger words + an intent row into the dingtalk-chat skill so
dispatch routes the request. The recipe orchestrates the official
@dingtalk-real-ai/dingtalk-connector (preflight gate -> npx install ->
QR scan -> cross-verify via `dws chat bot search`), and is explicit that
the flow depends on non-dws prerequisites (OpenClaw runtime + npm + QR)
so the agent never fakes a successful creation.

Docs-only: no Go / command-surface change.
The first version gated the recipe on `openclaw -v`, which wrongly
implied OpenClaw-only. The connector is host-agnostic by design
(`peerDependencies.openclaw` is optional; the `bin install` device-auth
flow mints the bot via DingTalk OpenAPI with zero OpenClaw dependency).

Reframe the recipe into two layers:
- 建号 (provisioning): host-agnostic — npx install works in any Node env.
- 收→回 (runtime): OpenClaw and its forks (e.g. Hermes) work out of the
  box via the openclaw plugin-sdk contract; other mainstream agents
  (Claude / Cursor / Codex / ...) connect via the host's OpenAI Chat
  Completions endpoint.

Preflight gate now accepts ANY supported host instead of hard-requiring
openclaw. Cross-verify via `dws chat bot search` stays (host-agnostic).
…rmes

The recipe implied only OpenClaw/Hermes were "first-class". In fact the
dws skill (incl. this recipe) installs into every mainstream agent home
dws supports — Claude Code, Cursor, Codex, Qoder, opencode, Gemini,
Windsurf, Cline, Kiro, Trae, Hermes, OpenClaw (~14 agent homes; see
internal/app/skill_command.go + internal/upgrade/paths.go).

Reframe the runtime as two equal bridges (no "only OpenClaw"):
- openclaw/plugin-sdk channel contract (OpenClaw + forks like Hermes)
- the host's OpenAI Chat Completions endpoint (every other agent)
Hard-won lesson: device-auth SUCCESS and a successful accessToken only
prove the APP credential is live — the robot still needs the
qyapi_robot_sendmsg scope approved before it can actually send/receive.
`openclaw channels status: connected` is just the stream WS, NOT a
DingTalk capability receipt, and must not be treated as "connected = done".

Add step 5 (approval-gate probe: get token -> robot/groupMessages/send;
AccessDenied on qyapi_robot_sendmsg => pending, apply via the open-dev
appscope link DingTalk returns) and a prominent caveat bullet.
机器人 provisioning 从「扫码 device-auth(npx @dingtalk-real-ai/dingtalk-connector install)」
改为服务端 API + DWClient Stream 建联,并删除所有扫码/device-auth 表述:

- 建号:POST /v1.0/microApp/agent/create 一次拿 robotCode/clientId/clientSecret,
  无需扫码、可无人值守。标注为目标态(依赖上游 MCP 工具上线,封成 mcp-gw 工具后
  dws 自动生成命令),并给出临时 dws api 裸调验证方式(需自带创建者凭证)。
- 建联:拿 clientId/secret 起 DWClient 订阅 TOPIC_ROBOT,agent 收→回;运行时两条
  对等路径(openclaw/plugin-sdk 契约 / OpenAI-compatible endpoint)保持不变。
- 审批闸门「建号≠可用」(qyapi_robot_sendmsg) + 真实发消息探测 + 交叉验证保留。
- best_practices 新增 provision-bot recipe 行。

注意:新 API/MCP 建号路径尚未上线,本 PR 合并后到工具上线前,skill 内建号步骤
不可直接闭环(过渡真空期,已在文档中明确标注,不写幽灵命令)。

涉及:chat.md(mono+multi)、dingtalk-chat/SKILL.md、01-messaging.md(mono+multi)
新增原生命令 `dws chat bot create`,调用「钉钉开放平台应用管理」MCP 的
create_dingtalk_robot 工具,一次性建号(企业自建 Agent 应用 + 承载机器人),
返回 agentId / robotCode / clientId / clientSecret(clientSecret 仅返回一次)。
corpId / userid 由 MCP 服务端按当前登录身份注入。

- internal/helpers/chat.go:新增 create 子命令 + robotCreateInvoke,
  路由 CanonicalProduct "opendev",必填 --app-name/--robot-name/--desc,
  可选 --robot-media-id/--preview-media-id
- internal/app/direct_runtime.go:硬编码 opendev 的 MCP 端点(不走服务发现),
  仿 PAT built-in;env-var DINGTALK_OPENDEV_MCP_URL 仍可覆盖
- internal/transport/client.go:支持 MCP 广场自包含 ?key= URL——可信域名上带
  key 的端点保留 query 并跳过会话 bearer(key 即凭据),否则维持原有
  strip query + bearer 行为(防参数注入)。含单元测试,普通端点无回归
- skills:chat.md / SKILL.md / best_practices 三处同步为真实命令,
  替换原「目标态/依赖上游 MCP 工具上线」占位措辞

预发已端到端验证:dws chat bot create 成功建号并返回完整凭据。
新增 scripts/bot_stream_probe.js(mono+multi):用 dingtalk-stream DWClient 起
Stream 连接、订阅 TOPIC_ROBOT,收到 @机器人 消息后经 sessionWebhook 回 echo,
最小验证 dws chat bot create 建出机器人的「建联 + 收→回」闭环,不依赖完整
OpenClaw/Hermes 运行时。chat.md ② 段补「建联自检」步骤指向该脚本。

预发已验证:connect success(建联通过)。收→回的最后一公里需机器人过
qyapi_robot_sendmsg 审批 + 一条真实 @ 消息触发。
robotCreateEndpoint 从带 ?key= 的 hash 端点改为命名别名
https://pre-mcp-gw.dingtalk.com/server/op-app。无 key → 走会话 bearer 鉴权,
建出的机器人按当前登录身份归属(不再固定归 key 绑定的账号)。

注意:该端点为另一套寻址,需调用方 bearer 在已注册 op-app 的组织/身份下才暴露
create_dingtalk_robot;预发用 MCP 默认凭证登录暂报「未找到指定工具」,待正确身份/
服务端注册后生效。transport 的 key-URL 兼容逻辑保留(此端点无 key 不触发)。
- create_dingtalk_robot(同步一把梭) → submit_robot_create_task + query_robot_create_result(异步)
- 阻塞轮询到 SUCCESS/FAIL/EXPIRED;失败带 taskId,新增 --task-id 重试避免重复建号
- 修复 bug:服务端返回是 content→result 两层壳,原只解一层导致 taskId 读空、轮询空转
  (已端到端验证:真建出机器人并起 Stream 建联 connect success)
- 端点保持 op-app 命名别名(按登录态归属,不写死 ?key= 密钥)
- 补轮询单测,mock 还原真实嵌套壳,负向验证能兜住该回归
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant