钉钉机器人接入
License 提示
钉钉渠道暂未单独 gate(_PLATFORM_TO_FEATURE 里还没有 channel.dingtalk,默认 fail-open 放行)。若选 DMZ 中转部署,额外需要 deploy.dmz_bridge (ENTERPRISE)。
把一个 Sira 编排器接入钉钉企业内部机器人。员工在钉钉里单聊机器人、或群聊 @ 机器人,问答自动走 Sira 编排。通过 sira-channel-dingtalk 插件(基于 dingtalk-stream SDK)装载。
适用场景与限制
| 项 | 支持情况 |
|---|---|
| 钉钉企业内部应用机器人 | ✅ |
| 第三方应用 / 自定义群机器人(Webhook-only) | ❌(需"企业内部应用 + 机器人" + Stream 模式) |
| 标准版钉钉(公有云) | ✅ |
| 专属钉(私有化) | ✅(仅接入域名不同) |
| 单聊 | ✅ |
| 群聊(@ 机器人触发) | ✅ |
| 流式响应 | ⚠️ 缓冲后单次推送(缓冲到 finish 一次性发 markdown,不做增量编辑,对齐飞书) |
| 文本 / 富文本入站 | ✅ |
| 图片入站 | ✅(下载到 MinIO 后注入消息给 LLM) |
| 文件入站(pdf / Office / zip 等) | ✅(content.downloadCode → 下载 → MinIO → 文件消息) |
| 音频 / 视频入站 | ◐ 走同一通用文件下载路径;file 结构已真机验证,音 / 视频投递结构未单独验证 |
| 图片 / 文件出站(MEDIA 标签) | ✅ |
| 主动推送(定时任务结果等) | ✅(优先 session_webhook,否则机器人批量 OTO,需「主动发消息」权限) |
| 原生互动卡片 HITL | ◐ 需在钉钉「卡片平台」预注册模板(配 hitl_card_template_id);未配则自动降级为文本 HITL |
连接模式
钉钉只有 Stream 长连接(WebSocket)一种接入:Backend 主动外连钉钉,无需公网回调地址(同企业微信 AI Bot)。创建 Application 时 connection_mode 自动锁定为 stream。
第一步:在钉钉开放平台创建企业内部应用
- 打开 钉钉开放平台,用企业管理员账号登录
- 创建 企业内部应用
- 在应用里启用 机器人 能力,并把消息接收模式设为 Stream 模式(而非 HTTP 回调)
- 按需开通权限:
- 机器人「接收消息」
- 机器人「主动发消息」(主动推送 / 定时任务结果需要)
- 「通讯录读权限」(需要按 userid 直解用户姓名 / 部门 / 扫码登录时)
- 在 凭证与基础信息 页拿到:
- AppKey(也叫 Client ID)
- AppSecret(也叫 Client Secret) 6.(可选,仅原生卡片 HITL)在 卡片平台 预注册一张含 approve/reject 回调按钮的卡片模板,记下模板 ID
第二步:在 Sira 创建 Application
进入 /agent-system/applications,点 新建应用,平台选 钉钉机器人。字段:
| 字段 | 必填 | 说明 |
|---|---|---|
| 部署形态(deploy_type) | ✅ | 标准版钉钉(公有云) / 专属钉(私有化) |
| AppKey(app_id) | ✅ | 钉钉开放平台 → 应用 → 凭证与基础信息 中的 AppKey |
| AppSecret(app_secret) | ✅ | 应用的 AppSecret(编辑已有应用时留空 = 保留旧值) |
| 专属钉接入域名 | 仅专属钉 | 选「专属钉」后填 API 域名等 override(透传给 SDK) |
| 连接模式(connection_mode) | 自动 | 固定 stream,无需手填 |
绑定一个目标编排器,保存。不需要在钉钉侧填回调地址——Stream 模式由 Backend 主动发起长连接。
第三步:测试
- 在钉钉企业内把应用 / 机器人可见范围授予测试用户
- 单聊机器人发一句话 → 路由到绑定的编排器并返回
- 群聊里 @ 机器人提问 → 同样有效
入站消息处理
- SDK 在后端进程的独立 daemon 线程 + 独立事件循环里跑长连接(
client.start()自带重连)。 - 收到消息后用
run_coroutine_threadsafe调度回主事件循环,再分发给编排器。 - 文本 / 富文本:
extract_text_from_incoming_message解析(富文本按换行多段拼接)。 - 图片:
get_image_list→ 下载 → 传 MinIO → 以 presigned URL 注入消息给 LLM(message_type="image")。 - 文件:消息
content.downloadCode→messageFiles/download下载 → 传 MinIO → 以message_type="file"注入(multimodal_content带文件 URL + 文件名)。该下载接口对任意downloadCode通用,音频 / 视频若以相同结构投递也会走此路径(按文件处理);目前仅对file结构做过真机验证。 - 单聊 vs 群聊:
conversation_type1=单聊、2=群聊(群聊chat_id=openConversationId)。 - 入站
user_id取sender_staff_id(企业内 userid),与钉钉 OAuth / 通讯录身份对齐,让"对话 / 绑定 / 登录"落到同一个 Sira 用户。
出站消息
钉钉出站有两条传输通道,按场景自动选择:
| 场景 | 通道 | 格式 |
|---|---|---|
普通回复(用户刚发消息,带 session_webhook) | 消息自带的 session_webhook(有效期约几小时) | msgtype=markdown,无需企业 token / robotCode |
| 主动推送 / webhook 不可用(定时任务结果、群推送等) | 机器人 API + 企业 accessToken | msgKey=sampleMarkdown + robotCode=AppKey;群聊 robot/groupMessages/send、单聊 robot/oToMessages/batchSend |
| 文件 / 图片(MEDIA 标签) | 机器人 API(先上传拿 mediaId) | sampleImageMsg / sampleFile |
- 流式:编排器的 chunk 累积到内存 buffer,直到
finish=True才一次性发出,不做增量编辑(对齐飞书,避免触发钉钉编辑限制)。 - webhook 失效自动回落:流式回复优先用
session_webhook;若 webhook 缺失 / 过期(任务跑了几小时、HITL 隔很久才恢复等),会自动回落到机器人主动推送(与send_message一致),不再丢消息。 - ⚠️ 文件 / 图片出站走机器人 API,需要机器人「主动发消息 / 群消息主动发送」权限。若未授权导致发送失败,会回落一条文本提示告知用户「文件已生成但发送失败(可能缺权限)」,不再静默。
人工审批(HITL)
钉钉原生回调按钮卡必须在开放平台「卡片平台」预注册模板。在 Application 配 hitl_card_template_id 即启用原生卡片审批;未配置时 supports_approval_interaction() 返回 False,dispatcher 自动降级为文本 HITL(发一段文字让用户回复确认)。详见 人工审批 (HITL)。
PlatformKey 与跨渠道关联
| Key | 含义 |
|---|---|
dingtalk | 钉钉机器人(实际走的 key;别名 dingding) |
员工的钉钉 userid(sender_staff_id)通过 users.external_ids.dingtalk 关联到 Sira 用户,与企微 / 飞书 / 微信客服 / Web 等渠道身份打通——一处装的沙箱 / 建的定时任务,其它渠道也能用。
标准版钉钉 vs 专属钉
协议完全一致,差异仅在接入域名。专属钉在创建 Application 时选「专属钉(私有化)」,并填入 API / Stream 接入域名 override(透传给 SDK)。
部署多副本注意
Stream 是出站长连接(不需要公网入口)。统一渠道管线用资源锁保证多副本下只有一个进程持连(内嵌 runner 或独立 Channel Gateway 节点),不会重复连、消息不会乱发。跨网隔离场景可选 deployment="gateway" 走 DMZ 中转(需 deploy.dmz_bridge License)。
已知不支持
- 音频 / 视频入站:未单独验证。它们若以
content.downloadCode结构投递会被当作文件处理,但钉钉对语音 / 视频的实际投递结构尚未在真机验证(文件、图片已验证 ✅)。 - 原生互动卡片:未在「卡片平台」注册模板时不能用回调按钮卡(自动降级文本 HITL)。
- stop() 为 best-effort:SDK 无公开 stop,靠关闭 loop + ws 退出线程。
相关文档
- Channel Plugin 总览
- 企业微信 AI Bot 配置(同为 Stream / 长连接、无回调地址)
- 飞书机器人接入
- 对话内命令与 MEDIA 文件发送
- 人工审批 (HITL)
