ReMe/skills/dingtalk-message
jinliyl 46adb5ae1e
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: add daily paper cookbook and DingTalk agent integration (#385)
* 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
2026-07-22 19:17:01 +08:00
..
scripts feat: add daily paper cookbook and DingTalk agent integration (#385) 2026-07-22 19:17:01 +08:00
package.json feat: add daily paper cookbook and DingTalk agent integration (#385) 2026-07-22 19:17:01 +08:00
README.md feat: add daily paper cookbook and DingTalk agent integration (#385) 2026-07-22 19:17:01 +08:00
SKILL.md feat: add daily paper cookbook and DingTalk agent integration (#385) 2026-07-22 19:17:01 +08:00

钉钉消息发送技能 (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&timestamp=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
    }
}

不支持 @功能

{
    "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) 正常支持
图片 ![alt](图片url) 正常支持
无序列表 - 列表项 正常支持
有序列表 1. 列表项 正常支持
引用 > 引用文字 正常支持

不支持的语法(禁止使用)

以下语法在钉钉中不会被渲染,甚至可能导致显示异常:

  • 水平分隔线:---、***、___
  • 表格:| col1 | col2 |
  • 代码块:```
  • 行内代码:`code`
  • 删除线:~~text~~
  • 任务列表:- [ ] item
  • 斜体:*italic*(不稳定)
  • 嵌套列表:多级缩进列表(显示不稳定)

编写建议

  1. 用 # ~ #### 标题组织结构
  2. 用 - item 无序列表展示条目
  3. 用 **重点** 加粗强调关键信息
  4. 用 > 备注 添加补充说明
  5. 不要用分隔线,用标题或空行替代
  6. 不要用表格,用列表格式替代
  7. 在 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