
Wecom Unified
- 727 installs
- 37 repo stars
- Updated July 2, 2026
- wecomteam/wecom-unified
wecom-unified is a Claude Code skill that drives the wecom-cli tool to read, create, edit, and send WeCom corporate messages, documents, schedules, meetings, and tasks for developers building enterprise WeChat Work autom
About
wecom-unified is a Claude Code skill for the WeCom (企业微信) CLI covering six business domains: contacts, messaging, documents, schedules, meetings, and tasks. Install via npm install -g @wecom/cli@0.1.8 after verifying wecom-cli --version and wecom-cli auth show --auth-status. The skill supports contact lookup by name or alias, sending text/image/file/voice/video messages, reading and editing doc.weixin.qq.com documents, smart spreadsheet subtables, schedule management, meeting booking, and todo assignment. Developers reach for wecom-unified when building agent or script automations against WeCom corporate accounts, including triggers from doc.weixin.qq.com URLs even when users do not explicitly say 企业微信.
- Unified CLI covering 6 business domains: contacts, messaging, documents/tables, schedules, meetings, and todos
- Automatically detects doc.weixin.qq.com URLs and intelligently routes to the correct document/table/smart-sheet handler
- Supports text, image, file, voice, and video message send/receive operations
- Full CRUD on smart tables, sub-sheets, fields, records plus intelligent document creation and export
- Pre-flight checklist enforces version check, auth verification, and non-interactive init before any command runs
Wecom Unified by the numbers
- 727 all-time installs (skills.sh)
- +27 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #350 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wecomteam/wecom-unified --skill wecom-unifiedAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 727 |
|---|---|
| repo stars | ★ 37 |
| Last updated | July 2, 2026 |
| Repository | wecomteam/wecom-unified ↗ |
How do you automate WeCom messaging and documents from CLI?
Let their coding agent directly read, create, edit, and send messages across WeCom corporate accounts including contacts, documents, schedules, meetings, and tasks.
Who is it for?
Developers automating WeCom corporate workflows who need CLI access to contacts, messaging, documents, calendars, meetings, and tasks from an agent.
Skip if: Teams outside the WeCom ecosystem or projects using Slack, Teams, or Feishu without WeCom corporate account credentials.
When should I use this skill?
User mentions WeCom, 企业微信, doc.weixin.qq.com URLs, corporate messaging, schedules, meetings, todos, or smart spreadsheet operations.
What you get
WeCom messages sent, documents created or edited, schedules and meetings booked, and todo tasks created via wecom-cli commands.
- WeCom CLI command sequences
- Sent messages and managed corporate documents
By the numbers
- Covers 6 WeCom business domains
- Installs @wecom/cli@0.1.8 via npm global package
Files
企业微信套件 (WeCom Unified)
企业微信 CLI (wecom-cli) 全能套件,通过命令行工具与企业微信系统交互,覆盖 6 大业务域:通讯录、消息、文档(含文档/表格/智能表格/智能文档 4 种品类)、日程、会议、待办。
⚠️ 前置检查 — 使用任何命令前必须执行
Step 1: 检查 CLI 是否安装
wecom-cli --version如果命令不存在或报错,执行安装:
npm install -g @wecom/cli@0.1.8Step 2: 检查凭证是否配置
wecom-cli auth show --auth-status- 输出
authorized→ 已配置,可以继续使用 - 输出
unauthorized→ 未配置,需要执行 Step 3
Step 3: 配置凭证(仅未授权时执行)
wecom-cli init --noninteractive⚠️ 该命令会输出一个授权链接和二维码,并阻塞等待用户扫码完成验证。授权成功后命令会自动退出,仅需执行一次。
---
业务域概览
👤 通讯录 (contact)
获取可见范围成员列表、按姓名/别名搜索匹配、查询 userid。
→ 详见 references/wecom-contact.md
💬 消息 (msg)
会话列表查询、消息记录拉取(文本/图片/文件/语音/视频)、多媒体文件获取、文本消息发送。
→ 详见 references/wecom-msg.md
📄 文档、表格、智能表格 & 智能文档 (doc)
文档创建/读取/编辑(Markdown 格式),表格读取,智能表格子表管理、字段/列管理、记录增删改查,智能文档(智能主页)创建与内容导出。支持通过 docid 或 URL 定位文档,自动识别文档品类(文档/表格/智能表格/智能文档)并路由到正确接口。
→ 详见 references/wecom-doc.md
📅 日程 (schedule)
查询日程列表与详情、创建/修改/取消日程、添加/移除参与人、查询多成员闲忙状态并分析共同空闲时段。
→ 详见 references/wecom-schedule.md
🎥 会议 (meeting)
创建预约会议、查询会议列表与详情、取消会议、更新受邀成员。
→ 详见 references/wecom-meeting.md
✅ 待办 (todo)
查询待办列表与详情、创建/更新/删除待办、变更用户处理状态(接受/拒绝/完成)、分派任务。
→ 详见 references/wecom-todo.md
---
公共概念与规则
所有业务域共享的通用调用格式、返回格式、错误处理、通讯录查询方法和时间格式规范。
→ 详见 references/wecom-shared.md
---
快速示例
查询通讯录成员
wecom-cli contact get_userlist '{}'查看最近会话列表
wecom-cli msg get_msg_chat_list '{"begin_time": "2026-04-08 00:00:00", "end_time": "2026-04-15 23:59:59"}'发送文本消息
wecom-cli msg send_message '{"chat_type": 1, "chatid": "zhangsan", "msgtype": "text", "text": {"content": "hello"}}'创建文档
wecom-cli doc create_doc '{"doc_type": 3, "doc_name": "项目周报"}'读取文档内容(Markdown 格式)
wecom-cli doc get_doc_content '{"docid": "DOCID", "type": 2}'创建智能文档(智能主页)
⚠️ 特殊语法:此命令必须使用+smartpage_create(带+前缀),加号不可省略;该+仅适用于此命令,不要泛化到其他doc子命令。
wecom-cli doc +smartpage_create '{"title": "项目概览", "pages": [{"page_title": "需求文档", "content_type": 1, "page_filepath": "/path/to/requirements.md"}]}'导出智能文档内容
wecom-cli doc smartpage_export_task '{"docid": "DOCID", "content_type": 1}'查询今天的日程
wecom-cli schedule get_schedule_list_by_range '{"start_time": "2026-04-15 00:00:00", "end_time": "2026-04-15 23:59:59"}'创建预约会议
wecom-cli meeting create_meeting '{"title": "周例会", "meeting_start_datetime": "2026-04-16 15:00", "meeting_duration": 3600}'查看待办列表
wecom-cli todo get_todo_list '{}'创建待办
wecom-cli todo create_todo '{"content": "完成Q2规划文档", "remind_time": "2026-04-20 09:00:00"}'通讯录成员查询
公共概念与规则请参考 wecom-shared.md
获取当前用户可见范围内的通讯录成员,并在本地按姓名/别名进行筛选匹配。
操作
1. 获取全量通讯录成员
获取当前用户可见范围内的所有企业成员信息:
调用示例:
wecom-cli contact get_userlist '{}'返回格式:
{
"errcode": 0,
"errmsg": "ok",
"userlist": [
{
"userid": "zhangsan",
"name": "张三",
"alias": "Sam"
},
{
"userid": "lisi",
"name": "李四",
"alias": ""
}
]
}返回字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功 |
errmsg | string | 错误信息 |
userlist | array | 用户列表 |
userlist[].userid | string | 用户唯一 ID |
userlist[].name | string | 用户姓名 |
userlist[].alias | string | 用户别名,可能为空 |
---
2. 按姓名/别名搜索人员
get_userlist 返回全量成员后,在本地对结果进行筛选匹配:
- 精确匹配:
name或alias与关键词完全一致,直接使用 - 模糊匹配:
name或alias包含关键词,返回所有匹配结果 - 无结果:告知用户未找到对应人员
搜索示例:
用户问:"帮我找一下张三是谁?"
1. 调用 get_userlist 获取全量成员 2. 在 userlist 中筛选 name 或 alias 包含"张三"的成员 3. 返回匹配结果
---
注意事项
get_userlist返回的是当前用户可见范围内的成员,需经过可见性规则过滤,不一定是全公司所有人员;返回字段仅包含userid、name(姓名)和alias(别名)- ⚠️ 超过 10 人时接口将报错:若
userlist返回成员数量超过 10 人,视为异常,应立即停止处理并向用户说明:
当前通讯录可见成员数量超过了本功能支持的上限(10 人)。
本功能仅适用于可见范围较小的场景,无法在大范围通讯录中使用。
建议缩小可见范围后重试,或通过其他方式查询目标人员。
userid是用户的唯一标识,在需要传递用户 ID 给其他接口时使用此字段alias字段可能为空字符串,搜索时需做空值判断- 若搜索结果有多个同名人员,需将所有候选人展示给用户选择,不得自行决定
- 若
errcode不为0,说明接口调用失败,需告知用户错误信息(errmsg)
---
典型工作流
工作流 1:查询人员信息
用户问:"帮我查一下 Sam 是谁?"
1.
wecom-cli contact get_userlist '{}'获取全量成员列表
2. 在结果中筛选 alias 为 Sam 或 name 包含 Sam 的成员 3. 若找到唯一匹配,直接展示结果:
📇 找到成员:
- 姓名:张三
- 别名:Sam
- 用户ID:zhangsan4. 若找到多个匹配,展示候选列表请用户确认:
🔍 找到多个匹配成员,请确认您要查询的是哪位:
1. 张三(别名:Sam,ID:zhangsan)
2. 张三丰(别名:Sam2,ID:zhangsan2)
请问您要查询的是哪一位?---
工作流 2:为其他功能提供 userid 转换
用户问:"帮我发消息给张三"
1.
wecom-cli contact get_userlist '{}'获取全量成员
2. 筛选 name 为"张三"的成员,确认 userid 3. 将 userid 传递给消息发送接口
---
工作流 3:批量查询多个人员
用户问:"帮我查一下张三和李四分别是谁?"
1.
wecom-cli contact get_userlist '{}'获取全量成员列表
2. 分别筛选"张三"和"李四"的匹配结果 3. 汇总后一并展示
注意:只需调用一次 get_userlist,在本地对结果进行多次筛选,避免重复调用接口。---
快速参考
接口说明
| 接口 | 用途 | 输入 | 返回 |
|---|---|---|---|
get_userlist | 获取可见范围内全量通讯录成员 | 无 | 用户列表(userid、name、alias) |
本地筛选策略
| 场景 | 策略 |
|---|---|
| 精确匹配(name 或 alias 完全一致) | 直接使用,无需用户确认 |
| 模糊匹配(name 或 alias 包含关键词),唯一结果 | 直接使用,向用户展示结果 |
| 模糊匹配,多个结果 | 展示候选列表,请用户选择 |
| 无匹配结果 | 告知用户未找到对应人员 |
create_doc API
新建文档、表格或智能表格。创建成功后返回文档访问链接和 docid。
技能定义
{
"name": "create_doc",
"description": "新建文档、表格或智能表格。支持在指定空间和目录下创建,可设置文档管理员。创建成功后返回文档访问链接和 docid(docid 仅在创建时返回,需妥善保存)。注意:创建智能表格(doc_type=10)时,文档会默认包含一个子表,可通过 smartsheet_get_sheet 查询其 sheet_id,无需额外调用 smartsheet_add_sheet。",
"inputSchema": {
"properties": {
"doc_type": {
"description": "文档类型:3-文档,10-智能表格",
"enum": [3, 10],
"title": "Doc Type",
"type": "integer"
},
"doc_name": {
"description": "文档名字,最多 255 个字符,超过会被截断",
"title": "Doc Name",
"type": "string"
}
},
"required": ["doc_type", "doc_name"],
"title": "create_docArguments",
"type": "object"
}
}请求示例
{
"doc_type": 3,
"doc_name": "项目周报"
}响应示例
{
"errcode": 0,
"errmsg": "ok",
"url": "https://doc.weixin.qq.com/doc/xxx",
"docid": "DOCID"
}注意事项
doc_type=3创建普通文档doc_type=10创建智能表格,默认包含一个子表- docid 仅在创建时返回,后续无法再获取,务必保存
edit_doc_content API
编辑(覆写)文档内容。
技能定义
{
"name": "edit_doc_content",
"description": "编辑文档内容",
"inputSchema": {
"properties": {
"docid": {
"description": "文档 id,与 url 二选一传入",
"title": "Docid",
"type": "string"
},
"url": {
"description": "文档的访问链接,与 docid 二选一传入",
"title": "URL",
"type": "string"
},
"content": {
"description": "覆写的文档内容",
"title": "Content",
"type": "string"
},
"content_type": {
"description": "内容类型格式。1:markdown",
"enum": [1],
"title": "Content Type",
"type": "integer"
}
},
"oneOf": [
{ "required": ["docid", "content", "content_type"] },
{ "required": ["url", "content", "content_type"] }
],
"title": "edit_doc_contentArguments",
"type": "object"
}
}请求示例
{
"docid": "DOCID",
"content": "# 标题\n\n正文内容",
"content_type": 1
}响应示例
{
"errcode": 0,
"errmsg": "ok"
}注意事项
content_type当前仅支持1(Markdown 格式)- 此操作为覆写,会替换文档全部内容
- 建议先调用
get_doc_content了解当前内容再编辑
get_doc_content API
获取企业微信文档的完整内容数据,以 Markdown 格式返回。该接口采用异步轮询机制:首次调用无需传 task_id,接口会返回 task_id;若 task_done 为 false,需携带该 task_id 再次调用,直到 task_done 为 true 时返回完整内容。
技能定义
{
"name": "get_doc_content",
"description": "获取企业微信文档的完整内容数据,以 Markdown 格式返回。该接口采用异步轮询机制:首次调用无需传 task_id,接口会返回 task_id;若 task_done 为 false,需携带该 task_id 再次调用,直到 task_done 为 true 时返回完整内容。",
"inputSchema": {
"properties": {
"docid": {
"description": "文档的 docid,与 url 二选一传入",
"title": "Doc ID",
"type": "string"
},
"url": {
"description": "文档的访问链接,与 docid 二选一传入",
"title": "URL",
"type": "string"
},
"type": {
"description": "内容返回格式。2: Markdown 格式",
"enum": [2],
"title": "Type",
"type": "integer"
},
"task_id": {
"description": "任务 ID,用于异步轮询。初次调用时不填,后续轮询时填写上次返回的 task_id",
"title": "Task ID",
"type": "string"
}
},
"oneOf": [
{ "required": ["docid", "type"] },
{ "required": ["url", "type"] }
],
"title": "get_doc_contentArguments",
"type": "object"
}
}参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| docid | string | 与 url 二选一 | 文档的 docid |
| url | string | 与 docid 二选一 | 文档的访问链接 |
| type | integer | 是 | 内容返回格式,固定传 2(Markdown 格式) |
| task_id | string | 否 | 任务 ID,初次调用不填,后续轮询时填写上次返回的 task_id |
异步轮询机制
1. 首次调用:传入 docid/url 和 type: 2,不传 task_id 2. 检查响应:若 task_done 为 false,记录返回的 task_id 3. 轮询调用:携带 task_id 再次调用,直到 task_done 为 true 4. 获取内容:当 task_done 为 true 时,content 字段包含完整的 Markdown 内容
请求示例
// 首次调用
{
"docid": "DOCID",
"type": 2
}
// 轮询调用
{
"docid": "DOCID",
"type": 2,
"task_id": "xxx"
}响应示例
{
"errcode": 0,
"errmsg": "ok",
"content": "# 文档标题\n\n文档正文内容...",
"task_id": "xxxxx",
"task_done": true
}smartpage_create API
创建智能文档(原智能主页)。支持传入多个子页面,每个子页面可指定标题、内容类型和本地文件路径。创建成功后返回文档访问链接和 docid。
技能定义
{
"name": "smartpage_create",
"description": "创建智能文档(原智能主页)。支持传入标题和多个子页面配置,每个子页面可指定标题、内容类型(Text/Markdown)和本地文件路径。创建成功后返回 docid 和 url(docid 仅在创建时返回,需妥善保存)。",
"inputSchema": {
"properties": {
"title": {
"description": "智能文档标题",
"title": "Title",
"type": "string"
},
"pages": {
"description": "子页面列表",
"title": "Pages",
"type": "array",
"items": {
"type": "object",
"properties": {
"page_title": {
"description": "子页面标题",
"title": "Page Title",
"type": "string"
},
"content_type": {
"description": "内容类型。1: Markdown(包含Markdown语法的内容),0: Text(纯文本,不含任何Markdown语法)",
"enum": [0, 1],
"default": 1,
"title": "Content Type",
"type": "integer"
},
"page_filepath": {
"description": "子页面内容对应的本地文件路径",
"title": "Page Filepath",
"type": "string"
}
}
}
}
},
"required": ["pages"],
"title": "smartpage_createArguments",
"type": "object"
}
}参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 否 | 智能文档标题 |
| pages | array | 是 | 子页面列表 |
| pages[].page_title | string | 否 | 子页面标题 |
| pages[].content_type | integer | 否 | 内容类型:1-Markdown,0-Text(纯文本)。默认应传 1,仅纯文本内容才传 0 |
| pages[].page_filepath | string | 否 | 子页面内容对应的本地文件路径,需确保文件存在且可读 |
ContentType 枚举
| 值 | 含义 | 适用场景 |
|---|---|---|
| 1 | Markdown | 文件内容包含 Markdown 语法(标题、列表、链接、代码块等) |
| 0 | Text(纯文本) | 文件内容为纯文本,不含任何 Markdown 语法 |
除了标准的 markdown 格式以外,智能文档还支持扩展语法以提升表示的丰富性,包括: 1. 背景块
<card color="green">
## 在扩展标签里面可以任意嵌套 markdown 语法
- 背景块常用于展示重要信息
- 颜色的使用根据需要表达的语义进行选择,卡片背景由 `color` 指定;支持 `green`, `blue`, `red`, `yellow`, `gray`, `purple`, `orange`, `cyan`, `indigo`,也支持 `dark_green`, `dark_blue`, `dark_red`, `dark_yellow`, `dark_gray`, `dark_purple`, `dark_orange`, `dark_cyan`, `dark_indigo` 等深色系。
</card>背景颜色推荐使用浅色背景,以完成区隔/高亮并且保持低饱和度确保正文内容的良好显示。 2. 分栏 使用分栏可以并列显示内容,常用于展示对比或者并列信息
<grid>
<area width-ratio="0.5">占据50%的空间</area>
<area width-ratio="0.5">占据50%的空间</area>
</grid>width-ratio:子容器宽度占比,范围 0.1~1.0,所有的子容器宽度占比之和为 1
请求示例
{
"title": "项目概览",
"pages": [
{
"page_title": "需求文档",
"content_type": 1,
"page_filepath": "/path/to/requirements.md"
},
{
"page_title": "设计说明",
"content_type": 1,
"page_filepath": "/path/to/design.md"
}
]
}响应示例
{
"errcode": 0,
"errmsg": "ok",
"docid": "DOCID",
"url": "https://doc.weixin.qq.com/smartpage/a1_xxxxxx"
}注意事项
docid仅在创建时返回,后续无法再获取,务必保存page_filepath指向本地文件,需确保文件存在且可读- `content_type` 必须与文件实际内容格式匹配:
.md文件或包含 Markdown 语法的内容必须传1,不要传0 - 每个子页面的 Markdown 文件大小不得超过 10MB,超过会导致创建失败;如果文件过大,需先拆分为多个子页面
smartpage_export_task / smartpage_get_export_result API
导出智能文档(原智能主页)内容。采用异步两步操作:先通过 smartpage_export_task 提交导出任务获取 task_id,再通过 smartpage_get_export_result 轮询任务状态,直到任务完成后返回完整文档内容。
---
第一步:smartpage_export_task — 提交导出任务
发起智能文档内容导出任务(异步)。传入 docid 或 url 和 content_type,返回 task_id。
技能定义
{
"name": "smartpage_export_task",
"description": "发起智能文档(原智能主页)内容导出任务(异步)。传入 docid(或 url)和 content_type,返回 task_id。需配合 smartpage_get_export_result 轮询查询导出进度,直到任务完成后获取文档内容。",
"inputSchema": {
"properties": {
"docid": {
"description": "智能文档的 docid,与 url 二选一传入",
"title": "Doc ID",
"type": "string"
},
"url": {
"description": "智能文档的访问链接,与 docid 二选一传入",
"title": "URL",
"type": "string"
},
"content_type": {
"description": "导出内容格式。目前仅支持 1(Markdown 格式)",
"enum": [1],
"title": "Content Type",
"type": "integer"
}
},
"oneOf": [
{ "required": ["docid", "content_type"] },
{ "required": ["url", "content_type"] }
],
"title": "smartpage_export_taskArguments",
"type": "object"
}
}参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| docid | string | 与 url 二选一 | 智能文档的 docid |
| url | string | 与 docid 二选一 | 智能文档的访问链接 |
| content_type | integer | 是 | 导出内容格式,目前仅支持 1(Markdown 格式) |
请求示例
// 通过 docid
{
"docid": "DOCID",
"content_type": 1
}
// 通过 url
{
"url": "https://doc.weixin.qq.com/smartpage/a1_xxxxxx",
"content_type": 1
}响应示例
{
"errcode": 0,
"errmsg": "ok",
"task_id": "TASK_ID"
}---
第二步:smartpage_get_export_result — 查询导出结果
查询智能文档导出任务进度。传入 task_id 进行轮询,当 task_done 为 true 时返回完整文档内容。
技能定义
{
"name": "smartpage_get_export_result",
"description": "查询智能文档(原智能主页)导出任务进度。传入 task_id 轮询,当 task_done 为 true 时返回 content 字段,包含导出的完整文档内容。",
"inputSchema": {
"properties": {
"task_id": {
"description": "导出任务 ID,由 smartpage_export_task 返回",
"title": "Task ID",
"type": "string"
}
},
"required": ["task_id"],
"title": "smartpage_get_export_resultArguments",
"type": "object"
}
}参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| task_id | string | 是 | 导出任务 ID,由 smartpage_export_task 返回 |
请求示例
{
"task_id": "TASK_ID"
}响应示例
任务未完成:
{
"errcode": 0,
"errmsg": "ok",
"task_done": false
}任务完成:
{
"errcode": 0,
"errmsg": "ok",
"task_done": true,
"content": "# 项目周报\n\n## 本周进展\n\n1. 完成了用户模块开发\n2. 修复了3个线上Bug"
}---
异步轮询机制
1. 调用 smartpage_export_task:传入 docid(或 url)和 content_type: 1,获取 task_id 2. 首次轮询:传入 task_id 调用 smartpage_get_export_result 3. 检查响应:若 task_done 为 false,继续轮询 4. 获取内容:当 task_done 为 true 时,content 字段包含完整的 Markdown 内容
注意事项
smartpage_export_task是异步操作的第一步,调用后仅返回task_idcontent_type目前仅支持1(Markdown 格式)docid和url二选一传入即可,无需同时传入- 任务完成后
content字段直接包含完整文档内容,无需额外读取文件 - 如果轮询多次仍未完成,建议适当增加轮询间隔
单元格值格式参考
smartsheet_add_records 仅支持字段标题作为key。 smartsheet_update_records 支持通过 key_type 参数指定使用字段标题(CELL_VALUE_KEY_TYPE_FIELD_TITLE)或字段 ID(CELL_VALUE_KEY_TYPE_FIELD_ID)。
各字段类型的值格式
1. 文本 (FIELD_TYPE_TEXT)
必须使用数组格式,外层方括号不可省略:
"字段标题": [{"type": "text", "text": "内容"}]2. 数字 (NUMBER) / 货币 (CURRENCY) / 百分比 (PERCENTAGE) / 进度 (PROGRESS)
直接传数字:
"金额": 100,
"完成率": 0.6,
"进度": 803. 复选框 (CHECKBOX)
直接传布尔值:
"已完成": true4. 单选 (SINGLE_SELECT) / 多选 (SELECT)
必须使用数组格式,不能直接传字符串:
"优先级": [{"text": "高"}],
"标签": [{"text": "紧急", "style": 17}, {"text": "重要", "style": 12}]已存在的选项应通过 id 匹配(id 可从 smartsheet_get_fields 返回中获取),新增选项时不填 id。可附带 style(颜色 1-27),对照表如下:
| style | 颜色 |
|---|---|
| 1 | 浅红1 |
| 2 | 浅橙1 |
| 3 | 浅天蓝1 |
| 4 | 浅绿1 |
| 5 | 浅紫1 |
| 6 | 浅粉红1 |
| 7 | 浅灰1 |
| 8 | 白 |
| 9 | 灰 |
| 10 | 浅蓝1 |
| 11 | 浅蓝2 |
| 12 | 蓝 |
| 13 | 浅天蓝2 |
| 14 | 天蓝 |
| 15 | 浅绿2 |
| 16 | 绿 |
| 17 | 浅红2 |
| 18 | 红 |
| 19 | 浅橙2 |
| 20 | 橙 |
| 21 | 浅黄1 |
| 22 | 浅黄2 |
| 23 | 黄 |
| 24 | 浅紫2 |
| 25 | 紫 |
| 26 | 浅粉红2 |
| 27 | 粉红 |
5. 日期时间 (DATE_TIME)
传日期时间字符串,系统自动按东八区转换:
"截止日期": "2026-01-15 14:30:00",
"创建日期": "2026-01-15"支持格式:YYYY-MM-DD HH:mm:ss、YYYY-MM-DD HH:mm、YYYY-MM-DD
6. 手机号 (PHONE_NUMBER) / 邮箱 (EMAIL) / 条码 (BARCODE)
直接传字符串:
"电话": "13800138000",
"邮箱": "test@example.com"7. 成员 (USER)
数组格式,需传 user_id。user_id 不是姓名,必须先通过 wecom-contact 查找目标人员的 userid,再填入此处。
具体步骤:先
wecom-cli contact get_userlist '{}'获取通讯录成员列表,在返回结果中按姓名/别名筛选出目标人员,取其 userid 值填入。
"负责人": [{"user_id": "zhangsan"}]多个成员:
"负责人": [{"user_id": "zhangsan"}, {"user_id": "lisi"}]8. 超链接 (URL)
数组格式,目前仅支持一个链接:
"参考链接": [{"type": "url", "text": "官网", "link": "https://example.com"}]9. 图片 (IMAGE)
数组格式,支持传入本地路径:
"封面": [{"image_path": "/path/to/img.png"}]10. 地理位置 (LOCATION)
数组格式:
"地点": [{"source_type": 1, "id": "地点ID", "latitude": "39.9", "longitude": "116.3", "title": "北京"}]11. 文件
数组格式:
"文件": [{"file_path": "/path/to/img.png"}]完整添加记录示例
{
"docid": "DOCID",
"sheet_id": "SHEETID",
"records": [{
"values": {
"任务名称": [{"type": "text", "text": "完成需求文档"}],
"优先级": [{"text": "高"}],
"截止日期": "2026-03-20",
"完成进度": 30,
"已完成": false
}
}]
}智能表格字段类型参考
支持的字段类型
| 类型枚举值 | 说明 | 适用场景 |
|---|---|---|
FIELD_TYPE_TEXT | 文本 | 名称、标题、描述、负责人姓名等自由文本 |
FIELD_TYPE_NUMBER | 数字 | 金额、工时、数量等数值 |
FIELD_TYPE_CHECKBOX | 复选框 | 是否完成等布尔值 |
FIELD_TYPE_DATE_TIME | 日期时间 | 截止日期、创建时间等 |
FIELD_TYPE_IMAGE | 图片 | 附件图片 |
FIELD_TYPE_USER | 用户/成员 | 需传入 user_id;仅在明确知道成员 ID 时使用,若只有姓名应用 TEXT |
FIELD_TYPE_URL | 链接 | 超链接 |
FIELD_TYPE_SELECT | 多选 | 标签、分类等可多选的选项 |
FIELD_TYPE_PROGRESS | 进度 | 完成进度(0-100 整数) |
FIELD_TYPE_PHONE_NUMBER | 手机号 | 联系电话 |
FIELD_TYPE_EMAIL | 邮箱 | 电子邮件 |
FIELD_TYPE_SINGLE_SELECT | 单选 | 状态、优先级、严重程度等有固定选项的字段 |
FIELD_TYPE_LOCATION | 位置 | 地理位置 |
FIELD_TYPE_CURRENCY | 货币 | 货币金额 |
FIELD_TYPE_PERCENTAGE | 百分比 | 比率类数值(完成率、转化率) |
FIELD_TYPE_BARCODE | 条码 | 条形码/二维码 |
FIELD_TYPE_ATTACHMENT | 文件 | 文件/附件 |
添加字段示例
{
"docid": "DOCID",
"sheet_id": "SHEETID",
"fields": [
{ "field_title": "任务名称", "field_type": "FIELD_TYPE_TEXT" },
{ "field_title": "优先级", "field_type": "FIELD_TYPE_SINGLE_SELECT" },
{ "field_title": "截止日期", "field_type": "FIELD_TYPE_DATE_TIME" },
{ "field_title": "完成进度", "field_type": "FIELD_TYPE_PROGRESS" }
]
}更新字段注意事项
smartsheet_update_fields只能更新字段标题,不能更改字段类型field_type必须传字段当前的原始类型field_title不能更新为原值(即不能传与当前相同的标题)
smartsheet_get_records API
查询智能表格中指定子表的记录信息,支持分页读取。支持通过 docid 或文档 URL 定位文档,二者传入其一即可。
技能定义
{
"name": "smartsheet_get_records",
"description": "查询智能表格中指定子表的记录信息。支持分页查询(cursor + limit),不填 cursor 从第一行开始。支持通过 docid 或文档 URL 定位文档,二者传入其一即可。",
"inputSchema": {
"properties": {
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "查询游标,不填代表从第一行记录开始查询",
"title": "Cursor"
},
"docid": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "文档的 docid,与 url 二选一传入",
"title": "Docid"
},
"limit": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "分页大小,每页返回多少条数据;当不填写该参数或将该参数设置为 0 时,如果总数大于 1000,一次性返回 1000 行记录,当总数小于 1000 时,返回全部记录;limit 最大值为 1000",
"title": "Limit"
},
"sheet_id": {
"description": "子表的 sheet_id,用于指定要查询的智能表格中的哪个子表",
"title": "Sheet Id",
"type": "string"
},
"url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "文档的访问链接,与 docid 二选一传入",
"title": "Url"
}
},
"required": [
"sheet_id"
],
"title": "smartsheet_get_recordsArguments",
"type": "object"
}
}参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cursor | string | 否 | 查询游标,不填代表从第一行记录开始查询 |
| docid | string | 与 url 二选一 | 文档的 docid |
| limit | integer | 否 | 分页大小,每页返回多少条数据;当不填写该参数或将该参数设置为 0 时,如果总数大于 1000,一次性返回 1000 行记录,当总数小于 1000 时,返回全部记录;limit 最大值为 1000 |
| sheet_id | string | 是 | 子表的 sheet_id,用于指定要查询的智能表格中的哪个子表 |
| url | string | 与 docid 二选一 | 文档的访问链接 |
请求示例
以传入docid为例:
{
"docid": "DOCID",
"sheet_id": "123Abc"
}以传url为例:
{
"url": "https://doc.weixin.qq.com/smartsheet/xxx",
"sheet_id": "123Abc"
}响应示例(含分页)
{
"errcode": 0,
"errmsg": "ok",
"total": 100,
"has_more": true,
"next_cursor": "mock_cursor_token",
"records": [
{
"record_id": "rec_001",
"create_time": "1700000000000",
"update_time": "1700000000000",
"values": {
"成员": [
{"user_id": "real.user001", "id_type": 1}
],
"序号": [
{"text": "1", "type": "text"}
],
"附件": [
{
"doc_type": 2,
"file_ext": "xlsx",
"file_type": "Wedrive",
"file_url": "https://drive.weixin.qq.com/s?k=MOCK_TOKEN",
"name": "report.xlsx",
"size": 12345
}
]
},
"creator_name": "张三",
"updater_name": "张三"
},
{
"record_id": "rec_002",
"create_time": "1700000000000",
"update_time": "1700000000000",
"values": {
"截图": [
{
"height": 1080,
"id": "img_mock_id",
"image_url": "https://wdcdn.qpic.cn/mocked_path?w=1920&h=1080",
"title": "screenshot_001",
"width": 1920
}
],
"序号": [
{"text": "2", "type": "text"}
]
},
"creator_name": "张三",
"updater_name": "李四"
}
]
}响应数据结构
total: 总记录数(integer)has_more: 是否还有更多数据(boolean)next_cursor: 下一页游标,用于分页(string,仅当 has_more 为 true 时存在)records: 记录数组
分页查询
# 第一页
wecom-cli doc smartsheet_get_records '{"docid": "DOCID", "sheet_id": "SHEETID"}'
# 下一页(使用上一条的 next_cursor)
wecom-cli doc smartsheet_get_records '{"docid": "DOCID", "sheet_id": "SHEETID", "cursor": "上一条的 next_cursor 值"}'真实场景示例
场景 1:记录一个 Bug(文本 + 单选 + 图片)
用户说:"帮我记一下这个 bug,登录页在 Safari 下白屏,模块是前端,严重程度严重。"
{
"add_records": [
{
"values": {
"fABCD1": "登录页在 Safari 浏览器下加载后白屏,其他浏览器正常。复现步骤:Safari 14+ 访问 /login → 页面空白,控制台报 CSS 解析错误。",
"fABCD2": [{"text": "前端"}],
"fABCD3": [{"text": "严重"}],
"fABCD4": [{"user_id": "wangwu"}],
"fABCD5": [{"title": "safari-bug-screenshot.png", "image_base64": "iVBORw0KGgoAAAANSUhEUg...(纯base64)"}]
}
}
]
}场景 2:记录一条任务(文本 + 日期 + 成员 + 单选 + 空图片)
用户说:"加一条任务,完成支付模块单元测试,3月20日前,负责人 lisi,状态未开始,暂无附件。"
{
"add_records": [
{
"values": {
"fTITLE": "完成支付模块单元测试,覆盖率达到 80%",
"fDUEDATE": "1742400000000",
"fOWNER": [{"user_id": "lisi"}],
"fSTATUS": [{"text": "未开始"}],
"fATTACH": []
}
}
]
}关于负责人(成员字段):
- 有 userid 时用 [{"user_id": "账号名"}],userid 通常就是企业微信登录账号- 没有 userid 只知道姓名时用 ["张三"],但匹配不上时不会写入- 暂不指定负责人时传 [] 空数组>
关于图片/附件字段:
- 暂无图片时传 [] 空数组即可,不会报错- 有图片时传[{"title": "filename.png", "image_base64": "纯base64字符串"}],注意不带data:image/...;base64,前缀
场景 3:批量添加多条客户记录
用户说:"帮我把这三条线索录进去:张伟/科技公司/跟进中,陈静/贸易公司/初步接触,刘洋/制造业/已成交。"
{
"add_records": [
{
"values": {
"fCUST_NAME": "张伟",
"fCOMPANY": "北京某科技有限公司",
"fSTAGE": [{"text": "跟进中"}],
"fSOURCE": [{"text": "展会"}]
}
},
{
"values": {
"fCUST_NAME": "陈静",
"fCOMPANY": "上海某贸易有限公司",
"fSTAGE": [{"text": "初步接触"}],
"fSOURCE": [{"text": "冷呼"}]
}
},
{
"values": {
"fCUST_NAME": "刘洋",
"fCOMPANY": "广州某制造有限公司",
"fSTAGE": [{"text": "已成交"}],
"fSOURCE": [{"text": "老客户转介绍"}]
}
}
]
}场景 4:更新一条已有记录
用户说:"把 record_id 是 REC_20250301 的那条任务状态改成已完成,进度 100%。"
{
"update_records": [
{
"record_id": "REC_20250301",
"values": {
"fSTATUS": [{"text": "已完成"}],
"fPROGRESS": 100
}
}
]
}场景 5:批量更新多条记录
用户说:"把这几条审批记录都标为已通过:REC_001、REC_002、REC_003。"
{
"update_records": [
{"record_id": "REC_001", "values": {"fSTATUS": [{"text": "已通过"}], "fAPPROVER": [{"user_id": "manager_a"}]}},
{"record_id": "REC_002", "values": {"fSTATUS": [{"text": "已通过"}], "fAPPROVER": [{"user_id": "manager_a"}]}},
{"record_id": "REC_003", "values": {"fSTATUS": [{"text": "已通过"}], "fAPPROVER": [{"user_id": "manager_a"}]}}
]
}场景 6:记录一条销售订单(多字段混合类型)
用户说:"新增一条订单,客户是北京某科技,产品是企业版,金额 58000,签约日期今天,负责人赵六,合同链接发给你了。"
{
"add_records": [
{
"values": {
"fCUSTOMER": "北京某科技有限公司",
"fPRODUCT": [{"text": "企业版"}],
"fAMOUNT": 58000,
"fSIGN_DATE": "1741622400000",
"fSALES": [{"user_id": "zhaoliu"}],
"fCONTRACT": [{"text": "合同文件", "link": "https://doc.example.com/contract/2025-001"}]
}
}
]
}场景 7:记录一次会议纪要
用户说:"帮我记一下今天下午的需求评审会,参会人产品+开发+测试,决议是优先做支付模块。"
{
"add_records": [
{
"values": {
"fMEETING_TITLE": "支付模块需求评审会",
"fDATE": "1741622400000",
"fPARTICIPANTS": "产品、开发、测试",
"fSUMMARY": "确定优先开发支付模块,目标 3 月底完成联调,4 月初上线。遗留问题:退款流程待产品补充文档。",
"fDOC_LINK": [{"text": "评审文档", "link": "https://doc.example.com/meeting/20250310"}]
}
}
]
}场景 8:同一请求中同时添加和更新
用户说:"新增一条'用户反馈收集'的任务,同时把'旧官网下线'那条(REC_OLD_001)标为已完成。"
{
"add_records": [
{
"values": {
"fTITLE": "用户反馈收集与分析",
"fSTATUS": [{"text": "未开始"}],
"fPRIORITY": [{"text": "高"}]
}
}
],
"update_records": [
{
"record_id": "REC_OLD_001",
"values": {
"fSTATUS": [{"text": "已完成"}],
"fPROGRESS": 100
}
}
]
}智能表格 Webhook 兜底写入
本文档是smartsheet_add_records/smartsheet_update_records的 fallback 参考。
当 CLI 调用因企业规模限制(可见范围 > 10 人)报错、无法写入智能表格时,切换到本方案,通过企业微信智能表格的 Webhook 接口直接写入数据。
>
⚠️ 格式隔离:以下字段值格式仅适用于 Webhook 接口,与 CLI 侧smartsheet_add_records/smartsheet_update_records的参数结构不同(例如文本、URL、图片、日期的写法均有差异),请勿与 wecom-doc-smartsheet-cell-value-formats.md 的格式混用。
---
一、Fallback 触发流程
何时切换到 Webhook
先走 CLI 正常链路(smartsheet_add_records / smartsheet_update_records)。仅在出现以下情况时才切换到 Webhook:
- 优先判据:CLI 返回
errcode: 851003,或errmsg包含no authority—— 这通常意味着企业可见范围 > 10 人,CLI 写入接口被限制 - 或
errmsg/ 提示信息明显指向企业规模 / 可见范围超限(例如"超出可见范围"、"成员数超限"等相关描述) - 其他错误(参数错误、字段 ID 错误、文档不存在等)不应切换到 Webhook,应按原错误排查
切换时向用户索取的两样东西
切换触发后,每次对话内临时获取,用完即弃,不保存到本地任何位置:
1. Webhook 完整 URL
- 在智能表格右上角菜单 → 「接收外部数据」→ 选择目标工作表 → 开启 → 复制
- 格式形如
https://qyapi.weixin.qq.com/cgi-bin/wedoc/smartsheet/webhook?key=XXXXXX - 该 URL 相当于该表的写入密钥,用户随时可以在智能表格里关闭「接收外部数据」使其失效
2. schema 示例 JSON
- 同一「接收外部数据」页面即可复制
- 包含字段 ID → 字段名的映射(
schema)和各字段的写入格式示例(add_records)
示例:
{
"schema": {
"fABCD1": "任务名称",
"fABCD2": "状态",
"fABCD3": "负责人",
"fABCD4": "截止日期"
},
"add_records": [
{
"values": {
"fABCD1": "示例任务",
"fABCD2": [{"text": "未开始"}],
"fABCD3": [{"user_id": ""}],
"fABCD4": "1742400000000"
}
}
]
}向用户告知的话术参考
- "CLI 写入接口返回了
851003 no authority(通常是企业可见范围 > 10 人的限制)。请把目标表的 Webhook 地址和「接收外部数据」页面的示例 JSON 发我,我帮你通过 Webhook 写入。该信息仅本轮使用,不会保存到本地。"
---
二、构建请求
字段匹配
用户描述通常是自然语言("标题""状态""处理人"),需从用户提供的 schema 中找对应字段 ID:
- 模糊匹配:
标题→ 标题 / 名称 / 主题;状态→ 状态 / 阶段;处理人→ 负责人 / 责任人 - 不确定时先问用户确认,避免写错字段
各字段类型的值写法见下方 字段类型格式规范;真实场景示例见 wecom-doc-smartsheet-webhook-examples.md。
日期处理
用户说"今天""明天""3 月 15 日""2025-03-01 09:00"等自然语言日期时,在 payload 构造阶段根据当前日期推算为毫秒时间戳字符串(如 "1742400000000")。Webhook 侧不接受可读日期字符串。
请求结构
Webhook 是标准 HTTP 接口,不经过 wecom-cli,请按执行环境选择合适的工具发送(curl、node 内置 fetch、python 的 requests / urllib 等均可,优先用当前环境最便捷的方式):
| 项 | 值 |
|---|---|
| Method | POST |
| URL | 用户提供的 Webhook 完整 URL(含 ?key=XXX) |
| Header | Content-Type: application/json |
| Body | JSON 对象,包含 add_records 和/或 update_records 字段 |
Body 结构
- 仅新增:
{
"add_records": [
{ "values": { "fABCD1": "...", "fABCD2": [{"text": "..."}] } }
]
}- 仅更新(需提供
record_id,且只能更新通过 Webhook 写入的记录,人工创建的记录无法更新):
{
"update_records": [
{ "record_id": "REC_xxx", "values": { "fABCD2": [{"text": "已完成"}] } }
]
}- 同一请求同时新增和更新:
{
"add_records": [ { "values": { ... } } ],
"update_records": [ { "record_id": "REC_xxx", "values": { ... } } ]
}成功后
简洁告知结果,例如:
"已通过 Webhook 写入,record_id: REC_xxx"返回非 0 errcode 时参考下方 常见错误码。
---
三、字段类型格式规范
各类型写法
| 字段类型 | value 示例 | 说明 |
|---|---|---|
| 文本 | "产品登录页白屏" 或 [{"type":"text","text":"产品登录页白屏"}] | 简单字符串更简洁 |
| 数字 / 货币 | 58000 | double,不要加引号 |
| 进度 / 百分数 | 30 | 传整数值,30 = 30%;不要传小数 0.3(那样会显示 0.3%) |
| 复选框 | true / false | bool |
| 日期 | "1740806400000" | 毫秒时间戳,字符串形式 |
| 成员 | [{"user_id":"lisi"}] 或 ["张三"] 或 [] | userid 通常就是企业微信登录账号;不指定时传 [] |
| 单选 | [{"text":"已完成"}] | 数组,选项文本必须与表格预设完全一致 |
| 多选 | [{"text":"前端"},{"text":"后端"}] | 数组,每个选项一个对象 |
| 链接 | [{"text":"需求文档","link":"https://doc.example.com"}] | 数组 |
| 地理位置 | [{"latitude":"31.23040","longitude":"121.47370","source_type":1,"title":"上海市徐汇区"}] | 数组,最多 1 条 |
| 图片 | [{"title":"screenshot.png","image_base64":"iVBORw0KGgo..."}] | 纯 base64,不要带 `data:image/...;base64,` 前缀,否则报 errcode 2023033 |
| 电话 / 邮箱 / 条码 | "13800138000" | 字符串 |
---
四、不支持的字段
以下字段由系统自动维护或结构特殊,Webhook 写入时跳过即可,不要报错:
公式、自动编号、查找引用、关联字段、创建人、最后编辑人、创建时间、最后编辑时间、群聊、文件附件。
---
五、频率限制
- 单工作表:≤ 3000 条/分钟
- 单文档:≤ 10000 条/分钟
数据量大时建议分批,每批不超过 500 条。
---
六、常见错误码
| errcode | 原因 | 解决方法 |
|---|---|---|
| 2023033 | 图片 base64 携带了 data:image/...;base64, 前缀 | 去掉前缀,只传纯 base64 字符串 |
| 40014 | Webhook key 无效或已过期 | 请用户重新在智能表格「接收外部数据」获取 Webhook 地址 |
| 45033 | 超出频率限制 | 降低发送速率或分批发送 |
| -100035 | testapi 域名不稳定(超时) | 改用正式域名 qyapi.weixin.qq.com |
| 2023001 | 字段 ID 不存在 | 核对用户提供的 schema,确认字段 ID 拼写正确 |
| 2023010 | 单选/多选的选项值不在预设列表 | 确认选项文本与表格设置完全一致(区分大小写) |
| 2023012 | record_id 不存在(更新时) | 只能更新通过 Webhook 写入的记录,人工创建的记录无法更新 |
---
七、参考文件
- 真实场景示例 → wecom-doc-smartsheet-webhook-examples.md
按需查阅,不用每次全读。
企业微信文档、表格、智能表格与智能文档管理
公共概念与规则请参考 wecom-shared.md
管理企业微信文档和智能文档(原名智能主页)的创建、读取和编辑,表格(在线表格)的读取以及智能表格的结构(子表、字段/列)和数据(记录)管理。文档接口支持通过 docid 或 url 二选一定位文档。
⚠️ 重要触发规则:只有当用户明确提到「智能文档」或「智能主页」时,才使用智能文档相关接口(smartpage_*系列)。其他所有涉及「文档」的场景(如"创建文档"、"写个文档"、"帮我建个文档"等),一律使用企微文档接口(create_doc/get_doc_content/edit_doc_content)。
调用方式
通过 wecom-cli 调用,品类为 doc:
wecom-cli doc <tool_name> '<json_params>'---
URL 品类识别与接口路由
企业微信文档有四种品类,URL 格式不同,读取内容所用的接口也不同,切勿混用。其中表格(在线表格)与智能表格是两类不同品类,请通过 URL 严格区分:
| URL 模式 | 品类 | 读取内容接口 |
|---|---|---|
https://doc.weixin.qq.com/doc/* | 文档(doc_type=3) | get_doc_content |
https://doc.weixin.qq.com/sheet/* | 表格 / 在线表格 | get_doc_content |
https://doc.weixin.qq.com/smartsheet/* | 智能表格(doc_type=10) | smartsheet_get_sheet → smartsheet_get_records |
https://doc.weixin.qq.com/smartpage/* | 智能文档(原名智能主页) | smartpage_export_task → smartpage_get_export_result |
判断规则:
- URL 路径以
/doc/*开头 → 文档 → 用get_doc_content - URL 路径以
/sheet/*开头 → 表格(在线表格) → 用get_doc_content - URL 路径以
/smartsheet/*开头 → 智能表格 → 用smartsheet_get_sheet - URL 路径以
/smartpage/*开头 → 智能文档(原名智能主页) → 用smartpage_export_task
⚠️ 表格 ≠ 智能表格:二者是不同品类(/sheet/vs/smartsheet/)。
返回格式说明
所有接口返回 JSON 对象,包含以下公共字段:
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功,非 0 表示失败 |
errmsg | string | 错误信息,成功时为 "ok" |
当 errcode 不为 0 时,说明接口调用失败,可重试 1 次;若仍失败,将 errcode 和 errmsg 展示给用户。
特殊错误码
| errcode | errmsg | 含义 | 处理方式 |
|---|---|---|---|
851002 | incompatible doc type | 文档品类与所调用的接口不匹配 | 根据文档 URL 重新确认品类(参见上方「URL 品类识别与接口路由」表),然后使用该品类对应的正确接口重试 |
851003 | no authority | 无权限调用该接口,智能表格写入场景下通常是企业可见范围 > 10 人的规模限制 | 若发生在 smartsheet_add_records / smartsheet_update_records,引导用户走 Webhook 兜底方案,详见 wecom-doc-smartsheet-webhook.md;其他接口则按权限问题排查 |
---
一、文档管理
get_doc_content
获取文档 / 表格(在线表格) / 智能表格的完整内容数据,统一以 Markdown 格式返回。采用异步轮询机制:首次调用无需传 task_id,接口返回 task_id;若 task_done 为 false,需携带该 task_id 再次调用,直到 task_done 为 true 时返回完整内容。
适用 URL:/doc/*、/sheet/*、/smartsheet/*。/smartpage/*(智能文档)不适用,请改用smartpage_export_task。
- 首次调用(不传 task_id):
wecom-cli doc get_doc_content '{"docid": "DOCID", "type": 2}'- 轮询(携带上次返回的 task_id):
wecom-cli doc get_doc_content '{"docid": "DOCID", "type": 2, "task_id": "xxx"}'- 通过 URL 读取文档:
wecom-cli doc get_doc_content '{"url": "https://doc.weixin.qq.com/doc/xxx", "type": 2}'- 通过 URL 读取表格(在线表格):
wecom-cli doc get_doc_content '{"url": "https://doc.weixin.qq.com/sheet/xxx", "type": 2}'参见 API 详情
create_doc
新建文档(doc_type=3)或智能表格(doc_type=10)。创建成功返回 url 和 docid。
- 创建文档:
wecom-cli doc create_doc '{"doc_type": 3, "doc_name": "项目周报"}'- 创建智能表格:
wecom-cli doc create_doc '{"doc_type": 10, "doc_name": "任务跟踪表"}'注意:
- docid 仅在创建时返回,需妥善保存。创建智能表格时默认包含一个子表,可通过
smartsheet_get_sheet查询其 sheet_id。 - 普通表格(在线表格,URL 含
/sheet/)本 skill 仅支持读取(通过get_doc_content),不支持创建
参见 API 详情。
edit_doc_content
用 Markdown 内容覆写文档正文。content_type 固定为 1(Markdown)。
wecom-cli doc edit_doc_content '{"docid": "DOCID", "content": "# 标题\n\n正文内容", "content_type": 1}'参见 API 详情。
---
二、智能文档(原名智能主页)
适用品类:智能文档(用户说「智能文档」或「智能主页」时触发) 适用 URL:/smartpage/*
⚠️ 只有当用户明确指定「智能文档」或「智能主页」时,才使用以下接口。其他「文档」场景请使用上方的企微文档接口。
适用场景: 1. 将本地 Markdown 文件创建为智能文档 2. 异步导出智能文档内容为 Markdown
smartpage_create
创建智能文档(原名智能主页),支持传入标题和多个子页面。每个子页面可指定标题、内容类型和本地文件路径。创建成功返回 docid 和 url。
⚠️ 特殊语法:此命令必须使用+smartpage_create(带+前缀),加号不可省略;该+仅适用于此命令,不要泛化到其他doc子命令。
wecom-cli doc +smartpage_create '{"title": "项目概览", "pages": [{"page_title": "需求文档", "content_type": 1, "page_filepath": "/path/to/requirements.md"}]}'注意:
content_type必须与文件实际内容匹配:.md文件或包含 Markdown 语法的内容必须传1(Markdown),仅纯文本才传0。绝大多数场景应传1- docid 仅在创建时返回,需妥善保存
- 每个子页面的 Markdown 文件大小不得超过 10MB,超过会导致创建失败。如果文件过大,需先拆分为多个子页面再创建
参见 API 详情。
smartpage_export_task
发起智能文档内容导出任务(异步)。传入 docid(或 url)和 content_type,返回 task_id。这是异步导出的第一步,需配合 smartpage_get_export_result 轮询获取导出结果。
- 通过 docid:
wecom-cli doc smartpage_export_task '{"docid": "DOCID", "content_type": 1}'- 或通过 URL:
wecom-cli doc smartpage_export_task '{"url": "https://doc.weixin.qq.com/smartpage/xxx", "content_type": 1}'参见 API 详情。
smartpage_get_export_result
查询智能文档导出任务进度。传入 task_id 进行轮询,当 task_done 为 true 时返回 content(导出的完整文档内容)。
wecom-cli doc smartpage_get_export_result '{"task_id": "TASK_ID"}'当 task_done 为 true 时,content 字段即为导出的 Markdown 内容。
参见 API 详情。
---
三、智能表格结构管理
smartsheet_get_sheet
查询文档中所有子表信息,返回 sheet_id、title、类型等。
wecom-cli doc smartsheet_get_sheet '{"docid": "DOCID"}'smartsheet_add_sheet
添加空子表。新子表不含视图、记录和字段,需通过其他接口补充。
wecom-cli doc smartsheet_add_sheet '{"docid": "DOCID", "properties": {"title": "新子表"}}'注意:新建智能表格文档默认已含一个子表,仅需多个子表时调用。
smartsheet_update_sheet
修改子表标题。需提供 sheet_id 和新 title。
wecom-cli doc smartsheet_update_sheet '{"docid": "DOCID", "properties":{"sheet_id":"SHEET_ID", "title":"新子表"}}'smartsheet_delete_sheet
永久删除子表,操作不可逆。
wecom-cli doc smartsheet_delete_sheet '{"docid": "DOCID", "sheet_id": "SHEETID"}'smartsheet_get_fields
查询子表的所有字段信息,返回 field_id、field_title、field_type。
wecom-cli doc smartsheet_get_fields '{"docid": "DOCID", "sheet_id": "SHEETID"}'smartsheet_add_fields
向子表添加一个或多个字段。单个子表最多 150 个字段。
wecom-cli doc smartsheet_add_fields '{"docid": "DOCID", "sheet_id": "SHEETID", "fields": [{"field_title": "任务名称", "field_type": "FIELD_TYPE_TEXT"}]}'支持的字段类型参见 字段类型参考。
smartsheet_update_fields
更新字段标题。只能改名,不能改类型(field_type 必须传原始类型)。field_title 不能更新为原值。
wecom-cli doc smartsheet_update_fields '{"docid": "DOCID", "sheet_id": "SHEETID", "fields": [{"field_id": "FIELDID", "field_title": "新标题", "field_type": "FIELD_TYPE_TEXT"}]}'smartsheet_delete_fields
删除一列或多列字段,操作不可逆。field_id 可通过 smartsheet_get_fields 获取。
wecom-cli doc smartsheet_delete_fields '{"docid": "DOCID", "sheet_id": "SHEETID", "field_ids": ["FIELDID"]}'---
四、智能表格数据管理
smartsheet_get_records
查询子表全部记录。
- 通过 docid:
wecom-cli doc smartsheet_get_records '{"docid": "DOCID", "sheet_id": "SHEETID"}'- 或通过 URL:
wecom-cli doc smartsheet_get_records '{"url": "https://doc.weixin.qq.com/smartsheet/xxx", "sheet_id": "SHEETID"}'参见 API 详情。
smartsheet_add_records 添加一行或多行记录(不带图片或文件)
添加一行或多行记录,单次建议 500 行内。
调用前必须先了解目标表的字段类型(通过 smartsheet_get_fields),重点关注 field_type。对于单选/多选(Option)字段,需注意匹配已有选项的 id。
wecom-cli doc smartsheet_add_records '{"docid": "DOCID", "sheet_id": "SHEETID", "records": [{"values": {"任务名称": [{"type": "text", "text": "完成需求文档"}], "优先级": [{"text": "高"}]}}]}'各字段类型的值格式参见 单元格值格式参考。
⚠️ 若返回errcode: 851003或errmsg包含no authority(通常是企业可见范围 > 10 人的规模限制),切换到 Webhook 兜底方案,详见 wecom-doc-smartsheet-webhook.md。
+smartsheet_add_records_auto_file 添加一行或多行记录(带图片或文件)
添加一行或多行记录,单次建议 500 行内。与 smartsheet_add_records 不同之处在于,可支持本地路径传入图片、文件。对于需要添加带图片或文件的记录,请使用此接口。传入后台后,后台将自动存储并转换为image_url。
wecom-cli doc +smartsheet_add_records_auto_file '{"docid":"DOCID","sheet_id":"SHEETID","records":[{"values":{"图片":[{"image_path":"/path/to/image.jpg"}],"文件":[{"file_path":"/path/to/file.txt"}]}}]}'smartsheet_update_records 更新记录(不带图片或文件)
更新一行或多行记录,单次建议在 500 行内。需提供 record_id(通过 smartsheet_get_records 获取)。支持通过 key_type 指定 values 的 key 使用字段标题或字段 ID:
CELL_VALUE_KEY_TYPE_FIELD_TITLE:key 为字段标题CELL_VALUE_KEY_TYPE_FIELD_ID:key 为字段 ID
wecom-cli doc smartsheet_update_records '{"docid": "DOCID", "sheet_id": "SHEETID", "key_type": "CELL_VALUE_KEY_TYPE_FIELD_TITLE", "records": [{"record_id": "RECORDID", "values": {"任务名称": [{"type": "text", "text": "更新后的内容"}]}}]}'注意:创建时间、最后编辑时间、创建人、最后编辑人字段不可更新。
⚠️ 若返回errcode: 851003或errmsg包含no authority(通常是企业可见范围 > 10 人的规模限制),切换到 Webhook 兜底方案,详见 wecom-doc-smartsheet-webhook.md。注意 Webhook 只能更新通过 Webhook 写入的记录,人工创建的记录无法更新。
+smartsheet_update_records_auto_file 更新记录(更新图片或文件字段)
更新一行或多行记录,单次建议在 500 行内。与 smartsheet_update_records 不同之处在于,可支持本地路径传入图片、文件。对于需要更新记录中的图片或文件,请使用此接口。传入后台后,后台将自动存储并转换为image_url。
wecom-cli doc +smartsheet_update_records_auto_file '{"docid": "DOCID", "sheet_id": "SHEETID", "key_type": "CELL_VALUE_KEY_TYPE_FIELD_TITLE", "records": [{"record_id": "RECORDID", "values": {"values":{"图片":[{"image_path":"/path/to/image.jpg"}],"文件":[{"file_path":"/path/to/file.txt"}]}}}]}'smartsheet_delete_records
删除一行或多行记录,单次必须在 500 行内。操作不可逆。record_id 通过 smartsheet_get_records 获取。
wecom-cli doc smartsheet_delete_records '{"docid": "DOCID", "sheet_id": "SHEETID", "record_ids": ["RECORDID1", "RECORDID2"]}'---
典型工作流
关键提示:读取内容前先看 URL 判断品类。/doc/、/sheet/、/smartsheet/→get_doc_content;/smartpage/→smartpage_export_task。只有用户明确提到「智能文档」或「智能主页」时才走 smartpage 流程,其他文档场景一律使用企微文档接口。
文档操作
1. 读取文档 / 表格 / 智能表格 →
wecom-cli doc get_doc_content '{"docid": "DOCID", "type": 2}'或通过 URL(/doc/*、/sheet/*、/smartsheet/* 均适用):
wecom-cli doc get_doc_content '{"url": "https://doc.weixin.qq.com/sheet/xxx", "type": 2}'若 task_done 为 false 则携带 task_id 继续轮询 2. 创建新文档 →
wecom-cli doc create_doc '{"doc_type": 3, "doc_name": "文档名"}',保存返回的 docid 3. 编辑文档 → 先 get_doc_content 了解当前内容,再 edit_doc_content 覆写
智能文档操作
1. 创建智能文档(仅当用户明确要求「智能文档」或「智能主页」时,⚠️ 命令必须带 + 前缀,不可省略) →
wecom-cli doc +smartpage_create '{"title": "标题", "pages": [{"page_title": "子页面", "content_type": 1, "page_filepath": "/path/to/file.md"}]}',保存返回的 docid 2. 获取智能文档内容(URL 含 /smartpage/,异步两步):
- 第一步:发起导出任务 →
wecom-cli doc smartpage_export_task '{"docid": "DOCID", "content_type": 1}',获取 task_id
- 第二步:轮询导出结果 →
wecom-cli doc smartpage_get_export_result '{"task_id": "TASK_ID"}',若 task_done 为 false 则继续轮询,直到 task_done 为 true,返回的 content 字段即为 Markdown 内容
智能表格结构操作
1. 了解表结构 →
wecom-cli doc smartsheet_get_sheet '{"docid": "DOCID"}'→
wecom-cli doc smartsheet_get_fields '{"docid": "DOCID", "sheet_id": "SHEETID"}'2. 创建表结构 → smartsheet_add_sheet 添加子表 → smartsheet_add_fields 定义列 3. 修改表结构 → smartsheet_update_fields 改列名 / smartsheet_delete_fields 删列
智能表格数据操作
1. 读取数据 →
wecom-cli doc smartsheet_get_records '{"docid":"DOCID","sheet_id":"SHEETID"}'2. 写入数据 → 先 smartsheet_get_fields 了解列类型 → 若涉及成员(USER)字段,先通过通讯录的 get_userlist 查找人员 userid(参见 wecom-contact.md) → smartsheet_add_records 写入 3. 更新数据 → 先 smartsheet_get_records 获取 record_id → 若涉及成员(USER)字段,先通过通讯录的 get_userlist 查找人员 userid → smartsheet_update_records 更新 4. 删除数据 → 先 smartsheet_get_records 确认 record_id → smartsheet_delete_records 删除 5. 写入失败 fallback → 第 2/3 步返回 errcode: 851003 / no authority(通常是企业可见范围 > 10 人的规模限制)时 → 请用户临时提供目标表的 Webhook 地址 + schema 示例 JSON(不保存到本地)→ 按 wecom-doc-smartsheet-webhook.md 构造请求体发送
注意:成员(USER)类型字段需要填写user_id,不能直接使用姓名。必须先通过通讯录的get_userlist接口按姓名查找到对应的userid后再使用。
创建会议 - 全参数综合场景示例
场景 : 高规格会议 (全参数)
用户意图: "帮我创建一个高规格的季度战略会议: 下周一上午9点,时长4小时,邀请全团队,设置密码,开启等候室,开启屏幕水印,全员静音"
{
"title": "Q2季度战略规划会",
"meeting_start_datetime": "2026-03-23 09:00",
"meeting_duration": 14400,
"description": "Q2季度战略规划,请各部门负责人提前准备汇报材料",
"location": "总部大会议室",
"invitees": {
"userid": ["zhangsan", "lisi", "wangwu", "zhaoliu", "sunqi"]
},
"settings": {
"password": "2026",
"enable_waiting_room": true,
"allow_enter_before_host": false,
"enable_enter_mute": 1,
"allow_external_user": false,
"enable_screen_watermark": true,
"remind_scope": 3,
"ring_users": {
"userid": ["zhangsan", "lisi", "wangwu", "zhaoliu", "sunqi"]
}
}
}创建会议 - 响铃提醒场景示例
场景 1: 仅提醒主持人
用户意图: "帮我创建一个会议,只提醒主持人,其他人不要响铃"
{
"title": "项目启动会",
"meeting_start_datetime": "2026-03-21 10:00",
"meeting_duration": 3600,
"invitees": {
"userid": ["zhangsan", "lisi"]
},
"settings": {
"remind_scope": 2
}
}---
场景 2: 指定部分人响铃 (remind_scope=4)
用户意图: "帮我创建一个会议,只响铃提醒张三和李四,其他人不提醒"
{
"title": "紧急故障复盘",
"meeting_start_datetime": "2026-03-18 20:00",
"meeting_duration": 3600,
"invitees": {
"userid": ["zhangsan", "lisi", "wangwu", "zhaoliu"]
},
"settings": {
"remind_scope": 4,
"ring_users": {
"userid": ["zhangsan", "lisi"]
},
"allow_enter_before_host": true
}
}创建会议 - 安全设置场景示例
场景 : 会议密码 + 等候室 + 主持人设置
用户意图: "帮我创建一个重要的客户汇报会议,需要设置密码1234,开启等候室,不允许外部人员入会"
{
"title": "客户汇报会议",
"meeting_start_datetime": "2026-03-19 14:00",
"meeting_duration": 5400,
"invitees": {
"userid": ["zhangsan", "lisi", "wangwu"]
},
"settings": {
"password": "1234",
"enable_waiting_room": true,
"allow_enter_before_host": false,
"allow_external_user": false
}
}获取会议详情 (get_meeting_info) - 返回参数
返回参数
{
"errcode": 0,
"errmsg": "ok",
"creator_userid": "创建者userid",
"admin_userid": "会议管理userid (与 creator_userid 有且仅返回一个)",
"title": "会议标题",
"meeting_start_datetime": "YYYY-MM-DD HH:mm",
"meeting_duration": "会议时长秒数",
"description": "会议描述文本",
"location": "会议地点文本",
"main_department": "创建者主部门ID",
"status": "会议状态枚举值",
"meeting_type": "会议类型枚举值",
"attendees": {
"member": [
{
"userid": "内部成员userid",
"status": "与会状态枚举值",
"first_join_datetime": "YYYY-MM-DD HH:mm",
"last_quit_datetime": "YYYY-MM-DD HH:mm",
"total_join_count": "加入次数",
"cumulative_time": "累计在会时长秒数"
}
],
"tmp_external_user": [
{
"tmp_external_userid": "外部临时用户ID",
"status": "与会状态枚举值",
"first_join_datetime": "YYYY-MM-DD HH:mm",
"last_quit_datetime": "YYYY-MM-DD HH:mm",
"total_join_count": "加入次数",
"cumulative_time": "累计在会时长秒数"
}
]
},
"settings": {
"remind_scope": "提醒范围枚举值",
"need_password": "是否需要密码布尔值",
"password": "会议密码",
"enable_waiting_room": "是否启用等候室布尔值",
"allow_enter_before_host": "是否允许提前入会布尔值",
"enable_enter_mute": "入会静音枚举值",
"allow_unmute_self": "是否允许自我解除静音布尔值",
"allow_external_user": "是否允许外部用户布尔值",
"enable_screen_watermark": "是否开启水印布尔值",
"watermark_type": "水印类型枚举值",
"auto_record_type": "录制类型枚举字符串",
"attendee_join_auto_record": "参会者加入自动录制布尔值",
"enable_host_pause_auto_record": "主持人可暂停录制布尔值",
"enable_doc_upload_permission": "允许上传文档布尔值",
"enable_enroll": "是否开启报名布尔值",
"enable_host_key": "是否启用主持人密钥布尔值",
"host_key": "主持人密钥字符串",
"hosts": {"userid": ["主持人userid列表"]},
"current_hosts": {"userid": ["当前主持人userid列表"]},
"co_hosts": {"userid": ["联席主持人userid列表"]},
"ring_users": {"userid": ["响铃用户userid列表"]}
},
"meeting_code": "会议号码字符串",
"meeting_link": "会议链接URL",
"has_vote": "是否有投票布尔值",
"has_more_sub_meeting": "是否还有更多子会议枚举值",
"remain_sub_meetings": "剩余子会议场数",
"current_sub_meetingid": "当前子会议ID",
"guests": [
{
"area": "国际区号",
"phone_number": "手机号字符串",
"guest_name": "嘉宾姓名"
}
],
"reminders": {
"is_repeat": "是否周期性枚举值",
"repeat_type": "重复类型枚举值",
"repeat_until_type": "结束类型枚举值",
"repeat_until_count": "限定次数",
"repeat_until_datetime": "YYYY-MM-DD HH:mm",
"repeat_interval": "重复间隔数值",
"is_custom_repeat": "是否自定义重复枚举值",
"repeat_day_of_week": ["星期几数组"],
"repeat_day_of_month": ["日期数组"],
"remind_before": ["提醒秒数数组"]
},
"sub_meetings": [
{
"sub_meetingid": "子会议ID",
"status": "子会议状态枚举值",
"start_datetime": "YYYY-MM-DD HH:mm",
"end_datetime": "YYYY-MM-DD HH:mm",
"title": "子会议标题",
"repeat_id": "周期性会议分段ID"
}
],
"sub_repeat_list": [
{
"repeat_id": "周期性会议分段ID",
"repeat_type": "重复类型枚举值",
"repeat_until_type": "结束类型枚举值",
"repeat_until_count": "限定次数",
"repeat_until_datetime": "YYYY-MM-DD HH:mm",
"repeat_interval": "重复间隔数值",
"is_custom_repeat": "是否自定义重复枚举值",
"repeat_day_of_week": ["星期几数组"],
"repeat_day_of_month": ["日期数组"]
}
]
}关键返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
creator_userid | string | 创建者 userid,与 admin_userid 有且仅返回一个 |
admin_userid | string | 会议管理 userid,与 creator_userid 有且仅返回一个 |
title | string | 会议标题 |
meeting_start_datetime | string | 会议开始时间 |
meeting_duration | integer | 会议时长 (秒) |
main_department | integer | 创建者所属主部门 |
status | integer | 会议状态 (1: 待开始,2: 会议中,3: 已结束,4: 已取消,5: 已过期) |
meeting_type | integer | 会议类型 (0: 一次性会议,1: 周期性会议,2: 微信专属会议,3: Rooms 投屏会议,5: 个人会议号会议,6: 网络研讨会) |
meeting_code | string | 会议号码 |
meeting_link | string | 会议链接 |
attendees.member | array | 内部参与者列表 |
attendees.member[].status | integer | 与会状态 (1: 已参与,2: 未参与) |
attendees.tmp_external_user | array | 外部参与者 (临时 ID) |
attendees.tmp_external_user[].status | integer | 与会状态 (1: 已参与,2: 未参与) |
guests | array | 外部嘉宾列表,每项含 area,phone_number,guest_name |
current_sub_meetingid | string | 当前子会议 ID |
settings.ring_users | object | 响铃用户列表 |
settings.need_password | boolean | 是否需要密码 (只读字段) |
settings.enable_doc_upload_permission | boolean | 是否允许成员上传文档 |
settings.hosts | object | 主持人列表 |
settings.current_hosts | object | 当前主持人列表 |
settings.co_hosts | object | 联席主持人列表 |
reminders | object | 周期性配置 |
has_vote | boolean | 是否有投票 (仅会议创建人和主持人有权限查询) |
has_more_sub_meeting | integer | 是否还有更多子会议特例 (0: 无更多,1: 有更多) |
remain_sub_meetings | integer | 剩余子会议场数 |
sub_meetings | array | 子会议列表 |
sub_meetings[].status | integer | 子会议状态 (0: 默认/存在,1: 已删除) |
sub_meetings[].repeat_id | string | 周期性会议分段 ID,用于关联子会议所属分段 |
sub_repeat_list | array | 周期性会议分段信息,修改周期性会议某一场后可能产生不同分段,各分段有不同重复规则 |
企业微信会议
公共概念与规则请参考 wecom-shared.md
概述
提供企业微信会议的完整管理能力,包含以下功能:
1. 创建预约会议 - 创建会议,支持设置会议参数,邀请参与人等 2. 查询会议列表 - 按用户和时间范围查询会议 ID 列表 (限制: 当日及前后 30 天,上限 100 个) 3. 获取会议详情 - 通过会议 ID 查询完整会议信息 4. 取消会议 - 取消指定的预约会议 5. 更新会议受邀成员 - 修改会议的参与人列表
命令调用方式
wecom-cli meeting <tool_name> '<json_params>'---
命令详细说明
1. 创建预约会议 (create_meeting)
创建一个预约会议,支持设置会议参数配置等。
执行命令
wecom-cli meeting create_meeting '{"title": "<会议标题>", "meeting_start_datetime": "<会议开始时间>", "meeting_duration": <会议持续时长(秒)>}'入参说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
title | string | 是 | 会议标题 |
meeting_start_datetime | string | 是 | 会议开始时间,格式:YYYY-MM-DD HH:mm |
meeting_duration | integer | 是 | 会议持续时长 (秒),例如 3600 = 1 小时 |
description | string | 否 | 会议描述 |
location | string | 否 | 会议地点 |
invitees | object | 否 | 被邀请人,格式:{"userid": ["lisi", "wangwu"]} |
settings | object | 否 | 会议设置 (详见下方) |
被邀请人 userid 通过通讯录查询获取(参见 wecom-contact.md)
settings 字段:
| 参数 | 类型 | 说明 |
|---|---|---|
password | string | 会议密码 |
enable_waiting_room | boolean | 是否启用等候室 |
allow_enter_before_host | boolean | 是否允许成员在主持人进入前加入 |
enable_enter_mute | integer | 入会时静音设置 (枚举: 0: 关闭,1: 开启) |
allow_external_user | boolean | 是否允许外部用户入会 |
enable_screen_watermark | boolean | 是否开启屏幕水印 |
remind_scope | integer | 提醒范围 (1: 不提醒,2: 仅提醒主持人,3: 提醒所有成员,4: 指定部分人响铃,默认仅提醒主持人) |
ring_users | object | 响铃用户,格式:{"userid": ["lisi"]} |
响铃用户 userid 通过通讯录查询获取
返回参数
{
"errcode": 0,
"errmsg": "ok",
"meetingid": "会议ID字符串",
"meeting_code": "会议号码字符串",
"meeting_link": "会议链接URL",
"excess_users": ["无效会议账号的userid"]
}| 字段 | 类型 | 说明 |
|---|---|---|
meetingid | string | 会议 ID |
meeting_code | string | 会议号码,向用户展示时需在回复开头单独一行纯文字展示,格式 #会议号: xxx-xxx-xxx (每3位用 - 分隔) |
meeting_link | string | 会议链接 |
excess_users | array | 参会人中包含无效会议账号的 userid,仅在购买会议专业版企业由于部分参会人无有效会议账号时返回 |
---
2. 查询会议列表 (list_user_meetings)
查询指定用户在时间范围内的会议 ID 列表。
执行命令
wecom-cli meeting list_user_meetings '{"begin_datetime": "2026-03-01 00:00", "end_datetime": "2026-03-31 23:59", "limit": 100}'入参说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
begin_datetime | string | 否 | 查询起始时间,格式:YYYY-MM-DD HH:mm |
end_datetime | string | 否 | 查询结束时间,格式:YYYY-MM-DD HH:mm |
cursor | string | 否 | 分页游标,用于获取下一页数据 |
limit | integer | 否 | 每页返回条数,最大 100 |
限制: 时间范围仅支持当日及前后 30 天。
返回参数
{
"errcode": 0,
"errmsg": "ok",
"next_cursor": "分页游标字符串,为空表示无更多",
"meetingid_list": ["会议ID_1", "会议ID_2"]
}| 字段 | 类型 | 说明 |
|---|---|---|
meetingid_list | array | 会议 ID 列表 |
next_cursor | string | 下一页游标,为空表示无更多数据 |
---
3. 获取会议详情 (get_meeting_info)
通过会议 ID 查询会议的完整详情。
执行命令
wecom-cli meeting get_meeting_info '{"meetingid": "<会议id>"}'入参说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
meetingid | string | 是 | 会议 ID,通过 list_user_meetings 获取 |
meeting_code | string | 否 | 会议号码 |
sub_meetingid | string | 否 | 子会议 ID |
返回参数
完整的返回参数结构和字段说明详见 wecom-meeting-response-get-meeting-info.md
核心字段速览:
| 字段 | 类型 | 说明 |
|---|---|---|
title | string | 会议标题 |
meeting_start_datetime | string | 会议开始时间 |
meeting_duration | integer | 会议时长 (秒) |
status | integer | 会议状态 (1: 待开始,2: 会议中,3: 已结束,4: 已取消,5: 已过期) |
meeting_type | integer | 会议类型 (0: 一次性,1: 周期性,2: 微信专属,3: Rooms 投屏,5: 个人会议号,6: 网络研讨会) |
meeting_code | string | 会议号码 |
meeting_link | string | 会议链接 |
description | string | 会议描述 |
location | string | 会议地点 |
attendees.member[].status | integer | 与会状态 (1: 已参与,2: 未参与) |
---
4. 取消会议 (cancel_meeting)
取消指定的预约会议。
执行命令
wecom-cli meeting cancel_meeting '{"meetingid": "<会议id>"}'入参说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
meetingid | string | 是 | 会议 ID,通过 list_user_meetings + get_meeting_info 获取 |
返回参数
{
"errcode": 0,
"errmsg": "ok"
}---
5. 更新会议受邀成员 (set_invite_meeting_members)
更新会议的受邀成员列表(全量覆盖)。
执行命令
wecom-cli meeting set_invite_meeting_members '{"meetingid": "<会议id>", "invitees": [{"userid": "lisi"}, {"userid": "wangwu"}]}'入参说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
meetingid | string | 是 | 会议 ID,通过 list_user_meetings + get_meeting_info 获取 |
invitees | array | 是 | 受邀成员列表,每项包含 userid 字段 |
注意: invitees 为全量覆盖,传入的列表将替换现有成员列表。
invitees 的 userid 通过通讯录查询获取(参见 wecom-contact.md)
返回参数
{
"errcode": 0,
"errmsg": "ok"
}---
典型工作流
工作流 1: 最简创建 (无邀请人)
用户意图: "帮我约一个明天下午3点的会议,主题是周例会,时长1小时"
步骤:
1. 解析用户意图: 时间 + 主题已有,邀请人未提及则默认留空,直接创建。 2. 调用创建命令:
wecom-cli meeting create_meeting '{"title": "周例会", "meeting_start_datetime": "2026-03-18 15:00", "meeting_duration": 3600}'3. 展示结果:
#会议号: <会议号>
✅ 会议创建成功!
📅 <会议标题>
🕐 时间: <开始时间>,时长 <时长>
🔗 会议链接: <会议链接>工作流 2: 带邀请人 + 地点 + 描述创建
用户意图: "帮我约一个明天下午3点的会议,主题是技术方案评审,邀请张三和李四,地点在3楼会议室,时长1小时"
步骤:
1. 解析用户意图: 有邀请人,需先查询通讯录获取 userid。 2. 通讯录查询: 调用通讯录获取成员,按姓名筛选出参与者的 userid。
wecom-cli contact get_userlist '{}'在返回的 userlist 中筛选 name 包含 "张三" 和 "李四" 的成员,获取其 userid。
3. 信息已充分,直接调用创建命令 (禁止暴露内部 ID):
wecom-cli meeting create_meeting '{"title": "技术方案评审", "meeting_start_datetime": "2026-03-18 15:00", "meeting_duration": 3600, "location": "3楼会议室", "invitees": {"userid": ["zhangsan", "lisi"]}}'4. 展示结果:
#会议号: <会议号>
✅ 会议创建成功!
📅 <会议标题>
🕐 时间: <开始时间>,时长 <时长>
👥 参与人: <参与者姓名列表>
🔗 会议链接: <会议链接>---
工作流 3: 查询会议列表
示例: 用户说 "帮我查一下本周有哪些会议"
步骤:
1. 确定时间范围: 根据当前日期计算本周的起止时间。 2. 查询会议 ID 列表:
wecom-cli meeting list_user_meetings '{"begin_datetime": "2026-03-16 00:00", "end_datetime": "2026-03-22 23:59", "limit": 100}'3. 逐个查询会议详情 (对返回的每个 meetingid):
wecom-cli meeting get_meeting_info '{"meetingid": "<会议id1>"}'wecom-cli meeting get_meeting_info '{"meetingid": "<会议id2>"}'4. 汇总展示:
📋 本周会议列表 (共 3 场):
1. 📅 技术方案评审
🕐 2026-03-17 10:00 - 11:00
👥 张三,李四,王五
2. 📅 产品需求沟通
🕐 2026-03-18 14:00 - 15:00
👥 赵六,钱七
3. 📅 周五周会
🕐 2026-03-21 09:00 - 10:00
👥 全组成员分页处理: 如果next_cursor不为空,使用cursor参数继续拉取下一页。
---
工作流 4: 获取会议详情
示例: 用户说 "帮我看下技术方案评审会议的详情"
步骤:
1. 定位会议: 先通过会议列表查询找到目标会议的 meetingid (按关键词匹配)。 2. 查询详情:
wecom-cli meeting get_meeting_info '{"meetingid": "<target_meetingid>"}'3. 展示结果:
#会议号: <会议号>
📅 <会议标题>
🕐 时间: <开始时间>,时长 <时长>
📍 地点: <会议地点>
📝 描述: <会议描述>
👤 创建者: <创建者姓名>
👥 参与者: <参与者姓名列表>
🔗 会议链接: <会议链接>---
工作流 5: 根据关键词查找会议
示例: 用户说 "技术评审会议是什么时候?"
查询策略:
1. 确定查询范围: 默认查当日前后 30 天 (接口限制范围)。 2. 拉取会议列表:
wecom-cli meeting list_user_meetings '{"begin_datetime": "2026-02-15 00:00", "end_datetime": "2026-04-16 23:59", "limit": 100}'3. 逐个查询详情并匹配标题关键词。 4. 找到匹配后停止查询,展示结果:
#会议号: <会议号>
✅ 找到会议: "<会议标题>"
📅 时间: <开始时间>,时长 <时长>
📍 地点: <会议地点>
👥 参与者: <参与者姓名列表>
🔗 会议链接: <会议链接>5. 未找到处理: 告知用户在前后 30 天范围内未找到匹配会议,请确认会议名称。
---
工作流 6: 取消会议
示例: 用户说 "帮我取消明天的技术方案评审会议"
步骤:
1. 定位会议: 通过 list_user_meetings + get_meeting_info 查询会议列表 + 关键词匹配找到目标会议。 2. 直接执行取消:
wecom-cli meeting cancel_meeting '{"meetingid": "<target_meetingid>"}'3. 展示结果:
✅ 会议已取消: 技术方案评审---
工作流 7: 更新会议成员
示例: 用户说 "把王五加到技术方案评审会议里"
步骤:
1. 定位会议: 通过 list_user_meetings + get_meeting_info 查询会议列表 + 匹配找到目标会议。 2. 获取当前受邀成员: set_invite_meeting_members 为全量覆盖,必须先通过 get_meeting_info 获取会议详情,获取现有成员后再合并。 3. 通讯录查询: 调用通讯录获取成员,按姓名筛选出王五的 userid。
wecom-cli contact get_userlist '{}'在返回的 userlist 中筛选 name 包含 "王五" 的成员,获取其 userid。
4. 合并成员列表: 将现有成员 + 新增成员合并 (全量覆盖)。 5. 执行更新:
wecom-cli meeting set_invite_meeting_members '{"meetingid": "<target_meetingid>", "invitees": [{"userid": "zhangsan"}, {"userid": "lisi"}, {"userid": "wangwu"}]}'6. 展示结果:
✅ 会议成员已更新: 技术方案评审
👥 当前成员: 张三,李四,王五---
复杂场景样例
按场景按需加载,避免一次性引入过多无关示例:
| 文件 | 适用场景 |
|---|---|
| wecom-meeting-response-get-meeting-info.md | 获取会议详情完整返回参数结构和字段说明 |
| wecom-meeting-example-security.md | 会议密码,等候室,外部用户限制 |
| wecom-meeting-example-reminder.md | 响铃提醒,指定部分人响铃 |
| wecom-meeting-example-full.md | 全参数综合场景 (含静音,屏幕水印,等候室等设置) |
---
注意事项
- 信息追问: 缺少时间或主题时,简洁追问用户;未提及邀请人则默认留空
- 通讯录查询: 涉及参与人时,需先通过通讯录的
get_userlist接口获取全量通讯录成员,再按姓名/别名本地筛选匹配出对应的userid(参见 wecom-contact.md)。该接口无入参,返回当前用户可见范围内的成员列表 (含userid,name,alias) - 直接创建: 时间 + 主题已知即可直接创建,邀请人有则带上,无则留空;无论信息是一次性提供还是上下文可推断,非必要则均不请求确认,直接创建即可
- 时间格式: 统一使用
YYYY-MM-DD HH:mm格式 - 会议列表时间范围限制: 仅支持查询当日及前后 30 天内的会议
- 查询详情需两步: 先通过
list_user_meetings获取会议 ID 列表,再通过get_meeting_info逐个获取详情 - 定位会议: 取消会议和更新成员等管理操作需先通过查询定位到目标会议的 meetingid
- 成员更新为全量覆盖:
set_invite_meeting_members传入的列表将替换现有成员列表,需先获取当前成员再合并 - 参与人仅支持企业内成员,不支持外部人员
get_message API
根据会话类型和会话 ID,拉取指定时间范围内的消息记录。支持文本、图片、文件、语音、视频类型消息。
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
chat_type | integer | ✅ | 会话类型,1-单聊,2-群聊 |
chatid | string | ✅ | 会话 ID,单聊时为 userid,群聊时为群 ID,最大 256 字节 |
begin_time | string | ✅ | 拉取开始时间,格式:YYYY-MM-DD HH:mm:ss,仅支持请求时刻往前 7 天内 |
end_time | string | ✅ | 拉取结束时间,格式:YYYY-MM-DD HH:mm:ss,必须 ≥ begin_time |
cursor | string | ❌ | 分页游标,首次请求不传,后续传入上次响应的 next_cursor,最大 256 字节 |
请求示例
单聊:
wecom-cli msg get_message '{"chat_type": 1, "chatid": "zhangsan", "begin_time": "2026-03-17 09:00:00", "end_time": "2026-03-17 18:00:00"}'群聊:
wecom-cli msg get_message '{"chat_type": 2, "chatid": "wrxxxxxxxx", "begin_time": "2026-03-17 09:00:00", "end_time": "2026-03-17 18:00:00"}'分页请求:
wecom-cli msg get_message '{"chat_type": 1, "chatid": "zhangsan", "begin_time": "2026-03-17 09:00:00", "end_time": "2026-03-17 18:00:00", "cursor": "CURSOR_xxxxxx"}'返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功 |
errmsg | string | 错误信息 |
messages | array | 消息列表 |
messages[].userid | string | 消息发送者的 userid |
messages[].send_time | string | 消息发送时间(北京时间),格式:YYYY-MM-DD HH:mm:ss |
messages[].msgtype | string | 消息类型,text-文本消息,image-图片消息,file-文件消息,voice-语音消息,video-视频消息 |
messages[].text | object | 文本消息内容,msgtype 为 text 时返回 |
messages[].text.content | string | 消息内容 |
messages[].image | object | 图片消息内容,msgtype 为 image 时返回 |
messages[].image.media_id | string | 图片的 media_id,可通过 get_msg_media 接口下载 |
messages[].image.name | string | 图片文件名称 |
messages[].file | object | 文件消息内容,msgtype 为 file 时返回 |
messages[].file.media_id | string | 文件的 media_id,可通过 get_msg_media 接口下载 |
messages[].file.name | string | 文件名称 |
messages[].voice | object | 语音消息内容,msgtype 为 voice 时返回 |
messages[].voice.media_id | string | 语音的 media_id,可通过 get_msg_media 接口下载 |
messages[].video | object | 视频消息内容,msgtype 为 video 时返回 |
messages[].video.media_id | string | 视频的 media_id,可通过 get_msg_media 接口下载 |
next_cursor | string | 分页游标,为空表示已拉取完毕 |
响应示例
{
"errcode": 0,
"errmsg": "ok",
"messages": [
{
"userid": "zhangsan",
"send_time": "2026-03-17 09:30:00",
"msgtype": "text",
"text": {
"content": "你好"
}
},
{
"userid": "lisi",
"send_time": "2026-03-17 09:35:00",
"msgtype": "image",
"image": {
"media_id": "MEDIAID_xxxxxx",
"name": "screenshot.png"
}
},
{
"userid": "zhangsan",
"send_time": "2026-03-17 09:40:00",
"msgtype": "file",
"file": {
"media_id": "MEDIAID_yyyyyy",
"name": "report.pdf"
}
}
],
"next_cursor": "CURSOR_xxxxxx"
}非文本消息处理
当 msgtype 为 image、file、voice、video 时,消息体中包含 media_id。需要调用 get_msg_media 接口获取文件的本地路径(local_path),再进行展示。
get_msg_chat_list API
获取指定时间范围内有消息的会话列表,支持分页查询。
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
begin_time | string | ✅ | 拉取开始时间,格式:YYYY-MM-DD HH:mm:ss |
end_time | string | ✅ | 拉取结束时间,格式:YYYY-MM-DD HH:mm:ss |
cursor | string | ❌ | 分页游标,首次请求不传,后续传入上次响应的 next_cursor,最大长度 256 |
请求示例
wecom-cli msg get_msg_chat_list '{"begin_time": "2026-03-11 00:00:00", "end_time": "2026-03-17 23:59:59"}'分页请求:
wecom-cli msg get_msg_chat_list '{"begin_time": "2026-03-11 00:00:00", "end_time": "2026-03-17 23:59:59", "cursor": "NEXT_CURSOR"}'返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功 |
errmsg | string | 错误信息 |
chats | array | 会话列表 |
chats[].chat_id | string | 会话 ID |
chats[].chat_name | string | 会话名称 |
chats[].last_msg_time | string | 最后一条消息时间,格式:YYYY-MM-DD HH:mm:ss |
chats[].msg_count | integer | 消息数量 |
has_more | boolean | 是否还有更多数据 |
next_cursor | string | 分页游标,用于下一次请求 |
响应示例
{
"errcode": 0,
"errmsg": "ok",
"chats": [
{
"chat_id": "CHAT_ID",
"chat_name": "张三",
"last_msg_time": "2026-03-17 15:30:45",
"msg_count": 128
},
{
"chat_id": "CHAT_ID_2",
"chat_name": "项目讨论群",
"last_msg_time": "2026-03-16 09:12:33",
"msg_count": 56
}
],
"has_more": true,
"next_cursor": "NEXT_CURSOR"
}get_msg_media API
获取消息文件内容。根据文件 ID 自动下载文件到本地,返回本地文件路径、文件名称、类型、大小及内容类型。
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
media_id | string | ✅ | 文件 ID,长度 1~256 |
请求示例
wecom-cli msg get_msg_media '{"media_id": "MEDIAID_xxxxxx"}'返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功 |
errmsg | string | 错误信息 |
media_item | object | 文件内容 |
media_item.media_id | string | 文件 ID |
media_item.name | string | 文件名称 |
media_item.type | string | 文件类型,image-图片,voice-语音,video-视频,file-普通文件 |
media_item.local_path | string | 文件下载后的本地路径 |
media_item.size | integer | 文件大小(字节) |
media_item.content_type | string | 文件 MIME 类型,如 image/png、application/pdf 等 |
响应示例
{
"errcode": 0,
"errmsg": "ok",
"media_item": {
"media_id": "MEDIAID_xxxxxx",
"name": "screenshot.png",
"type": "image",
"local_path": "xxx/yyy/screenshot.png",
"size": 102400,
"content_type": "image/png"
}
}send_message API
向单聊或群聊发送文本消息。
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
chat_type | integer | ✅ | 会话类型,1-单聊,2-群聊 |
chatid | string | ✅ | 会话 ID,单聊时为 userid,群聊时为群 ID,最大 256 字节 |
msgtype | string | ✅ | 消息类型,目前仅支持 text |
text | object | ✅ | 文本消息内容 |
text.content | string | ✅ | 消息内容,最大 2048 字节 |
请求示例
单聊:
wecom-cli msg send_message '{"chat_type": 1, "chatid": "zhangsan", "msgtype": "text", "text": {"content": "hello world"}}'群聊:
wecom-cli msg send_message '{"chat_type": 2, "chatid": "wrxxxxxxxx", "msgtype": "text", "text": {"content": "大家好"}}'返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功 |
errmsg | string | 错误信息 |
响应示例
{
"errcode": 0,
"errmsg": "ok"
}企业微信消息
公共概念与规则请参考 wecom-shared.md
通过 wecom-cli msg <接口名> '<json入参>' 与企业微信消息系统交互。
---
接口列表
get_msg_chat_list — 获取会话列表
wecom-cli msg get_msg_chat_list '{"begin_time": "2026-03-11 00:00:00", "end_time": "2026-03-17 23:59:59"}'按时间范围查询有消息的会话列表,支持分页。参见 API 详情。
get_message — 拉取会话消息
wecom-cli msg get_message '{"chat_type": 1, "chatid": "zhangsan", "begin_time": "2026-03-17 09:00:00", "end_time": "2026-03-17 18:00:00"}'根据会话类型和 ID 拉取指定时间范围内的消息记录,支持分页。支持 text/image/file/voice/video 消息类型,仅支持 7 天内。参见 API 详情。
get_msg_media — 获取消息文件内容
wecom-cli msg get_msg_media '{"media_id": "MEDIAID_xxxxxx"}'根据文件 ID 自动下载文件到本地,返回文件的本地路径(local_path)、名称、类型、大小及 MIME 类型。用于获取图片、文件、语音、视频等非文本消息的实际内容。参见 API 详情。
send_message — 发送文本消息
wecom-cli msg send_message '{"chat_type": 1, "chatid": "zhangsan", "msgtype": "text", "text": {"content": "hello world"}}'向单聊或群聊发送文本消息。参见 API 详情。
---
核心规则
时间范围规则
- 格式:所有时间参数使用
YYYY-MM-DD HH:mm:ss格式 - 默认范围:用户未指定时,默认使用最近7天(当前时间往前推7天)
- 限制:开始时间不能早于当前时间的7天前,不能晚于当前时间
- 相对时间支持:支持"昨天"、"最近三天"等自动推算
chatid查找规则
- 当用户提供人名或群名而非ID时:
1. 调用 get_msg_chat_list 获取会话列表(时间范围与目标查询一致) 2. 在 chats 中按 chat_name 匹配 3. 匹配策略:
- 精确匹配唯一结果:直接使用
- 模糊匹配多个结果:展示候选列表让用户选择
- 无匹配结果:告知用户未找到
- chat_type 判断:
get_msg_chat_list返回中不含会话类型字段,需根据上下文推断:用户明确提到「群」时使用chat_type=2,否则默认chat_type=1(单聊)
userid 转 name
流程: 1. 调用通讯录的 get_userlist 获取用户列表(参见 wecom-contact.md) 2. 建立 userid 到 name 的映射关系 3. 展示策略:
- 精确匹配:显示 name
- 无匹配:保持显示 userid
强制交互步骤(不可跳过)
以下步骤在涉及非文本消息下载时必须逐一执行,不得合并、省略或跳过,即使用户未主动询问也必须执行: 1. 必须主动告知文件位置:下载完成后必须立即向用户展示所有文件的完整路径和存放目录 2. 必须询问是否删除:告知位置后必须立即询问用户是否需要清理临时文件
---
典型工作流
查看会话列表
用户query示例:
- "看看我最近一周有哪些聊天"
- "这几天谁给我发过消息"
执行流程: 1. 确定时间范围(用户指定或默认最近7天) 2. 调用 get_msg_chat_list 获取会话列表 3. 展示会话名称、最后消息时间、消息数量 4. 若 has_more 为 true,告知用户还有更多会话可继续查看
查看聊天记录
用户query示例:
- "帮我看看和张三最近的聊天记录"
- "看看项目群里最近的消息"
执行流程: 1. 确定时间范围(用户指定或默认最近7天) 2. 通过 chatid查找规则 确定目标会话的 chatid 和 chat_type 3. 调用 get_message 拉取消息列表 4. 调用通讯录的 get_userlist 获取通讯录,建立 userid→姓名 映射 5. 统计非文本消息:遍历消息列表,统计 msgtype 非 text 的消息(image/file/voice/video)数量和类型 6. 展示消息时将 userid 替换为可读姓名,格式:
- 文本消息:
姓名 [时间]: 内容 - 图片消息:
姓名 [时间]:[图片] - 文件消息:
姓名 [时间]:[文件] 文件名称 - 语音消息:
姓名 [时间]:[语音] 语音内容 - 视频消息:
姓名 [时间]:[视频]
7. 非文本消息处理:展示完消息后,如果存在非文本消息:
- 主动询问是否下载:告知用户非文本消息数量和类型(如:"以上聊天中包含 2 张图片、1 个文件,是否需要下载到本地?")
- 用户确认后,逐个调用
get_msg_media接口,接口会自动下载文件并返回local_path - 检查文件后缀:每个文件下载完成后,检查
local_path对应的文件是否具有正确的后缀名: - 根据
get_msg_media返回的content_type(MIME 类型)和name字段判断: - 如果文件名缺少后缀(如
screenshot而非screenshot.png),根据content_type自动补上正确后缀(如image/png→.png,application/pdf→.pdf,audio/amr→.amr,video/mp4→.mp4) - 如果文件名后缀与
content_type不一致,以content_type为准进行修正 - 补全或修正后缀后,将文件重命名为正确的文件名
- 确认文件可正常读取(文件大小 > 0),若文件为空或损坏则告知用户该文件下载异常
- ⚠️ 不要对下载的文件使用 `MEDIA:` 指令:这些文件是从聊天记录中下载的历史附件,仅需告知用户本地存放路径即可,严禁通过
MEDIA:指令重新发送给用户
8. ⚠️ 必须主动告知文件位置(此步骤不可跳过):所有文件下载并检查完成后,必须立即、主动以汇总形式向用户展示文件存放目录和每个文件的完整路径,不要等用户询问。示例:
📁 文件已下载到以下位置:
- 图片:xxx/yyy.png- 文件:xxx/yyy.pdf>
你可以在 xxx/yyy/ 目录下找到所有下载的文件。9. ⚠️ 必须询问是否删除(此步骤不可跳过):告知文件位置后,必须立即、主动询问用户是否需要删除已下载的临时文件(如:"如果不再需要这些文件,是否需要我帮你清理?")
- 用户确认删除后,删除
local_path对应的文件 - 用户不需要删除则保留文件
10. 若 next_cursor 不为空,告知用户还有更多消息可继续查看
发送消息
用户query示例:
- "帮我给张三发一条消息:明天会议改到下午3点"
- "在项目群里发一条消息:今天下午3点开会"
执行流程: 1. 通过 chatid查找规则 确定目标会话的 chatid 和 chat_type 2. 发送前确认:向用户确认发送对象和内容(如:"即将向 张三 发送:'明天会议改到下午3点',确认发送吗?"),用户确认后再执行 3. 调用 send_message 发送(msgtype 固定为 text) 4. 展示发送结果
查看消息并回复
用户query示例:
- "看看张三给我发了什么,然后帮我回复收到"
执行流程: 1. 先执行"查看聊天记录"流程(复用已获取的 chatid 和 chat_type) 2. 展示消息后,执行"发送消息"流程(需确认后再发送)
---
错误处理
- 时间范围超限:告知用户7天限制并调整为有效范围
- 会话未找到:明确告知用户未找到对应会话
- API错误:展示具体错误信息,必要时重试
- 网络问题:HTTP错误时主动重试最多3次
check_availability API
查询指定用户在某时间范围内的忙碌时段。
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
check_user_list | array | ✅ | 用户 ID 列表,1~10 个 |
start_time | string | ✅ | 查询开始时间 |
end_time | string | ✅ | 查询结束时间 |
请求示例
wecom-cli schedule check_availability '{"check_user_list": ["USER_ID_1", "USER_ID_2"], "start_time": "YYYY-MM-DD HH:mm:ss", "end_time": "YYYY-MM-DD HH:mm:ss"}'返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功 |
errmsg | string | 错误信息 |
user_busy_list | array | 用户忙碌时段列表 |
user_busy_list[] 数组中每项字段
| 字段 | 类型 | 说明 |
|---|---|---|
userid | string | 用户 ID |
busy_slots | array | 忙碌时段列表 |
busy_slots[].start_time | string | 忙碌时段开始时间 |
busy_slots[].end_time | string | 忙碌时段结束时间 |
busy_slots[].schedule_id | string | 关联的日程 ID |
busy_slots[].subject | string | 日程标题 |
响应示例
{
"errcode": 0,
"errmsg": "ok",
"user_busy_list": [
{
"userid": "USER_ID",
"busy_slots": [
{
"start_time": "YYYY-MM-DD HH:mm:ss",
"end_time": "YYYY-MM-DD HH:mm:ss",
"schedule_id": "SCHEDULE_ID",
"subject": "日程标题"
}
]
}
]
}create_schedule API
创建新日程,支持设置标题、时间、地点、参与者、提醒和重复规则。
参数说明(schedule 对象内)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
start_time | string | ✅ | 开始时间 |
end_time | string | ✅ | 结束时间 |
summary | string | ❌ | 日程标题,最长 128 字 |
description | string | ❌ | 日程描述,最长 1000 字 |
location | string | ❌ | 地点,最长 128 字 |
is_whole_day | integer | ❌ | 是否全天:0-否(默认),1-是 |
attendees | array | ❌ | 参与者列表,每项含 userid |
reminders | object | ❌ | 提醒与重复设置(见 reminders 字段参考) |
请求示例
wecom-cli schedule create_schedule '{"schedule": {"start_time": "YYYY-MM-DD HH:mm:ss", "end_time": "YYYY-MM-DD HH:mm:ss", "summary": "日程标题", "attendees": [{"userid": "USER_ID"}], "reminders": {"is_remind": 1, "remind_before_event_secs": 3600, "timezone": 8}, "location": "会议地点"}}'返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功 |
errmsg | string | 错误信息 |
schedule_id | string | 创建成功的日程 ID |
响应示例
{
"errcode": 0,
"errmsg": "ok",
"schedule_id": "SCHEDULE_ID"
}get_schedule_detail API
通过日程 ID 批量获取日程详细信息。
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
schedule_id_list | array | ✅ | 日程 ID 列表,1~50 个 |
请求示例
wecom-cli schedule get_schedule_detail '{"schedule_id_list": ["SCHEDULE_ID_1", "SCHEDULE_ID_2"]}'返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功 |
errmsg | string | 错误信息 |
schedule | array | 日程详情列表 |
schedule[] 字段
| 字段 | 类型 | 说明 |
|---|---|---|
schedule_id | string | 日程唯一 ID |
summary | string | 日程标题 |
description | string | 日程描述 |
start_time | integer | 开始时间(Unix 时间戳,秒) |
end_time | integer | 结束时间(Unix 时间戳,秒) |
location | string | 地点 |
status | integer | 0-正常,1-已取消 |
is_whole_day | integer | 0-否,1-是 |
admins | array | 管理员 userid 列表 |
attendees | array | 参与者列表 |
attendees[].userid | string | 参与者 userid |
attendees[].response_status | integer | 响应状态(见下表) |
reminders | object | 提醒设置(见 reminders 字段参考) |
response_status 枚举
| 值 | 含义 |
|---|---|
1 | 待定 |
2 | 接受 |
3 | 接受单次 |
4 | 拒绝 |
5 | 接受本次及未来 |
6 | 待定单次 |
7 | 待定本次及未来 |
8 | 拒绝单次 |
9 | 拒绝本次及未来 |
响应示例
{
"errcode": 0,
"errmsg": "ok",
"schedule": [
{
"schedule_id": "SCHEDULE_ID",
"summary": "日程标题",
"start_time": 1700000000,
"end_time": 1700003600,
"location": "会议室",
"status": 0,
"is_whole_day": 0,
"attendees": [
{"userid": "USER_ID","tmp_external_userid": "tmp_external_userid_example","response_status": 2}
],
"reminders": {
"is_remind": 1,
"remind_before_event_secs": 3600,
"timezone": 8
}
}
]
}reminders 字段参考
提醒设置对象,用于 create_schedule 和 update_schedule 接口。
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
is_remind | integer | 是否提醒:0-否,1-是 |
remind_before_event_secs | integer | 提前提醒秒数,可选值:0/300/900/3600/86400 |
remind_time_diffs | array | 提醒时间差(秒),可选值:-604800/-172800/-86400/-3600/-900/-300/0/32400 |
timezone | integer | 时区,-12 ~ 12,中国为 8 |
使用示例
基本提醒(提前 1 小时)
{
"is_remind": 1,
"remind_before_event_secs": 3600,
"timezone": 8
}update_schedule API
修改已有日程,只需传入需要修改的字段,未传字段保持不变。
参数说明(schedule 对象内)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
schedule_id | string | ✅ | 目标日程 ID |
start_time | string | ❌ | 开始时间 |
end_time | string | ❌ | 结束时间 |
summary | string | ❌ | 日程标题,最长 128 字 |
description | string | ❌ | 日程描述,最长 1000 字 |
location | string | ❌ | 地点,最长 128 字 |
is_whole_day | integer | ❌ | 是否全天:0-否,1-是 |
attendees | array | ❌ | 参与者列表,每项含 userid |
reminders | object | ❌ | 提醒与重复设置(见 reminders 字段参考) |
仅传需修改的字段,其余保持不变。
请求示例
wecom-cli schedule update_schedule '{"schedule": {"schedule_id": "SCHEDULE_ID", "summary": "更新后的标题", "start_time": "YYYY-MM-DD HH:mm:ss", "end_time": "YYYY-MM-DD HH:mm:ss"}}'返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功 |
errmsg | string | 错误信息 |
企业微信日程管理
公共概念与规则请参考 wecom-shared.md
通过 wecom-cli schedule <接口名> '<json入参>' 与企业微信日程系统交互。
注意事项
- 日程列表查询仅支持当日前后 30 天,时间格式
YYYY-MM-DD或YYYY-MM-DD HH:mm:ss - 涉及参与者 userid 时,需先使用通讯录查询获取(参见 wecom-contact.md);存在同名时展示候选让用户选择(禁止暴露 userid)
- 创建/修改/取消前,先确认目标日程和参与者信息
errcode != 0时展示错误信息;返回的start_time/end_time为 Unix 时间戳(秒),需转为可读格式- 注意时间格式转换:接口入参使用字符串格式(如
YYYY-MM-DD HH:mm:ss),但返回值多为 Unix 时间戳,使用时需进行格式转换
---
接口列表
get_schedule_list_by_range — 查询日程 ID 列表
wecom-cli schedule get_schedule_list_by_range '{"start_time": "YYYY-MM-DD HH:mm:ss", "end_time": "YYYY-MM-DD HH:mm:ss"}'返回 schedule_id_list 数组。仅支持当日前后 30 天。
get_schedule_detail — 获取日程详情
wecom-cli schedule get_schedule_detail '{"schedule_id_list": ["SCHEDULE_ID_1", "SCHEDULE_ID_2"]}'支持 1~50 个 ID,返回日程标题、时间、地点、参与者等。参见 API 详情。
create_schedule — 创建日程
wecom-cli schedule create_schedule '{"schedule": {"start_time": "YYYY-MM-DD HH:mm:ss", "end_time": "YYYY-MM-DD HH:mm:ss", "summary": "日程标题", "attendees": [{"userid": "USER_ID"}], "reminders": {"is_remind": 1, "remind_before_event_secs": 3600, "timezone": 8}}}'参见 API 详情 | reminders 字段。
update_schedule — 修改日程
只需传入需修改的字段,未传字段保持不变。
wecom-cli schedule update_schedule '{"schedule": {"schedule_id": "SCHEDULE_ID", "summary": "更新后的标题"}}'参见 API 详情。
cancel_schedule — 取消日程
wecom-cli schedule cancel_schedule '{"schedule_id": "SCHEDULE_ID"}'add_schedule_attendees / del_schedule_attendees — 管理参与人
- 添加参与人:
wecom-cli schedule add_schedule_attendees '{"schedule_id": "SCHEDULE_ID", "attendees": [{"userid": "USER_ID"}]}'- 移除参与人:
wecom-cli schedule del_schedule_attendees '{"schedule_id": "SCHEDULE_ID", "attendees": [{"userid": "USER_ID"}]}'check_availability — 查询闲忙
wecom-cli schedule check_availability '{"check_user_list": ["USER_ID_1", "USER_ID_2"], "start_time": "YYYY-MM-DD HH:mm:ss", "end_time": "YYYY-MM-DD HH:mm:ss"}'支持 1~10 个用户,返回各用户的忙碌时段列表。参见 API 详情。
---
典型工作流
查询日程
经典 query 示例:
- "我今天有哪些日程?"
- "帮我看看这周三下午有没有会议"
- "明天的日程安排是什么?"
- "查一下最近有没有关于项目评审的日程"
- "我下周一到周五的日程都有哪些?"
流程: 1. 根据用户意图计算时间范围(如"今天"→当日 00:00:00 至 23:59:59,"这周"→本周一至周日) 2. 调用 get_schedule_list_by_range 获取日程 ID 列表 3. 调用 get_schedule_detail 批量获取详情,将 Unix 时间戳转为可读时间 4. 若用户提到关键词(如"项目评审"),在 summary 中匹配筛选;未找到则逐步扩大范围至前后 30 天上限 5. 展示日程列表时包含标题、时间、地点、参与者等关键信息,方便用户快速了解
创建日程
经典 query 示例:
- "帮我创建一个明天下午 2 点到 3 点的会议,标题叫需求评审"
- "安排一个周五全天的团建活动"
- "创建日程:后天上午 10 点和张三、李四开产品方案讨论会,地点在 3 楼会议室"
- "帮我建个日程,下周一 14:00-15:00,提前 15 分钟提醒"
- "约一个明天上午的日程,邀请王伟参加"
流程: 1. 解析用户意图,提取时间、标题、地点、参与人、提醒设置等信息 2. 若涉及参与人,先通过通讯录查询 userid(参见 wecom-contact.md);存在同名时展示候选让用户选择 3. 若用户未指定提醒,默认设置提前 15 分钟提醒(remind_before_event_secs: 900) 4. 若用户说"全天",设置 is_whole_day: 1,时间设为当天 00:00:00 至 23:59:59 5. 向用户确认日程信息(标题、时间、地点、参与人等)后调用 create_schedule
修改日程
经典 query 示例:
- "把明天的需求评审改到后天下午 3 点"
- "帮我修改下今天下午的会议标题,改成技术方案评审"
- "我今天 14 点的日程地点改成线上腾讯会议"
- "把周五的团建活动推迟一个小时"
- "帮我给明天的周会加个描述:讨论 Q2 规划"
流程: 1. 先通过查询工作流定位目标日程(根据用户提到的时间、标题等关键词匹配) 2. 若匹配到多个日程,展示候选列表让用户确认 3. 向用户确认要修改的字段和目标值 4. 调用 update_schedule,只传入需修改的字段
取消日程
经典 query 示例:
- "取消明天下午的需求评审"
- "帮我把周五的团建日程删掉"
- "我不想开今天 15 点的会了,帮我取消"
流程: 1. 先通过查询工作流定位目标日程 2. 向用户确认取消的日程信息(标题、时间等),避免误操作 3. 确认后调用 cancel_schedule
管理参与人
经典 query 示例:
- "把张三加到明天的需求评审会议里"
- "帮我把李四从周五的日程里移除"
- "明天下午的会议再邀请一下王伟和赵敏"
- "把我后天那个技术分享的参与人里去掉刘强"
流程: 1. 通过通讯录获取目标人员 userid(参见 wecom-contact.md);存在同名时展示候选让用户选择 2. 通过查询工作流定位目标日程 3. 调用 add_schedule_attendees 或 del_schedule_attendees 完成添加/移除
查询闲忙并安排会议
经典 query 示例:
- "帮我看看张三和李四明天下午有没有空"
- "查一下我和王伟这周的空闲时间,想约个会"
- "我想跟产品组的小明、小红开个会,看看大家什么时候有空"
- "找一个明天下午大家都有空的时段,安排一个 1 小时的会议"
流程: 1. 通过通讯录获取相关人员 userid 2. 调用 check_availability 查询指定时间范围内各用户的忙碌时段 3. 分析所有用户的忙碌时段,计算出共同空闲时段并推荐给用户 4. 用户确认时段后,调用 create_schedule 创建会议并自动添加参与人
公共概念与规则
本文档包含所有业务域共享的公共内容,包括 CLI 安装要求、凭证配置、通用调用格式、返回格式、错误处理、通讯录查询方法和时间格式规范。
---
CLI 安装与版本要求
- 包名:
@wecom/cli - 安装命令:
npm install -g @wecom/cli- 检查安装:
which wecom-cli || echo "NOT_INSTALLED"---
凭证配置
检查凭证状态
wecom-cli auth show --auth-status- 输出
authorized→ 已配置 - 输出
unauthorized→ 未配置,需执行初始化
配置凭证
wecom-cli init交互式命令,引导用户完成授权配置,仅需执行一次。
---
通用调用格式
所有业务域的命令遵循统一格式:
wecom-cli <品类> <接口名> '<json入参>'品类列表:
| 品类 | 说明 |
|---|---|
contact | 通讯录 |
msg | 消息 |
doc | 文档 & 智能表格 |
schedule | 日程 |
meeting | 会议 |
todo | 待办 |
示例:
wecom-cli msg send_message '{"chat_type": 1, "chatid": "zhangsan", "msgtype": "text", "text": {"content": "hello"}}'---
通用返回格式
所有接口返回 JSON 对象,包含以下公共字段:
| 字段 | 类型 | 说明 |
|---|---|---|
errcode | integer | 返回码,0 表示成功,非 0 表示失败 |
errmsg | string | 错误信息,成功时为 "ok" |
成功示例:
{
"errcode": 0,
"errmsg": "ok",
...
}失败示例:
{
"errcode": 40001,
"errmsg": "invalid credential"
}---
通用错误处理与重试策略
1. errcode 非 0:说明接口调用失败,将 errcode 和 errmsg 展示给用户 2. 可重试错误:遭遇 HTTP 错误或网络问题时,主动重试,最多重试 3 次 3. 不可重试错误:参数错误、权限不足等,直接告知用户错误信息 4. errcode 非 0 但可能是临时性错误:可重试 1 次,若仍失败则展示错误信息
---
通讯录查询(userid ↔ 姓名转换)
多个业务域(消息、日程、会议、待办等)在涉及人员操作时,需要将用户姓名转换为 userid,或将 userid 转换为可读姓名。
获取通讯录
wecom-cli contact get_userlist '{}'返回当前用户可见范围内的成员列表:
{
"errcode": 0,
"errmsg": "ok",
"userlist": [
{"userid": "zhangsan", "name": "张三", "alias": "Sam"},
{"userid": "lisi", "name": "李四", "alias": ""}
]
}姓名 → userid(用于创建/修改操作)
1. 调用 get_userlist 获取全量成员 2. 按 name 或 alias 匹配目标人员 3. 精确匹配唯一结果:直接使用 4. 模糊匹配多个结果:展示候选列表让用户选择 5. 无匹配结果:告知用户未找到
⚠️ 禁止根据用户姓名自行猜测 userid,必须通过通讯录查询获取。
userid → 姓名(用于展示操作)
1. 调用 get_userlist 获取全量成员 2. 建立 userid → name 的映射关系 3. 展示时将 userid 替换为可读姓名 4. 若通讯录中找不到某个 ID,展示时标注"未知用户(ID:xxx)"
注意事项
get_userlist返回的是当前用户可见范围内的成员,非全量成员- ⚠️ 超过 10 人时接口将报错,本功能仅适用于可见范围较小的场景
alias字段可能为空字符串,搜索时需做空值判断- 若搜索结果有多个同名人员,需将所有候选人展示给用户选择,不得自行决定
- 只需调用一次
get_userlist,在本地对结果进行多次筛选,避免重复调用接口
---
时间格式规范
不同业务域的时间格式略有差异,请注意区分:
| 业务域 | 入参格式 | 返回格式 |
|---|---|---|
| 消息 (msg) | YYYY-MM-DD HH:mm:ss | YYYY-MM-DD HH:mm:ss |
| 文档 (doc) | 无时间参数 | 无时间参数 |
| 日程 (schedule) | YYYY-MM-DD 或 YYYY-MM-DD HH:mm:ss | Unix 时间戳(秒),需转为可读格式 |
| 会议 (meeting) | YYYY-MM-DD HH:mm | YYYY-MM-DD HH:mm |
| 待办 (todo) | YYYY-MM-DD HH:mm:ss | YYYY-MM-DD HH:mm:ss |
相对时间支持
用户说"今天"、"明天"、"昨天"、"最近三天"、"下周一"等相对时间时,根据当前日期自动推算为具体日期时间。
Related skills
How it compares
Choose wecom-unified over generic messaging skills when automating WeCom corporate accounts with doc.weixin.qq.com documents and CLI credentials.
FAQ
How do you install wecom-unified prerequisites?
wecom-unified requires wecom-cli installed via npm install -g @wecom/cli@0.1.8. Run wecom-cli --version and wecom-cli auth show --auth-status before any contacts, messaging, or document commands.
Which WeCom features does wecom-unified cover?
wecom-unified spans six domains: contacts, messaging, documents (including smart spreadsheets), schedules, meetings, and todos. Agents can search contacts by name, send multimedia messages, and manage doc.weixin.qq.com content.
Does wecom-unified trigger on doc.weixin.qq.com links?
wecom-unified should trigger when messages include doc.weixin.qq.com URLs or involve schedules, todos, documents, meetings, or contact lookup, even if the user does not explicitly mention 企业微信 or WeCom by name.