dingtalk-ai-table

负责钉钉 AI 表格(.able 格式多维表格)的所有操作,通过钉钉开放平台 Notable API 实现。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "dingtalk-ai-table" with this command: npx skills add breath57/dingtalk-skills/breath57-dingtalk-skills-dingtalk-ai-table

钉钉 AI 表格技能

负责钉钉 AI 表格(.able 格式多维表格)的所有操作,通过钉钉开放平台 Notable API 实现。

核心概念:

  • AI 表格(.able 文件):多维表格,使用 Notable API(/v1.0/notable ),不是普通电子表格

  • base_id:AI 表格文件的 nodeId,是表格在钉钉文档系统中的唯一标识

  • 工作表(Sheet):AI 表格内的单张表,包含字段和记录

  • 字段(Field):列定义,有名称和类型(text 、number 、date 等)

  • 记录(Record):数据行,包含各字段的值

API 详情见 references/api.md 。

配置管理(每次开始前必读)

配置文件路径

~/.dingtalk-skills/config (跨会话保留,所有 dingtalk-skills 共用同一文件)

本技能需要的配置说明

键 说明 来源

DINGTALK_APP_KEY

钉钉应用 appKey 开放平台 → 应用管理 → 凭证信息

DINGTALK_APP_SECRET

钉钉应用 appSecret 同上

DINGTALK_MY_USER_ID

当前用户的企业员工 ID(userId) 管理后台 → 通讯录 → 成员管理 → 点击姓名查看(不是手机号、不是 unionId)

DINGTALK_MY_OPERATOR_ID

当前用户的 unionId 首次由脚本自动通过 userId 转换获取并写入

DINGTALK_AI_TABLE_BASE_ID

AI 表格的 nodeId 从 AI 表格分享链接提取

启动流程(每次执行任务前)

  • 读取配置:检查 ~/.dingtalk-skills/config 是否存在,解析已有键值

  • 识别缺失项:找出上表中尚未配置的键

  • 一次性收集:将所有缺失项合并为一条提问,不要逐条询问,例如:

需要以下信息才能继续(已有的无需再填):

  • 钉钉应用 appKey(钉钉开放平台 → 应用管理 → 凭证信息)

  • 钉钉应用 appSecret

  • AI 表格链接(用于提取 base_id)

  • 你的钉钉 userId(管理后台 → 通讯录 → 成员管理 → 点击姓名查看)

  • 持久化:将用户提供的值追加写入 config,后续直接读取,无需再问

  • 执行任务:配置完整后开始操作

注意:APP_KEY /APP_SECRET /OPERATOR_ID 属于凭证,禁止在输出中完整打印,确认时仅显示前 4 位 + **** 。

认证

每次调用 API 前,用 appKey/appSecret 获取当次的 accessToken(有效期 2 小时):

POST https://api.dingtalk.com/v1.0/oauth2/accessToken Content-Type: application/json

{ "appKey": "<应用 appKey>", "appSecret": "<应用 appSecret>" }

所有请求需携带:

  • 请求头:x-acs-dingtalk-access-token: <accessToken>

  • 查询参数:operatorId=<用户 unionId> (所有写操作及部分读操作必须)

为什么需要 base_id

钉钉文档系统中每个文件(文档、表格、AI 表格)都有一个全局唯一的 nodeId,即 base_id 。它的作用类似数据库主键——API 通过它定位到具体是哪个 AI 表格文件,因为账号下可能有多个 .able 文件。

从链接提取 base_id:

https://alidocs.dingtalk.com/i/nodes/&#x3C;base_id>?... ↑ 这一段就是 base_id

请用户提供 AI 表格的分享链接,从 /nodes/ 后截取 ID 片段。首次获取后写入 config,后续无需再问。

为什么需要 operatorId(unionId)

钉钉开放平台要求所有写操作必须代表一个真实用户身份执行,而不是以匿名应用身份操作。operatorId 就是声明"这个操作是谁做的"——它会被记录到变更日志、触发对应用户的通知,并用于权限校验。

  • AI 表格 API 的 operatorId 参数使用 unionId(跨组织唯一),不是 userId

  • 配置中优先收集 userId (管理后台直接查看),系统自动转换为 unionId

身份标识说明

标识 说明 如何获取

userId (= staffId ) 企业内部员工 ID,最容易获取 管理后台 → 通讯录 → 成员管理 → 点击姓名查看

unionId

跨企业/跨应用唯一 通过 userId 调用 API 转换获取

userId → unionId 自动转换

当配置中有 DINGTALK_MY_USER_ID 但缺少 DINGTALK_MY_OPERATOR_ID 时,自动执行转换:

1. 获取旧版 token

OLD_TOKEN=$(curl -s "https://oapi.dingtalk.com/gettoken?appkey=${APP_KEY}&#x26;appsecret=${APP_SECRET}" | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4)

2. userId → unionId

UNION_ID=$(curl -s -X POST "https://oapi.dingtalk.com/topapi/v2/user/get?access_token=${OLD_TOKEN}"
-H 'Content-Type: application/json'
-d "{"userid":"${USER_ID}"}" | grep -o '"unionid":"[^"]*"' | cut -d'"' -f4)

3. 写入配置文件

echo "DINGTALK_MY_OPERATOR_ID=$UNION_ID" >> ~/.dingtalk-skills/config

⚠️ 注意:返回体中 result.unionid (无下划线)有值,result.union_id (有下划线)可能为空。

核心操作

  1. 列出工作表

