|
Some checks failed
Pre-commit / run (ubuntu-latest) (push) Has been cancelled
Tests ReMe / Unit Tests - py3.11 (push) Has been cancelled
Tests ReMe / Unit Tests - py3.12 (push) Has been cancelled
Tests ReMe / Unit Tests - py3.13 (push) Has been cancelled
Windows Smoke / CLI smoke - py3.11 (push) Has been cancelled
* feat(daily-paper): add daily paper cookbook workflow with schema and tests - Introduce daily paper schema types (DailyBriefOutput, PaperInfo, PaperNoteOutput, etc.) - Create daily paper cookbook module with analyze, collect, digest, rank, and select steps - Add cookbook entry point and integrate into main steps module - Replace job config export with daily brief output in schema exports - Add comprehensive unit tests covering pipeline, filtering, and output generation - Update dependencies including openai-codex and pypdf packages - Configure standalone daily paper cron job with proper scheduling and routing * test(daily_paper): update tests to use Claude Code wrapper exclusively - Add test to verify web search is disallowed by default in Claude Code - Update imports to include DailyBriefOutput, PaperNoteOutput, and PaperSelection schemas - Change test name from standalone_config_has_backend_split to reflect Claude Code only usage - Remove default agent wrapper and configure all steps to use Claude Code wrapper - Rename select_wrapper to cc_wrapper for clarity and consistency - Remove duplicate Claude Code wrapper initialization - Update test assertions to verify output schema usage matches expected sequence - Remove unused as_llm component from standalone configuration test * refactor(agent-wrapper): simplify skill resolution logic across all wrappers - Replace duplicate skill resolution code with centralized _resolve_project_skills method - Add project_path property with configurable relative path resolution - Introduce proper validation for skill names and directory existence - Change Codex wrapper to use project_path instead of workspace_path for skills - Add SKILL.md requirement validation for project skills - Remove redundant skill processing logic from individual wrappers * feat(daily_paper): add daily paper workflow with PDF analysis and brief generation - Implement shared state management and file helpers for daily-paper steps - Add PDF download and text extraction capabilities with arXiv integration - Create paper collection step with Hugging Face weekly/monthly rankings - Build ranking system using reciprocal-rank fusion with memory keyword scoring - Add Claude Code integration for paper analysis and detailed note generation - Implement digest step to create final five-minute brief from detailed notes - Add configuration for standalone daily cookbook application with cron scheduling - Create typed schema for paper information, selection, and output formats - Add atomic file writing with temporary file safety mechanisms - Implement exclusion logic for previously recommended papers and daily filters * feat(daily_paper): add DingTalk notification integration and enhance logging - Integrate DingTalk markdown send step to notify groups about daily paper briefs - Add comprehensive logging throughout daily paper workflow including start/finish events - Update daily paper analysis prompt to include code repository context requirement - Configure DingTalk notification in daily_cookbook.yaml with app credentials - Add dingtalk-stream dependency for proactive message API integration - Enhance daily paper README with DingTalk notification section and updated flow chart - Implement detailed logging for each step including paper processing and agent calls - Add test coverage for DingTalk markdown sending functionality and configuration - Update pre-commit config to exclude skills directory from checks - Add .claude/skills to gitignore for local development environment * refactor(dingtalk): move dingtalk_stream import to local scope and improve code safety - Moved global dingtalk_stream import to local scope in send.py to avoid eager loading - Added dynamic import with error handling for optional dependency cases - Updated test suite to verify lazy loading behavior works correctly - Fixed markdown title generation by using safe variable naming in wait.py - Enhanced test coverage for arxiv PDF download caching functionality - Updated application context initialization with proper resource directory configuration - Modified paper metadata to include source PDF path reference in output files * refactor(daily_paper): remove manifest system and store selection metadata in digest files - Remove JSON manifest creation and storage functionality - Store selection data directly in digest file frontmatter instead of separate manifest files - Add load_saved_selection method to rebuild selection from digest and paper-note metadata - Update README documentation to reflect new cookbook workflow architecture - Modify test cases to verify selection metadata in digest files instead of manifest JSON - Remove unused json import from multiple daily paper modules - Integrate PaperSelection schema for proper data validation in stored metadata * docs(daily_paper): add bilingual cookbook guides |
||
|---|---|---|
| .. | ||
| scripts | ||
| package.json | ||
| README.md | ||
| SKILL.md | ||
钉钉消息发送技能 (dingtalk-message)
钉钉消息发送 CLI 工具,支持企业内部机器人和 Webhook 自定义机器人两种接入方式,支持文本、Markdown、链接、ActionCard、FeedCard、文件等多种消息类型。
官方文档:https://open.dingtalk.com/document/development/development-robot-overview
目录
API 接口文档
一、企业内部机器人 API
1. 批量发送人与机器人会话中机器人消息
官方文档:https://open.dingtalk.com/document/development/chatbots-send-one-on-one-chat-messages-in-batches
接口概述
调用本接口批量发送人与机器人会话(即人与机器人的单聊)中的机器人消息。通过该接口,企业内部应用的机器人可以向多个用户同时发送单聊消息。
请求方式
- HTTP 方法:
POST - URL:
https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend
请求头
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
x-acs-dingtalk-access-token |
String | 是 | 调用服务端接口的授权凭证(access_token) |
Content-Type |
String | 是 | 固定值:application/json |
请求体参数(Body)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
robotCode |
String | 是 | 机器人的编码(robotCode),可在钉钉开发者后台的机器人管理页面获取 |
userIds |
List<String> | 是 | 接收消息的用户 userId 列表,最多支持 100 个 |
msgKey |
String | 是 | 消息模板 Key,用于指定消息类型,见下方消息类型 msgKey 映射表 |
msgParam |
String | 是 | 消息模板参数,JSON 字符串格式,内容结构取决于 msgKey 的类型 |
消息类型 msgKey 映射表
| 消息类型 | msgKey 值 | 说明 |
|---|---|---|
| 文本消息 | sampleText |
纯文本消息,支持 @用户 |
| 图片消息 | sampleImage |
需先上传获取 media_id |
| 语音消息 | sampleVoice |
需先上传获取 media_id |
| 文件消息 | sampleFile |
需先上传获取 media_id |
| 链接消息 | sampleLink |
带缩略图的链接卡片 |
| Markdown 消息 | sampleMarkdown |
支持有限 Markdown 语法 |
| ActionCard(单按钮) | sampleActionCard |
单按钮交互卡片 |
| ActionCard(多按钮) | sampleMultiActionCard |
多按钮交互卡片 |
各消息类型 msgParam 结构
文本消息 (sampleText)
{
"content": "消息内容",
"atUserIds": ["userId1", "userId2"] // 可选,@指定用户
}
Markdown 消息 (sampleMarkdown)
{
"title": "消息标题",
"text": "#### 标题\n> 引用内容\n正文"
}
链接消息 (sampleLink)
{
"title": "链接标题",
"text": "链接描述",
"messageUrl": "https://example.com",
"picUrl": "https://example.com/image.png" // 可选,缩略图
}
图片消息 (sampleImage)
{
"mediaId": "@lADPxxxxxxxx",
"caption": "图片描述" // 可选
}
文件消息 (sampleFile)
{
"mediaId": "@lADPxxxxxxxx",
"fileName": "报告.pdf",
"fileSize": "1024", // 可选,单位:字节
"fileType": "pdf" // 可选
}
语音消息 (sampleVoice)
{
"mediaId": "@lADPxxxxxxxx",
"duration": "10", // 语音时长,单位:秒
"fileSize": "2048" // 可选,单位:字节
}
ActionCard 单按钮 (sampleActionCard)
{
"title": "卡片标题",
"markdown": "#### 内容标题\n正文",
"singleTitle": "查看详情",
"singleUrl": "https://example.com"
}
ActionCard 多按钮 (sampleMultiActionCard)
{
"title": "卡片标题",
"markdown": "#### 内容标题\n正文",
"btnOrientation": "0", // "0"=竖排,"1"=横排
"btns": [
{"title": "同意", "url": "https://example.com/approve"},
{"title": "拒绝", "url": "https://example.com/reject"}
]
}
响应参数
| 参数名 | 类型 | 说明 |
|---|---|---|
processQueryKey |
String | 消息发送任务的查询 Key,可用于查询发送结果 |
成功响应示例:
{
"processQueryKey": "msgTaskId_xxx"
}
错误响应示例:
{
"code": "InvalidParameter.RobotCode",
"message": "robotCode is invalid",
"requestid": "xxxx-xxxx-xxxx"
}
请求示例(cURL)
curl -X POST 'https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend' \
-H 'x-acs-dingtalk-access-token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"robotCode": "dingxxxxxxxx",
"userIds": ["user001", "user002"],
"msgKey": "sampleText",
"msgParam": "{\"content\": \"Hello, 这是一条测试消息!\"}"
}'
请求示例(Python)
import requests
import json
url = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend"
headers = {
"x-acs-dingtalk-access-token": "YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
payload = {
"robotCode": "dingxxxxxxxx",
"userIds": ["user001", "user002"],
"msgKey": "sampleText",
"msgParam": json.dumps({"content": "Hello, 这是一条测试消息!"})
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())
2. 发送群聊消息
官方文档:https://open.dingtalk.com/document/orgapp/the-robot-sends-a-group-message
接口概述
调用本接口向指定群聊发送机器人消息。机器人需要先加入群聊才能发送消息。
请求方式
- HTTP 方法:
POST - URL:
https://api.dingtalk.com/v1.0/robot/groupMessages/send
请求头
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
x-acs-dingtalk-access-token |
String | 是 | access_token |
Content-Type |
String | 是 | 固定值:application/json |
请求体参数(Body)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
robotCode |
String | 是 | 机器人编码 |
openConversationId |
String | 是 | 群聊会话 ID |
msgKey |
String | 是 | 消息模板 Key |
msgParam |
String | 是 | 消息模板参数,JSON 字符串 |
响应参数
| 参数名 | 类型 | 说明 |
|---|---|---|
processQueryKey |
String | 消息发送任务的查询 Key |
3. 获取 Access Token
官方文档:https://open.dingtalk.com/document/orgapp/obtain-the-access_token-of-an-internal-app
请求方式
- HTTP 方法:
GET - URL:
https://oapi.dingtalk.com/gettoken
查询参数(Query)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
appkey |
String | 是 | 应用的 AppKey |
appsecret |
String | 是 | 应用的 AppSecret |
响应参数
| 参数名 | 类型 | 说明 |
|---|---|---|
errcode |
Number | 错误码,0 表示成功 |
errmsg |
String | 错误信息 |
access_token |
String | 访问凭证 |
expires_in |
Number | 有效期(秒),通常为 7200 |
响应示例
{
"errcode": 0,
"errmsg": "ok",
"access_token": "xxxxxx",
"expires_in": 7200
}
4. 上传媒体文件
用于发送图片、语音、文件类消息前的文件上传。
请求方式
- HTTP 方法:
POST - URL:
https://oapi.dingtalk.com/media/upload
查询参数(Query)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
access_token |
String | 是 | 访问凭证 |
请求体参数(multipart/form-data)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
type |
String | 是 | 文件类型:image/voice/file |
media |
File | 是 | 上传的文件 |
响应参数
| 参数名 | 类型 | 说明 |
|---|---|---|
errcode |
Number | 错误码 |
errmsg |
String | 错误信息 |
media_id |
String | 媒体文件 ID,后续发送消息时使用 |
type |
String | 文件类型 |
created_at |
Number | 创建时间戳(毫秒) |
二、Webhook 自定义机器人 API
官方文档:https://open.dingtalk.com/document/orgapp/custom-bot-to-send-group-chat-messages
Webhook 概述
自定义机器人是一种可以直接添加到钉钉群聊的机器人,通过 Webhook URL 推送消息到群聊。与企业内部机器人不同,不需要创建应用、不需要 OAuth Token 流程,只需 POST JSON 到 Webhook URL 即可。
适用场景:
- 监控告警通知
- CI/CD 构建通知
- 定时数据报告推送
- 简单的群聊消息推送
Webhook URL 格式:
https://oapi.dingtalk.com/robot/send?access_token=XXXXXX
请求方式
- HTTP 方法:
POST - Content-Type:
application/json; charset=utf-8 - 频率限制:每个机器人每分钟最多发送 20 条消息
安全设置
创建自定义机器人时,必须至少选择以下三种安全方式之一:
方式一:自定义关键词
- 最多设置 10 个关键词
- 消息内容必须包含至少一个关键词,否则被拒绝
方式二:IP 地址白名单
- 配置允许的 IP 地址或 CIDR 段
- 仅允许白名单内的 IP 发送消息
方式三:加签(推荐)
启用加签后,每次请求需要在 URL 中附加 timestamp 和 sign 参数。
签名算法:
timestamp = 当前毫秒时间戳
string_to_sign = timestamp + "\n" + secret
sign = URL_Encode(Base64(HMAC-SHA256(secret, string_to_sign)))
签名后的 URL:
https://oapi.dingtalk.com/robot/send?access_token=XXXXXX×tamp=1609459200000&sign=YYYY
时间戳与服务器时间差不能超过 1 小时,否则请求被拒绝。 脚本已内置加签逻辑,只需在配置文件中设置
webhook_secret即可自动签名。
Python 签名示例:
import time, hmac, hashlib, base64, urllib.parse
def generate_sign(secret: str):
timestamp = str(round(time.time() * 1000))
string_to_sign = f'{timestamp}\n{secret}'
hmac_code = hmac.new(
secret.encode('utf-8'),
string_to_sign.encode('utf-8'),
digestmod=hashlib.sha256
).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
return timestamp, sign
Webhook 消息类型
文本消息 (text)
{
"msgtype": "text",
"text": {
"content": "消息内容"
},
"at": {
"atMobiles": ["13800138000"],
"atUserIds": ["user123"],
"isAtAll": false
}
}
Markdown 消息 (markdown)
{
"msgtype": "markdown",
"markdown": {
"title": "标题(通知栏显示)",
"text": "#### 标题\n> 引用内容\n正文"
},
"at": {
"atMobiles": ["13800138000"],
"isAtAll": false
}
}
链接消息 (link)
不支持 @功能
{
"msgtype": "link",
"link": {
"title": "链接标题",
"text": "链接描述",
"messageUrl": "https://example.com",
"picUrl": "https://example.com/image.png"
}
}
ActionCard 单按钮 (actionCard)
{
"msgtype": "actionCard",
"actionCard": {
"title": "卡片标题",
"text": "#### 内容\n正文(支持 Markdown)",
"btnOrientation": "0",
"singleTitle": "阅读全文",
"singleURL": "https://example.com/"
}
}
ActionCard 多按钮 (actionCard)
{
"msgtype": "actionCard",
"actionCard": {
"title": "卡片标题",
"text": "#### 内容\n正文",
"btnOrientation": "0",
"btns": [
{"title": "同意", "actionURL": "https://example.com/approve"},
{"title": "拒绝", "actionURL": "https://example.com/reject"}
]
}
}
注意:多按钮时使用
btns+actionURL,不要同时设置singleTitle/singleURL
FeedCard 消息 (feedCard)
不支持 @功能
{
"msgtype": "feedCard",
"feedCard": {
"links": [
{
"title": "链接标题1",
"messageURL": "https://example.com/1",
"picURL": "https://example.com/pic1.png"
},
{
"title": "链接标题2",
"messageURL": "https://example.com/2",
"picURL": "https://example.com/pic2.png"
}
]
}
}
Webhook 响应
成功:
{
"errcode": 0,
"errmsg": "ok"
}
错误示例:
{
"errcode": 310000,
"errmsg": "keywords not in content"
}
请求示例(cURL)
curl -X POST 'https://oapi.dingtalk.com/robot/send?access_token=XXXXXX' \
-H 'Content-Type: application/json; charset=utf-8' \
-d '{
"msgtype": "text",
"text": {
"content": "Hello, 这是一条 Webhook 测试消息!"
}
}'
Webhook 与企业内部机器人对比
| 维度 | Webhook 自定义机器人 | 企业内部机器人 |
|---|---|---|
| 接入方式 | 群聊添加自定义机器人 | 钉钉开放平台创建应用 |
| API 域名 | oapi.dingtalk.com/robot/send |
api.dingtalk.com/v1.0/robot/ |
| 认证方式 | URL 中的 access_token + 可选签名 | Header 中的 OAuth access_token |
| 配置项 | webhook_url, webhook_secret | app_key, app_secret, robot_code |
| 消息范围 | 仅所在群聊 | 任意用户/群聊 |
| 消息格式 | msgtype + 类型对象 |
msgKey + msgParam (JSON 字符串) |
| 频率限制 | 20 条/分钟 | 20 次/秒 |
| Token 管理 | 无需刷新(URL 固定) | Token 每 2 小时过期 |
CLI 使用指南
安装依赖
pip install requests
命令行格式
# 企业内部机器人
python scripts/dingtalk.py <消息类型> [选项参数] "<消息内容>" --users <用户ID>
# Webhook 自定义机器人(命令以 webhook- 前缀开头)
python scripts/dingtalk.py webhook-<消息类型> [选项参数] "<消息内容>"
企业内部机器人命令
发送文本消息
# 单聊
python scripts/dingtalk.py text "Hello, 这是一条测试消息!" --users user001,user002
# @指定用户
python scripts/dingtalk.py text "Hello, @user001" --users user001,user002 --at-users user001
# 群聊
python scripts/dingtalk.py text "大家好!" \
--mode group \
--conversation-id chatxxxxxxxxxxxxxxxx \
--at-mobiles 13800138000,13900139000
发送 Markdown 消息
python scripts/dingtalk.py markdown \
--title "天气提醒" \
--users user001 \
"#### 杭州天气\n> 9度,西北风1级"
发送链接消息
python scripts/dingtalk.py link \
--title "时代在进步" \
--url "https://www.dingtalk.com" \
--pic-url "https://example.com/image.png" \
--users user001 \
"点击查看详情"
发送 ActionCard 消息
# 单按钮
python scripts/dingtalk.py action-card \
--title "审批通知" \
--single-title "查看详情" \
--url "https://www.dingtalk.com" \
--users user001 \
"#### 请假申请\n请审批"
# 多按钮
python scripts/dingtalk.py action-card \
--title "审批通知" \
--buttons "同意,https://approve.com/yes;拒绝,https://approve.com/no" \
--btn-orientation 0 \
--users user001 \
"#### 请假申请"
发送文件
python scripts/dingtalk.py file \
--users user001,user002 \
--file /path/to/report.pdf \
--file-name "月度报告.pdf"
Webhook 自定义机器人命令
所有 Webhook 命令以
webhook-前缀开头。 Webhook URL 可通过--webhook-url参数传入,或在配置文件中设置webhook_url。
Webhook 发送文本消息
# 使用配置文件中的 webhook_url
python scripts/dingtalk.py webhook-text "Hello, 这是一条 Webhook 消息!"
# 通过参数指定 webhook URL
python scripts/dingtalk.py webhook-text \
--webhook-url "https://oapi.dingtalk.com/robot/send?access_token=xxx" \
"Hello, 测试消息"
# @指定手机号
python scripts/dingtalk.py webhook-text \
--at-mobiles 13800138000,13900139000 \
"通知内容 @13800138000"
# @所有人
python scripts/dingtalk.py webhook-text --at-all "全员通知"
Webhook 发送 Markdown 消息
python scripts/dingtalk.py webhook-markdown \
--title "天气提醒" \
"#### 杭州天气\n> 9度,西北风1级"
Webhook 发送链接消息
python scripts/dingtalk.py webhook-link \
--title "时代在进步" \
--url "https://www.dingtalk.com" \
--pic-url "https://example.com/image.png" \
"点击查看详情"
Webhook 发送 ActionCard 消息
# 单按钮
python scripts/dingtalk.py webhook-action-card \
--title "审批通知" \
--single-title "查看详情" \
--url "https://www.dingtalk.com" \
"#### 请假申请\n请审批"
# 多按钮
python scripts/dingtalk.py webhook-action-card \
--title "审批通知" \
--buttons "同意,https://approve.com/yes;拒绝,https://approve.com/no" \
--btn-orientation 0 \
"#### 请假申请"
Webhook 发送 FeedCard 消息
python scripts/dingtalk.py webhook-feed-card \
--links "新闻标题1,https://news1.com,https://img1.com/pic.png;新闻标题2,https://news2.com,https://img2.com/pic.png"
Webhook 使用加签
# 通过命令行参数
python scripts/dingtalk.py webhook-text \
--webhook-url "https://oapi.dingtalk.com/robot/send?access_token=xxx" \
--webhook-secret "SECxxxxxxxxxxxxxxxxxxxxxxxxxx" \
"带签名的消息"
# 或在配置文件中设置(推荐)
python scripts/dingtalk.py config --set webhook_secret=SECxxxxxxxxxxxxxxxxxxxxxxxxxx
查看帮助
python scripts/dingtalk.py --help
python scripts/dingtalk.py text --help
python scripts/dingtalk.py webhook-text --help
python scripts/dingtalk.py webhook-markdown --help
配置说明
配置文件
配置统一存储在系统配置目录,所有 AI agent 共享,无需重复配置:
| 平台 | 配置文件 | 状态文件 |
|---|---|---|
| macOS / Linux | ~/.config/dingtalk/config.json |
~/.config/dingtalk/state.json |
| Windows | %APPDATA%\dingtalk\config.json |
%APPDATA%\dingtalk\state.json |
{
"default_robot": "技术告警群",
"robots": [
{
"name": "技术告警群",
"type": "webhook",
"description": "发送技术告警到后端技术群",
"webhook_token": "YOUR_ACCESS_TOKEN",
"webhook_secret": ""
},
{
"name": "内部通知机器人",
"type": "app",
"description": "企业内部机器人,支持单聊和群聊",
"app_key": "YOUR_APP_KEY",
"app_secret": "YOUR_APP_SECRET",
"robot_code": "YOUR_ROBOT_CODE",
"agent_id": "YOUR_AGENT_ID"
}
]
}
参数获取说明
企业内部机器人
| 参数 | 说明 | 获取方式 | 必填 |
|---|---|---|---|
app_key |
应用 AppKey | 钉钉开放平台 > 应用详情 > 凭证与基础信息 | 是 |
app_secret |
应用 AppSecret | 钉钉开放平台 > 应用详情 > 凭证与基础信息 | 是 |
robot_code |
机器人编号 | 钉钉开放平台 > 应用详情 > 机器人与消息推送 | 是 |
agent_id |
应用 AgentID | 钉钉开放平台 > 应用详情 > 凭证与基础信息 | 否 |
Webhook 自定义机器人
| 参数 | 说明 | 获取方式 | 必填 |
|---|---|---|---|
webhook_url |
Webhook 地址 | 钉钉群 > 群设置 > 智能群助手 > 添加自定义机器人 > 复制 Webhook | 是 |
webhook_secret |
加签密钥 | 创建机器人时选择"加签"安全方式,复制 SEC 开头的密钥 | 否* |
*如果安全设置选择了"加签"方式,则 webhook_secret 必填。 两种机器人的配置可以同时存在于同一个配置文件中,互不影响。
配置管理命令
# 初始化配置文件
python scripts/dingtalk.py config --init
# 查看当前配置
python scripts/dingtalk.py config --show
# 设置单个配置项
python scripts/dingtalk.py config --set app_key=dingxxxxxxxxxxxx
# 添加机器人
python scripts/dingtalk.py robot-add --name "技术告警群" --type webhook --webhook-token "token_xxx"
python scripts/dingtalk.py robot-add --name "内部通知" --type app --app-key dingxxx --app-secret xxx --robot-code robot-xxx
# 强制覆盖已存在的配置
python scripts/dingtalk.py config --init --force
命令行参数覆盖
配置文件中的值可以通过命令行参数临时覆盖:
python scripts/dingtalk.py text "测试消息" \
--users user001 \
--app-key dingxxxxxxxxxxxx \
--app-secret your-secret-key \
--robot-code robot-xxxxxx
消息类型详解
| 类型 | CLI 指令 | 模式 | 说明 |
|---|---|---|---|
| 文本消息 | text |
单聊/群聊 | 纯文本,支持 @用户 |
| Markdown | markdown |
单聊/群聊 | 有限 Markdown 语法的富文本 |
| 链接消息 | link |
单聊/群聊 | 带缩略图的链接卡片 |
| ActionCard | action-card |
单聊/群聊 | 带按钮的交互卡片(单/多按钮) |
| 文件消息 | file |
仅单聊 | 发送文件,自动上传 |
| 图片消息 | image |
仅单聊 | 发送图片 |
| 语音消息 | voice |
仅单聊 | 发送语音 |
钉钉 Markdown 语法限制
钉钉的 Markdown 渲染器只支持标准 Markdown 的有限子集。
支持的语法
| 语法 | 写法 | 说明 |
|---|---|---|
| 标题 | # 一级标题 ~ ###### 六级标题 |
正常支持 |
| 加粗 | **粗体文字** |
正常支持 |
| 链接 | [链接文字](url) |
正常支持 |
| 图片 |  |
正常支持 |
| 无序列表 | - 列表项 |
正常支持 |
| 有序列表 | 1. 列表项 |
正常支持 |
| 引用 | > 引用文字 |
正常支持 |
不支持的语法(禁止使用)
以下语法在钉钉中不会被渲染,甚至可能导致显示异常:
- 水平分隔线:
---、***、___ - 表格:
| col1 | col2 | - 代码块:
``` - 行内代码:
`code` - 删除线:
~~text~~ - 任务列表:
- [ ] item - 斜体:
*italic*(不稳定) - 嵌套列表:多级缩进列表(显示不稳定)
编写建议
- 用
#~####标题组织结构 - 用
- item无序列表展示条目 - 用
**重点**加粗强调关键信息 - 用
> 备注添加补充说明 - 不要用分隔线,用标题或空行替代
- 不要用表格,用列表格式替代
- 在 CLI 中使用
\n表示换行
错误码参考
企业内部机器人
| 错误码 | 说明 |
|---|---|
| 0 | 成功 |
| -1 | 系统繁忙,请稍后重试 |
| 40001 | access_token 不存在或已过期 |
| 40002 | access_token 不合法 |
| 40004 | 无效的机器人(robotCode 错误) |
| 40007 | 无效的 openConversationId |
| 40008 | 无效的消息内容(msgParam 格式错误) |
| 40009 | 消息发送失败,用户不在该机器人可见范围 |
| 40010 | 消息发送失败,用户未与机器人建立会话 |
| 40014 | 无效的 userId |
| 40037 | 发送消息过于频繁,已触发限流 |
| 40056 | 无效的 agentId |
Webhook 自定义机器人
| 错误码 | 说明 |
|---|---|
| 0 | 成功 |
| 300001 | 无效的 token / 机器人不存在 |
| 310000 | 安全校验失败(关键词不匹配 / IP 不在白名单 / 签名错误 / 时间戳过期) |
| 302503 | 频率限制,每分钟超过 20 条 |
| 400013 | JSON 格式无效 |
注意事项与限制
企业内部机器人
频率限制
- 每个应用每秒钟最多调用 20 次 消息发送接口
- 超出限制会返回错误码
40037
用户限制
- 批量发送单聊消息时,
userIds每次最多 100 个 - 超过 100 个需分批发送
会话前置条件
- 发送单聊消息前,用户需要先与机器人建立会话(用户主动给机器人发送过消息)
- 未建立会话的用户会收到错误码
40010
文件上传
- 发送文件/图片/语音消息前,需要先通过
/media/upload接口上传文件获取media_id - CLI 工具的
file命令已自动集成上传流程
Token 管理
access_token有效期为 7200 秒(2 小时)- 工具内置缓存机制,过期前 5 分钟自动刷新
- 不建议频繁调用 gettoken 接口
Webhook 自定义机器人
频率限制
- 每个机器人每分钟最多发送 20 条 消息
- 超出限制返回错误码
302503
安全设置
- 创建机器人时必须至少选择一种安全方式:自定义关键词、IP 白名单、加签
- 使用加签时,时间戳与服务器时间差不能超过 1 小时
- 脚本内置加签逻辑,配置
webhook_secret后自动签名
消息范围
- Webhook 机器人只能在添加到的群聊中发送消息,不支持单聊
link和feedCard消息类型不支持 @功能
Token 管理
- Webhook URL 中的
access_token是固定的,无需刷新 - 只要机器人未被删除,URL 持续有效
通用
消息内容
- Markdown 消息仅支持有限语法子集,见 Markdown 语法限制
- 消息内容不宜过长,过长建议拆分或使用文件发送
- 企业内部机器人的
msgParam需要序列化为 JSON 字符串后传入(脚本已自动处理)
API 域名
- 企业内部机器人(消息发送):
https://api.dingtalk.com - 企业内部机器人(gettoken、文件上传):
https://oapi.dingtalk.com - Webhook 自定义机器人:
https://oapi.dingtalk.com/robot/send