|
1 | 1 | # 钉钉接入 |
2 | 2 |
|
3 | | -钉钉接入走 DingTalk Stream,不需要公网回调地址。桌面端设置页支持扫码创建并授权机器人,授权成功后会把 `clientId / clientSecret` 写入 `~/.claude/adapters.json`。 |
| 3 | +> 钉钉 Adapter 的接入教程。钉钉走 DingTalk Stream,不需要公网回调地址。 |
4 | 4 |
|
5 | | -## 配置方式 |
| 5 | +## 适用场景 |
6 | 6 |
|
7 | | -打开 Desktop Webapp 的 `Settings -> IM 接入 -> 钉钉`。 |
| 7 | +钉钉方案适合通过钉钉单聊远程驱动本机 Claude Code。当前实现只处理单聊消息,不处理群聊。 |
8 | 8 |
|
9 | | -推荐方式: |
| 9 | +当前实现支持文本聊天、图片附件、项目选择、状态查看、停止生成、AI Card 流式输出,以及文本或卡片形式的权限审批。 |
10 | 10 |
|
11 | | -1. 点击“扫码绑定” |
12 | | -2. 使用钉钉手机 App 扫码 |
13 | | -3. 在钉钉里确认创建机器人 |
14 | | -4. 等待桌面端显示已绑定 |
| 11 | +实现入口:`adapters/dingtalk/index.ts` |
| 12 | + |
| 13 | +## 1. 绑定钉钉机器人 |
| 14 | + |
| 15 | +打开桌面端 `设置 -> IM 接入 -> 钉钉`。 |
| 16 | + |
| 17 | +推荐使用扫码绑定: |
| 18 | + |
| 19 | +1. 点击「扫码绑定」。 |
| 20 | +2. 使用钉钉手机 App 扫码。 |
| 21 | +3. 在钉钉里确认创建并授权机器人。 |
| 22 | +4. 等待桌面端显示「钉钉机器人已绑定」。 |
| 23 | +5. 点击保存,或确认当前配置已经写入本地。 |
| 24 | + |
| 25 | +授权成功后,桌面端会把 `clientId` 和 `clientSecret` 写入 `~/.claude/adapters.json` 的 `dingtalk` 配置。发布版桌面端会重启 adapter sidecar,让新凭据立即生效。 |
| 26 | + |
| 27 | + |
| 28 | + |
| 29 | +## 2. 手动填写凭据 |
15 | 30 |
|
16 | 31 | 如果扫码不可用,也可以手动填写: |
17 | 32 |
|
18 | | -- `Client ID` |
19 | | -- `Client Secret` |
20 | | -- 可选 `Stream Endpoint` |
21 | | -- 可选 `Allowed Users` |
22 | | -- 可选 `权限卡片模板 ID` |
| 33 | +- `Client ID` — 钉钉应用的 `appKey` |
| 34 | +- `Client Secret` — 钉钉应用的 `appSecret` |
| 35 | +- `Stream Endpoint` — 可选,默认 `https://api.dingtalk.com` |
| 36 | +- `权限卡片模板 ID` — 可选,配置后权限请求优先使用钉钉互动卡片 |
| 37 | +- `Allowed Users` — 可选,直接放行指定钉钉用户 ID |
| 38 | + |
| 39 | +保存后 adapter 会用 DingTalk Stream 建立长连接。 |
| 40 | + |
| 41 | +## 3. 授权具体钉钉用户 |
| 42 | + |
| 43 | +机器人绑定完成后,还需要让具体用户通过配对码授权: |
| 44 | + |
| 45 | +1. 在 `设置 -> IM 接入` 顶部的「配对管理」里点击「生成配对码」。 |
| 46 | +2. 在钉钉机器人单聊里发送这枚 6 位配对码。 |
| 47 | +3. 看到配对成功提示后,就可以开始聊天。 |
| 48 | + |
| 49 | + |
| 50 | + |
| 51 | +配对码有效期 60 分钟,一次性使用。配对用户会出现在「已配对用户」列表里,可以随时解绑。解绑后该用户需要重新发送新的配对码才能使用。 |
| 52 | + |
| 53 | +## 4. 选择项目并开始对话 |
| 54 | + |
| 55 | +如果已经配置默认项目,发送任意消息会直接在该目录下创建或复用 Claude Code session。 |
| 56 | + |
| 57 | +如果没有配置默认项目,adapter 会返回最近项目列表。回复编号、项目名或绝对路径后,会新建会话并绑定到当前钉钉 chat。 |
| 58 | + |
| 59 | +后续消息会复用 `~/.claude/adapter-sessions.json` 里的 chat 到 session 映射。发送 `/new` 可以重新选择项目并开启新会话。 |
| 60 | + |
| 61 | +## 支持的命令 |
| 62 | + |
| 63 | +钉钉这里没有像飞书那样的机器人菜单配置流程;当前命令入口就是单聊输入框。配对成功后,bot 会提示发送 `/help`;用户也可以随时发送 `/help` 或 `帮助` 查看完整命令列表。 |
| 64 | + |
| 65 | +- `/help` 或 `帮助` — 显示可用命令 |
| 66 | +- `/status` 或 `状态` — 查看当前会话的项目、分支、模型、运行状态和任务摘要 |
| 67 | +- `/projects` 或 `项目列表` — 重新显示最近项目列表 |
| 68 | +- `/new` 或 `新会话` — 清空当前 chat 绑定的 session,并重新选择项目 |
| 69 | +- `/new <编号、项目名或绝对路径>` — 直接在指定项目下新建会话 |
| 70 | +- `/clear` 或 `清空` — 清空当前会话上下文,保留项目绑定 |
| 71 | +- `/stop` 或 `停止` — 向当前 session 发送 `stop_generation` |
| 72 | + |
| 73 | +## 权限审批 |
| 74 | + |
| 75 | +默认情况下,钉钉 adapter 会发送文本审批消息。回复: |
| 76 | + |
| 77 | +- `/allow <requestId>` — 允许一次权限请求 |
| 78 | +- `/always <requestId>` — 永久允许同类权限请求 |
| 79 | +- `/deny <requestId>` — 拒绝一次权限请求 |
| 80 | + |
| 81 | +如果配置了已发布的钉钉互动卡片模板 ID,adapter 会优先发送权限卡片,并通过 DingTalk Stream 的 `/v1.0/card/instances/callback` 接收按钮回调。卡片发送失败或不可见时,仍可使用文本命令审批。 |
23 | 82 |
|
24 | | -## 配对用户 |
| 83 | +## 返回消息的表现 |
25 | 84 |
|
26 | | -钉钉机器人绑定完成后,还需要让具体用户通过 IM 配对码授权: |
| 85 | +- 使用 `dingtalk-stream` 接收机器人单聊消息。 |
| 86 | +- 使用消息里的 `sessionWebhook` 回复 Markdown 文本。 |
| 87 | +- 普通回复优先使用 AI Card 做流式输出。 |
| 88 | +- 权限审批可以使用互动卡片;没有模板时自动回退文本命令。 |
| 89 | +- 图片附件会下载后以内联图片形式进入模型输入。 |
| 90 | +- 附件会走公共大小限制检查,超限时 adapter 会在钉钉里返回提示。 |
27 | 91 |
|
28 | | -1. 在 `配对管理` 里生成配对码 |
29 | | -2. 在钉钉私聊里把配对码发给机器人 |
30 | | -3. 显示配对成功后即可开始聊天 |
| 92 | +## 解绑 |
31 | 93 |
|
32 | | -配对用户会出现在“已配对用户”列表里,可以随时解绑。解绑后该用户需要重新发送新的配对码才能使用。 |
| 94 | +有两种解绑: |
33 | 95 |
|
34 | | -## 运行 adapter |
| 96 | +- 解绑钉钉机器人账号:在钉钉标签页点击「解绑机器人账号」,会清空 `dingtalk.clientId`、`dingtalk.clientSecret`、`allowedUsers`、`pairedUsers` 和权限卡片模板 ID。 |
| 97 | +- 解绑某个用户:在「已配对用户」列表里点击对应钉钉用户右侧的「解绑」,只移除该用户的 `pairedUsers` 记录。 |
35 | 98 |
|
36 | | -桌面端发布版会通过 sidecar 自动启动。开发时可以手动运行: |
| 99 | +解绑机器人账号后需要重新扫码或手动填写凭据。解绑用户后,该用户需要重新发送新的配对码才能继续使用。 |
| 100 | + |
| 101 | +## 本地开发启动 |
| 102 | + |
| 103 | +发布版桌面端会自动启动 adapter sidecar。只有本地开发或单独调试时才需要手动运行: |
37 | 104 |
|
38 | 105 | ```bash |
39 | 106 | cd adapters |
40 | 107 | bun install |
41 | 108 | bun run dingtalk |
42 | 109 | ``` |
43 | 110 |
|
44 | | -## 当前行为 |
| 111 | +可选环境变量: |
| 112 | + |
| 113 | +```bash |
| 114 | +export DINGTALK_CLIENT_ID="..." |
| 115 | +export DINGTALK_CLIENT_SECRET="..." |
| 116 | +export DINGTALK_STREAM_ENDPOINT="https://api.dingtalk.com" |
| 117 | +export DINGTALK_PERMISSION_CARD_TEMPLATE_ID="..." |
| 118 | +export ADAPTER_SERVER_URL="ws://127.0.0.1:3456" |
| 119 | +``` |
| 120 | + |
| 121 | +正常桌面端使用不需要手动设置这些环境变量,扫码绑定或手动填写会写入本地配置。 |
| 122 | + |
| 123 | +## 常见问题 |
| 124 | + |
| 125 | +### 扫码成功后发消息仍提示未授权 |
| 126 | + |
| 127 | +这是正常授权流程的一部分。扫码绑定只写入机器人凭据;具体钉钉用户还需要发送配对码,或被加入 `Allowed Users`。 |
| 128 | + |
| 129 | +### 扫码失败或一直等待确认 |
| 130 | + |
| 131 | +重新点击「扫码绑定」生成新二维码。如果仍失败,可以手动填写 `Client ID` 和 `Client Secret`。 |
| 132 | + |
| 133 | +### adapter 启动时报缺少 clientId / clientSecret |
| 134 | + |
| 135 | +说明 `DINGTALK_CLIENT_ID / DINGTALK_CLIENT_SECRET` 和 `~/.claude/adapters.json` 里的 `dingtalk.clientId / dingtalk.clientSecret` 都没有生效。先在桌面端钉钉标签页完成扫码绑定或手动填写凭据。 |
| 136 | + |
| 137 | +### 权限卡片没有出现 |
| 138 | + |
| 139 | +优先检查: |
| 140 | + |
| 141 | +- 是否已经配置发布后的权限卡片模板 ID。 |
| 142 | +- 模板是否支持 adapter 使用的回调路由。 |
| 143 | +- 当前机器人是否已经发布新版本。 |
| 144 | + |
| 145 | +即使卡片不可见,也可以用 `/allow <requestId>`、`/always <requestId>`、`/deny <requestId>` 完成审批。 |
| 146 | + |
| 147 | +### 收不到回复 |
| 148 | + |
| 149 | +优先检查: |
| 150 | + |
| 151 | +- 桌面端是否正在运行。 |
| 152 | +- 钉钉标签页是否显示已绑定。 |
| 153 | +- 当前用户是否已经配对或在 `Allowed Users` 中。 |
| 154 | +- `~/.claude/adapters.json` 是否能正常写入。 |
| 155 | +- 本地开发时 `ADAPTER_SERVER_URL` 是否指向正在运行的 Desktop server WebSocket 地址。 |
| 156 | + |
| 157 | +### 会话没恢复 |
| 158 | + |
| 159 | +检查 `~/.claude/adapter-sessions.json` 是否能正常写入,以及 Desktop server 里的 session 是否仍存在。 |
| 160 | + |
| 161 | +## 源码入口 |
45 | 162 |
|
46 | | -- 只处理钉钉单聊消息 |
47 | | -- 使用 `sessionWebhook` 回复文本 / Markdown |
48 | | -- 支持用户图片附件进入模型输入 |
49 | | -- 支持 AI Card 流式输出和 thinking / 输入状态展示 |
50 | | -- 支持 `/new`、`/projects`、`/status`、`/clear`、`/stop`、`/help` |
51 | | -- 权限确认支持 `/allow <requestId>`、`/always <requestId>`、`/deny <requestId>` 文本回复 |
52 | | -- 如果配置了已发布的钉钉互动卡片模板 ID,会优先发送权限卡片,并通过 DingTalk Stream 的 `/v1.0/card/instances/callback` 接收按钮回调;卡片发送失败时自动回退到文本命令 |
53 | | -- 群聊后续再扩展 |
| 163 | +- `adapters/dingtalk/index.ts` |
| 164 | +- `adapters/dingtalk/helpers.ts` |
| 165 | +- `adapters/dingtalk/ai-card.ts` |
| 166 | +- `adapters/dingtalk/permission-card.ts` |
| 167 | +- `adapters/dingtalk/media.ts` |
| 168 | +- `adapters/common/pairing.ts` |
| 169 | +- `adapters/common/session-store.ts` |
| 170 | +- `adapters/common/ws-bridge.ts` |
| 171 | +- `adapters/common/http-client.ts` |
0 commit comments