GET https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets?operatorId={operatorId} x-acs-dingtalk-access-token: <accessToken>

返回:

{ "value": [ { "id": "HAcL4SD", "name": "项目" }, { "id": "nr2iEiW", "name": "任务" } ] }

  1. 查询单个工作表

GET https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}?operatorId={operatorId}

返回:{ "id": "HAcL4SD", "name": "项目" }

  1. 新建工作表

POST https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets?operatorId={operatorId} Content-Type: application/json

{ "name": "新工作表名称", "fields": [ { "name": "标题", "type": "text" }, { "name": "数量", "type": "number" } ] }

fields 可选(不传则创建空工作表)。

返回:{ "id": "新sheetId", "name": "新工作表名称" }

  1. 删除工作表

DELETE https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}?operatorId={operatorId}

返回:{ "success": true }

⚠️ 不可恢复,执行前需用户确认。

  1. 列出字段

GET https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}/fields?operatorId={operatorId}

返回:

{ "value": [ { "id": "6mNRNHb", "name": "标题", "type": "text" }, { "id": "BDGLCo2", "name": "截止日期", "type": "date", "property": { "formatter": "YYYY-MM-DD" } }, { "id": "mr8APlG", "name": "数量", "type": "number", "property": { "formatter": "INT" } } ] }

  1. 新建字段

POST https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}/fields?operatorId={operatorId} Content-Type: application/json

{ "name": "字段名称", "type": "number" }

type 常用值:text (文本)、number (数字)、date (日期)

返回:{ "id": "新fieldId", "name": "字段名称", "type": "number", "property": { "formatter": "INT" } }

  1. 更新字段

PUT https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}/fields/{field_id}?operatorId={operatorId} Content-Type: application/json

{ "name": "新字段名称" }

返回:{ "id": "fieldId" } (通过重新查询列表确认名称已变更)

  1. 删除字段

DELETE https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}/fields/{field_id}?operatorId={operatorId}

返回:{ "success": true }

⚠️ 删除字段会同时删除该列所有数据,执行前需用户确认。

  1. 新增记录(最常用操作)

POST https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}/records?operatorId={operatorId} Content-Type: application/json

{ "records": [ { "fields": { "标题": "任务一", "数量": 3 } }, { "fields": { "标题": "任务二", "数量": 5 } } ] }

fields 中使用字段名称(非 ID)作为键。

返回:{ "value": [{ "id": "记录ID1" }, { "id": "记录ID2" }] }

  1. 查询记录列表

POST https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}/records/list?operatorId={operatorId} Content-Type: application/json

{ "maxResults": 20, "nextToken": "" }

返回:

{ "records": [ { "id": "RNXU1Vm2L2", "fields": { "标题": "任务一", "数量": 3 }, "createdTime": 1772723541439, "createdBy": { "unionId": "xxx" }, "lastModifiedTime": 1772723541439, "lastModifiedBy": { "unionId": "xxx" } } ], "hasMore": false, "nextToken": "" }

翻页:上次响应 hasMore=true 时,将 nextToken 传入下次请求。

  1. 更新记录

PUT https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}/records?operatorId={operatorId} Content-Type: application/json

{ "records": [ { "id": "记录ID", "fields": { "标题": "新标题" } } ] }

返回:{ "value": [{ "id": "记录ID" }] }

只传需要修改的字段,未传字段保持不变。

  1. 删除记录

POST https://api.dingtalk.com/v1.0/notable/bases/{base_id}/sheets/{sheet_id}/records/delete?operatorId={operatorId} Content-Type: application/json

{ "recordIds": ["记录ID1", "记录ID2"] }

返回:{ "success": true }

典型场景

"查看 AI 表格里有哪些工作表"

  • 询问 AI 表格链接,提取 base_id

  • GET /sheets 获取工作表列表

  • 展示工作表名称和 ID

"往 AI 表格的'任务'工作表添加几条记录"

  • GET /sheets 找到目标工作表的 sheet_id

  • GET /fields 了解现有字段名称和类型

  • POST /records 批量插入,fields 中用字段名称作键

  • 告知写入成功及记录 ID

"查询'任务'表中所有记录"

  • GET /sheets 找到 sheet_id

  • POST /records/list 翻页获取所有记录

  • 整理为表格形式展示

"删除某条记录"

  • 先 POST /records/list 定位目标记录(让用户确认)

  • POST /records/delete 传入 recordId

  • 告知删除成功

"给工作表新增一个'备注'文本字段"

  • GET /sheets 找到 sheet_id

  • POST /fields ,{ "name": "备注", "type": "text" }

  • 返回新字段 ID 并告知成功

字段类型参考

type 含义

text

纯文本

number

数字(含 property.formatter :INT 、PERCENT 等)

date

日期(含 property.formatter :如 YYYY-MM-DD )

错误处理

HTTP 状态码 / code 含义 处理方式

401 token 过期 重新获取 accessToken

403 权限不足 检查应用是否开通 Notable 相关权限

invalidRequest.document.notFound

base_id 无效或无权访问 确认 AI 表格 nodeId 正确且已授权

404 工作表或字段不存在 确认 sheet_id / field_id 正确

429 触发限流 等待 1 秒后重试

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

dingtalk-document

No summary provided by upstream source.

Repository SourceNeeds Review
General

dingtalk-message

No summary provided by upstream source.

Repository SourceNeeds Review
General

dingtalk-todo

No summary provided by upstream source.

Repository SourceNeeds Review
General

dingtalk-contact

No summary provided by upstream source.

Repository SourceNeeds Review