
Dingtalk Contact
- 284 installs
- 97 repo stars
- Updated June 26, 2026
- breath57/dingtalk-skills
dingtalk-contact is an integration skill that wires Claude agents to DingTalk contact APIs for enterprise directory lookup, sync, and messaging workflows inside SaaS or internal tooling builds.
About
dingtalk-contact is a breath57/dingtalk-skills module for connecting AI agents to DingTalk enterprise contact endpoints. It guides directory lookup, contact sync, and messaging workflow setup when building SaaS or internal tools that must read or act on DingTalk org data. Developers reach for dingtalk-contact when agents need authenticated calls to DingTalk contact APIs instead of manual OpenAPI exploration. The skill fits enterprise integrations where Claude or Cursor agents orchestrate HR directory queries, contact synchronization jobs, or notification flows against DingTalk backends.
- DingTalk contact API wiring
- Enterprise directory lookup
- Agent-driven contact sync
- Tenant and OAuth scoping
- Messaging workflow hooks
Dingtalk Contact by the numbers
- 284 all-time installs (skills.sh)
- Ranked #499 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/breath57/dingtalk-skills --skill dingtalk-contactAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 284 |
|---|---|
| repo stars | ★ 97 |
| Last updated | June 26, 2026 |
| Repository | breath57/dingtalk-skills ↗ |
How do you integrate DingTalk contact APIs in agents?
Wire Claude agents to DingTalk contact APIs for enterprise directory lookup, sync, and messaging workflows inside SaaS or internal tooling builds.
Who is it for?
Developers building enterprise SaaS or internal tools that must query or sync DingTalk organizational contacts via agents.
Skip if: Products outside the DingTalk ecosystem or teams without enterprise messaging and directory requirements.
When should I use this skill?
A build task needs DingTalk directory lookup, contact sync, or messaging API integration through an agent.
What you get
DingTalk contact API integration with directory lookup, sync jobs, and messaging workflow hooks.
- DingTalk contact API client wiring
- Directory sync or messaging workflow stubs
Files
钉钉通讯录技能
负责钉钉通讯录的所有查询操作。本文件为策略指南,仅包含决策逻辑和工作流程。完整 API 请求格式见文末「references/api.md 查阅索引」。
dt_helper.sh位于本SKILL.md同级目录的scripts/dt_helper.sh。
工作流程(每次执行前)
1. 先识别本次任务类型 → 例如:搜索用户、查用户详情、搜索部门、列部门成员、查部门路径、统计员工数 2. 按本次任务校验所需配置 → 通过 bash scripts/dt_helper.sh --get KEY 读取;仅校验本任务必须项 3. 仅收集缺失配置 → 若缺少某项,一次性询问用户所有缺失值,用 bash scripts/dt_helper.sh --set KEY=VALUE 写入 4. 获取 Token → 直接调用 bash scripts/dt_helper.sh 5. 执行操作 → 复杂的创建临时文件再执行,简单的直接执行;禁止 heredoc
按任务校验配置(必须先做)
- 所有任务通用必需:
DINGTALK_APP_KEY、DINGTALK_APP_SECRET - 需要“以当前操作者为起点”或“直接读取本人身份信息”的任务:必须有
DINGTALK_MY_USER_ID
规则:未通过“本次任务配置校验”前,不得进入 API 调用步骤。
凭证禁止在输出中完整打印,确认时仅显示前 4 位 + ****所需配置
| 配置键 | 必填 | 说明 | 如何获取 |
|---|---|---|---|
DINGTALK_APP_KEY | ✅ | 应用 AppKey | 钉钉开放平台 → 应用管理 → 凭证信息 |
DINGTALK_APP_SECRET | ✅ | 应用 AppSecret | 同上 |
DINGTALK_MY_USER_ID | ❌ | 当前操作用户的 userId(即运行此技能的人自己),仅在需要以自身为起点查询时才需要 | 管理后台 → 通讯录 → 成员管理 → 点击姓名查看 |
身份标识说明
| 标识 | 说明 |
|---|---|
userId(= staffId) | 企业内部员工 ID,可通过通过管理后台 -> 通讯录 -> 成员管理 -> 点击姓名查看 |
unionId | 跨企业/跨应用唯一标识,可通过 bash scripts/dt_helper.sh --to-unionid <userid> 获取 |
执行脚本模板
#!/bin/bash
set -e
HELPER="./scripts/dt_helper.sh"
NEW_TOKEN=$(bash "$HELPER" --token) # api.dingtalk.com 接口用
OLD_TOKEN=$(bash "$HELPER" --old-token) # oapi.dingtalk.com 接口用
# USER_ID=$(bash "$HELPER" --get DINGTALK_MY_USER_ID) # 以当前操作用户为起点时启用
# 在此追加具体 API 调用,例如按姓名搜索用户并获取详情:
KEYWORD="张三"
SEARCH=$(curl -s -X POST https://api.dingtalk.com/v1.0/contact/users/search \
-H "x-acs-dingtalk-access-token: $NEW_TOKEN" \
-H 'Content-Type: application/json' \
-d "{\"queryWord\":\"$KEYWORD\",\"offset\":0,\"size\":20}")
echo "搜索结果: $SEARCH"
TARGET_UID=$(echo "$SEARCH" | grep -o '"list":\["[^"]*"' | grep -o '"[^"]*"$' | tr -d '"')
DETAIL=$(curl -s -X POST "https://oapi.dingtalk.com/topapi/v2/user/get?access_token=${OLD_TOKEN}" \
-H 'Content-Type: application/json' \
-d "{\"userid\":\"$TARGET_UID\",\"language\":\"zh_CN\"}")
echo "用户详情: $DETAIL"Token 失效处理:dt_helper 仅按时间缓存,无法感知 token 被提前吊销。若 API 返回errcode 40001/40014(token 无效/过期),用--nocache跳过缓存强制重新获取:
```bash
OLD_TOKEN=$(bash "$HELPER" --old-token --nocache) # 强制重新获取旧版 token
NEW_TOKEN=$(bash "$HELPER" --token --nocache) # 强制重新获取新版 token
```
references/api.md 查阅索引
确定好要做什么之后,用以下命令从 references/api.md 中提取对应章节的完整 API 细节(请求格式、参数说明、返回值示例):
grep -A 30 "^## 1. 按关键词搜索用户" references/api.md
grep -A 50 "^## 2. 获取用户完整详情" references/api.md
grep -A 20 "^## 3. unionId → userId 转换" references/api.md
grep -A 18 "^## 4. 企业员工总人数" references/api.md
grep -A 25 "^## 5. 按关键词搜索部门" references/api.md
grep -A 25 "^## 6. 获取子部门列表" references/api.md
grep -A 20 "^## 7. 获取子部门 ID 列表" references/api.md
grep -A 25 "^## 8. 获取部门详情" references/api.md
grep -A 40 "^## 9. 获取部门成员完整列表" references/api.md
grep -A 18 "^## 10. 获取部门成员 userId 列表" references/api.md
grep -A 20 "^## 11. 获取用户所在部门路径" references/api.md
grep -A 12 "^## 错误码" references/api.md
grep -A 6 "^## 所需应用权限" references/api.mddingtalk-contact API 参考
所有接口均已验证可用。
NEW_TOKEN= 新版 token(api.dingtalk.com用),获取方式bash scripts/dt_helper.sh --token
OLD_TOKEN= 旧版 token(oapi.dingtalk.com用),获取方式bash scripts/dt_helper.sh --old-token
---
1. 按关键词搜索用户
POST https://api.dingtalk.com/v1.0/contact/users/search
Header: x-acs-dingtalk-access-token: {NEW_TOKEN}请求体:
{
"queryWord": "张三",
"offset": 0,
"size": 20
}| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
queryWord | string | ✅ | 搜索关键词,不可为空 |
offset | int | ❌ | 分页偏移量,默认 0 |
size | int | ❌ | 每页数量,最大 20 |
响应:
{
"hasMore": false,
"totalCount": 1,
"list": ["25262904"]
}⚠️ list 中存放的是 userId(字符串),不是 unionId。---
2. 获取用户完整详情
POST https://oapi.dingtalk.com/topapi/v2/user/get?access_token={OLD_TOKEN}请求体:
{
"userid": "25262904",
"language": "zh_CN"
}响应(result 字段):
{
"userid": "25262904",
"unionid": "dGJ...",
"name": "张三",
"title": "高级工程师",
"job_number": "EMP001",
"mobile": "138xxxx0000",
"state_code": "86",
"email": "zhangsan@example.com",
"org_email": "zhangsan@corp.com",
"dept_id_list": [932988755, 933257043],
"dept_order_list": [{"dept_id": 932988755, "order": 0}],
"dept_position_list": [{"dept_id": 932988755, "title": "工程师"}],
"role_list": [{"id": 123, "name": "管理员", "group_name": "组织架构"}],
"hired_date": 1640000000000,
"active": true,
"admin": false,
"boss": false
}⚠️ 返回体中result.unionid(无下划线)有值,result.union_id(有下划线)可能为空。
errcode 说明:0=成功;60121=用户不存在;40014=token 无效。
---
3. unionId → userId 转换
POST https://oapi.dingtalk.com/topapi/user/getbyunionid?access_token={OLD_TOKEN}请求体:
{
"unionid": "dGJ..."
}响应:
{
"errcode": 0,
"errmsg": "ok",
"result": {
"contact_type": 0,
"userid": "25262904"
}
}contact_type=0企业内部员工;contact_type=1外部联系人。
---
4. 企业员工总人数
POST https://oapi.dingtalk.com/topapi/user/count?access_token={OLD_TOKEN}请求体:
{ "only_active": false }only_active=true 仅统计激活员工;false 统计全部。
响应:
{
"errcode": 0,
"errmsg": "ok",
"result": { "count": 2192 }
}---
5. 按关键词搜索部门
POST https://api.dingtalk.com/v1.0/contact/departments/search
Header: x-acs-dingtalk-access-token: {NEW_TOKEN}请求体:
{
"queryWord": "技术",
"offset": 0,
"size": 20
}响应:
{
"hasMore": false,
"totalCount": 2,
"list": [932988755, 933257043]
}list返回部门 ID(整数)。根部门 ID =1。
---
6. 获取子部门列表
POST https://oapi.dingtalk.com/topapi/v2/department/listsub?access_token={OLD_TOKEN}请求体:
{ "dept_id": 1, "language": "zh_CN" }响应(result 为数组):
[
{
"dept_id": 932988755,
"name": "技术部",
"parent_id": 1,
"auto_add_user": false,
"dept_manager_userid_list": ["25262904"]
}
]---
7. 获取子部门 ID 列表
POST https://oapi.dingtalk.com/topapi/v2/department/listsubid?access_token={OLD_TOKEN}请求体:
{ "dept_id": 1 }响应:
{
"errcode": 0,
"result": { "dept_id_list": [932988755, 933257043, 933035510] }
}仅返回直接子部门,不递归多层。如需完整树,循环调用此接口。
---
8. 获取部门详情
POST https://oapi.dingtalk.com/topapi/v2/department/get?access_token={OLD_TOKEN}请求体:
{ "dept_id": 932988755, "language": "zh_CN" }响应(result):
{
"dept_id": 932988755,
"name": "技术部",
"parent_id": 1,
"member_count": 32,
"order": 100,
"auto_add_user": false,
"hide_dept": false
}---
9. 获取部门成员完整列表
POST https://oapi.dingtalk.com/topapi/v2/user/list?access_token={OLD_TOKEN}请求体:
{
"dept_id": 932988755,
"cursor": 0,
"size": 100,
"order_field": "custom",
"contain_access_level": false,
"language": "zh_CN"
}| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
dept_id | int | ✅ | 部门 ID |
cursor | int | ✅ | 分页游标,首次传 0 |
size | int | ✅ | 每页数量,最大 100 |
order_field | string | ❌ | custom=自定义排序 |
响应(result):
{
"has_more": true,
"next_cursor": 100,
"list": [
{
"userid": "25262904",
"unionid": "dGJ...",
"name": "张三",
"title": "工程师",
"job_number": "EMP001",
"mobile": "138xxxx0000",
"dept_id_list": [932988755],
"active": true
}
]
}分页:has_more=true时,用next_cursor作为下次请求的cursor。
---
10. 获取部门成员 userId 列表
POST https://oapi.dingtalk.com/topapi/user/listid?access_token={OLD_TOKEN}请求体:
{ "dept_id": 932988755 }响应:
{
"errcode": 0,
"result": { "userid_list": ["25262904", "12345678"] }
}---
11. 获取用户所在部门路径
POST https://oapi.dingtalk.com/topapi/v2/department/listparentbyuser?access_token={OLD_TOKEN}请求体:
{ "userid": "25262904" }响应:
{
"errcode": 0,
"result": {
"parent_list": [
{ "parent_dept_id_list": [932988755, 933257043, 1] }
]
}
}parent_dept_id_list从直属部门到根部门(1)排列。
用户可能同时属于多个部门,parent_list 每项对应一条路径。---
错误码
| errcode | 含义 | 处理建议 |
|---|---|---|
| 0 | 成功 | — |
| 40014 | token 无效或过期 | 删除缓存,重新获取 token |
| 60003 | 部门 ID 不存在 | 检查 dept_id 是否正确 |
| 60121 | 用户不存在 | 检查 userId 是否正确 |
| 60122 | unionId 不存在 | 检查 unionId 是否正确 |
| 88 | 没有操作权限 | 在钉钉开放平台申请对应接口权限 |
| 400 | 参数错误 | 检查 queryWord 不为空等参数约束 |
---
所需应用权限
| 权限 | 用途 |
|---|---|
qyapi_addresslist_search | 按关键词搜索用户/部门 |
Contact.User.Read | 读取用户详情(企业内部应用通常默认有) |
#!/bin/bash
# =============================================================================
# dt_helper.sh — 钉钉开放平台辅助工具
# 路径: scripts/common/dt_helper.sh
# 用法: bash scripts/common/dt_helper.sh <命令> [参数]
# =============================================================================
set -e
CONFIG="${DINGTALK_CONFIG:-$HOME/.dingtalk-skills/config}"
# ─────────────────────────────────────────────────────────────────────────────
# 帮助信息
# ─────────────────────────────────────────────────────────────────────────────
show_help() {
cat <<'EOF'
钉钉开放平台辅助工具 (dt_helper.sh)
用法: bash scripts/common/dt_helper.sh <命令> [参数]
Token 管理(两种 token 互不兼容,按域名区分):
--token [--nocache] 获取新版 accessToken(用于 api.dingtalk.com 域名的所有接口)
适用:待办、文档、AI 表格等 api.dingtalk.com 域名下所有版本的接口
请求头:x-acs-dingtalk-access-token: <token>
有缓存且未过期则直接返回,否则自动刷新并缓存
--nocache:跳过缓存,强制重新获取(token 被提前吊销时使用)
--token-info 查看新版 token 缓存状态(是否有效、剩余有效秒数)
--clear-token 清除缓存的新版 token(下次 --token 时强制重新获取)
--old-token [--nocache]
获取旧版 access_token(用于 oapi.dingtalk.com 域名的所有接口)
适用:群消息/工作通知/userId↔unionId 转换等 oapi.dingtalk.com 接口
不适用:api.dingtalk.com 接口(如待办、文档、AI表格)
⚠️ 新旧两种 token 互不兼容,混用会导致 401/403
--nocache:跳过缓存,强制重新获取(token 被提前吊销时使用)
身份转换:
--to-unionid [userId] 将 userId 转换为 unionId
不传参数:转换配置中的 DINGTALK_MY_USER_ID(操作者自身),
结果首次自动写入 DINGTALK_MY_OPERATOR_ID
传入参数:动态转换指定 userId,仅返回结果,不写入配置
--to-userid [unionId] 将 unionId 反向转换为 userId(需传入参数)
配置管理:
--config 查看 ~/.dingtalk-skills/config 中的所有配置项(敏感项脱敏显示)
--get KEY [KEY...] 获取一个或多个配置项的值(敏感项脱敏显示)
--set KEY=VALUE 将配置项持久化写入配置文件(已存在则更新,不存在则追加,目录自动创建)
帮助:
--help, -h 显示此帮助信息
环境变量:
DINGTALK_CONFIG 覆盖默认配置文件路径(默认 ~/.dingtalk-skills/config)
配置文件:
~/.dingtalk-skills/config key=value 格式,存储以下键:
DINGTALK_APP_KEY 应用 Client ID(AppKey)
DINGTALK_APP_SECRET 应用 Client Secret(AppSecret)
DINGTALK_MY_USER_ID 企业员工 ID(userId,管理后台通讯录可查)
DINGTALK_MY_OPERATOR_ID 操作者 unionId(由 --to-unionid 自动生成)
DINGTALK_ACCESS_TOKEN 新版 token 缓存
DINGTALK_TOKEN_EXPIRY 新版 token 过期时间戳(Unix 秒)
DINGTALK_OLD_TOKEN 旧版 token 缓存
DINGTALK_OLD_TOKEN_EXPIRY 旧版 token 过期时间戳(Unix 秒)
EOF
}
# ─────────────────────────────────────────────────────────────────────────────
# 工具函数
# ─────────────────────────────────────────────────────────────────────────────
# 从配置文件读取指定键的值
cfg_get() {
local key="$1"
grep "^${key}=" "$CONFIG" 2>/dev/null | head -1 | cut -d= -f2-
}
# 写入或更新配置文件中的键值
cfg_set() {
local key="$1"
local value="$2"
mkdir -p "$(dirname "$CONFIG")"
touch "$CONFIG"
if grep -q "^${key}=" "$CONFIG" 2>/dev/null; then
sed -i "s|^${key}=.*|${key}=${value}|" "$CONFIG"
else
echo "${key}=${value}" >> "$CONFIG"
fi
}
# 从配置文件删除指定键
cfg_del() {
local key="$1"
sed -i "/^${key}=/d" "$CONFIG" 2>/dev/null || true
}
# 确保必须的配置项存在,否则报错退出
require_cfg() {
local key="$1"
local val
val=$(cfg_get "$key")
if [ -z "$val" ]; then
echo "❌ 缺少配置项 ${key},请先运行: bash scripts/common/dt_helper.sh --set ${key}=<值>" >&2
exit 1
fi
echo "$val"
}
# ─────────────────────────────────────────────────────────────────────────────
# Token 管理
# ─────────────────────────────────────────────────────────────────────────────
cmd_token() {
local force="${1:-}" app_key app_secret cached expiry now resp token expire_in
app_key=$(require_cfg DINGTALK_APP_KEY)
app_secret=$(require_cfg DINGTALK_APP_SECRET)
now=$(date +%s)
if [ "$force" != "--nocache" ]; then
cached=$(cfg_get DINGTALK_ACCESS_TOKEN)
expiry=$(cfg_get DINGTALK_TOKEN_EXPIRY)
if [ -n "$cached" ] && [ -n "$expiry" ] && [ "$now" -lt "$expiry" ]; then
echo "$cached"
return 0
fi
fi
# 过期或无缓存,重新获取
resp=$(curl -s -X POST "https://api.dingtalk.com/v1.0/oauth2/accessToken" \
-H "Content-Type: application/json" \
-d "{\"appKey\":\"${app_key}\",\"appSecret\":\"${app_secret}\"}")
token=$(echo "$resp" | grep -o '"accessToken":"[^"]*"' | cut -d'"' -f4)
expire_in=$(echo "$resp" | grep -o '"expireIn":[0-9]*' | cut -d: -f2)
if [ -z "$token" ]; then
echo "❌ 获取 token 失败: $resp" >&2
exit 1
fi
cfg_set DINGTALK_ACCESS_TOKEN "$token"
cfg_set DINGTALK_TOKEN_EXPIRY "$((now + expire_in - 200))"
echo "$token"
}
cmd_token_info() {
local cached expiry now remaining
cached=$(cfg_get DINGTALK_ACCESS_TOKEN)
expiry=$(cfg_get DINGTALK_TOKEN_EXPIRY)
now=$(date +%s)
if [ -z "$cached" ]; then
echo "状态: 无缓存(从未获取或已清除)"
return 0
fi
if [ -z "$expiry" ] || [ "$now" -ge "$expiry" ]; then
echo "状态: 已过期"
echo "Token: ${cached:0:20}..."
else
remaining=$((expiry - now))
echo "状态: 有效"
echo "Token: ${cached:0:20}..."
echo "剩余: ${remaining} 秒(约 $((remaining / 60)) 分钟)"
fi
}
cmd_clear_token() {
cfg_del DINGTALK_ACCESS_TOKEN
cfg_del DINGTALK_TOKEN_EXPIRY
echo "✅ 新版 Token 缓存已清除"
}
cmd_old_token() {
# 旧版 access_token,用于所有 oapi.dingtalk.com 接口:
# - 群消息、工作通知、互动卡片(dingtalk-message)
# - userId ↔ unionId 转换
# ⚠️ 不可用于 api.dingtalk.com 接口(待办、文档、AI表格等)
local force="${1:-}" app_key app_secret resp token cached expiry now
app_key=$(require_cfg DINGTALK_APP_KEY)
app_secret=$(require_cfg DINGTALK_APP_SECRET)
now=$(date +%s)
if [ "$force" != "--nocache" ]; then
cached=$(cfg_get DINGTALK_OLD_TOKEN)
expiry=$(cfg_get DINGTALK_OLD_TOKEN_EXPIRY)
if [ -n "$cached" ] && [ -n "$expiry" ] && [ "$now" -lt "$expiry" ]; then
echo "$cached"
return 0
fi
fi
resp=$(curl -s "https://oapi.dingtalk.com/gettoken?appkey=${app_key}&appsecret=${app_secret}")
token=$(echo "$resp" | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4)
expires_in=$(echo "$resp" | grep -o '"expires_in":[0-9]*' | cut -d: -f2)
if [ -z "$token" ]; then
echo "❌ 获取旧版 token 失败: $resp" >&2
exit 1
fi
cfg_set DINGTALK_OLD_TOKEN "$token"
cfg_set DINGTALK_OLD_TOKEN_EXPIRY "$((now + expires_in - 200))"
echo "$token"
}
# ─────────────────────────────────────────────────────────────────────────────
# 身份转换
# ─────────────────────────────────────────────────────────────────────────────
cmd_to_unionid() {
local user_id="$1"
local is_self=false
local old_token resp union_id
# 未传参 → 使用配置中的操作者自身 userId,转换结果写入配置
if [ -z "$user_id" ]; then
user_id=$(require_cfg DINGTALK_MY_USER_ID)
is_self=true
fi
old_token=$(cmd_old_token)
resp=$(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}\"}")
# 注意:使用无下划线的 unionid 字段(有下划线的 union_id 可能为空)
union_id=$(echo "$resp" | grep -o '"unionid":"[^"]*"' | head -1 | cut -d'"' -f4)
if [ -z "$union_id" ]; then
echo "❌ userId→unionId 转换失败: $resp" >&2
exit 1
fi
# 仅当转换的是操作者自身时,才写入配置(动态转换他人 userId 不写入)
if "$is_self" && [ -z "$(cfg_get DINGTALK_MY_OPERATOR_ID)" ]; then
cfg_set DINGTALK_MY_OPERATOR_ID "$union_id"
echo "✅ 自身 unionId 已写入配置 DINGTALK_MY_OPERATOR_ID" >&2
fi
echo "$union_id"
}
cmd_to_userid() {
local union_id="$1"
local old_token resp user_id
if [ -z "$union_id" ]; then
echo "❌ 请提供 unionId 参数" >&2
exit 1
fi
old_token=$(cmd_old_token)
resp=$(curl -s -X POST \
"https://oapi.dingtalk.com/topapi/user/getbyunionid?access_token=${old_token}" \
-H "Content-Type: application/json" \
-d "{\"unionid\":\"${union_id}\"}")
user_id=$(echo "$resp" | grep -o '"userid":"[^"]*"' | head -1 | cut -d'"' -f4)
if [ -z "$user_id" ]; then
echo "❌ unionId→userId 转换失败: $resp" >&2
exit 1
fi
echo "$user_id"
}
# ─────────────────────────────────────────────────────────────────────────────
# 配置管理
# ─────────────────────────────────────────────────────────────────────────────
cmd_config() {
if [ ! -f "$CONFIG" ]; then
echo "配置文件不存在: $CONFIG"
echo "使用 --set KEY=VALUE 写入配置项"
return 0
fi
echo "配置文件: $CONFIG"
echo "─────────────────────────────────"
# 脱敏显示 SECRET 和 TOKEN
while IFS= read -r line; do
key="${line%%=*}"
val="${line#*=}"
case "$key" in
DINGTALK_APP_SECRET|DINGTALK_ACCESS_TOKEN|DINGTALK_OLD_TOKEN)
echo "${key}=${val:0:6}***(已脱敏)"
;;
*)
echo "$line"
;;
esac
done < "$CONFIG"
}
cmd_get() {
if [ $# -eq 0 ]; then
echo "❌ 请提供至少一个键名,用法: --get KEY [KEY2 ...]" >&2
exit 1
fi
for key in "$@"; do
val=$(cfg_get "$key")
if [ -z "$val" ]; then
echo "${key}=(未设置)"
else
case "$key" in
DINGTALK_APP_SECRET|DINGTALK_ACCESS_TOKEN|DINGTALK_OLD_TOKEN)
echo "${key}=${val:0:6}***(脱敏)"
;;
*)
echo "${key}=${val}"
;;
esac
fi
done
}
cmd_set() {
local kv="$1"
if [ -z "$kv" ] || [[ "$kv" != *"="* ]]; then
echo "❌ 格式错误,用法: --set KEY=VALUE" >&2
exit 1
fi
local key="${kv%%=*}"
local value="${kv#*=}"
cfg_set "$key" "$value"
echo "✅ 已设置 ${key}"
}
# ─────────────────────────────────────────────────────────────────────────────
# 入口:解析命令
# ─────────────────────────────────────────────────────────────────────────────
CMD="${1:-}"
case "$CMD" in
--help|-h|"")
show_help
;;
--token)
cmd_token "${2:-}"
;;
--token-info)
cmd_token_info
;;
--clear-token)
cmd_clear_token
;;
--old-token)
cmd_old_token "${2:-}"
;;
--to-unionid)
cmd_to_unionid "${2:-}"
;;
--to-userid)
cmd_to_userid "${2:-}"
;;
--config)
cmd_config
;;
--get)
shift
cmd_get "$@"
;;
--set)
cmd_set "${2:-}"
;;
*)
echo "❌ 未知命令: $CMD" >&2
echo "运行 --help 查看用法" >&2
exit 1
;;
esac
Related skills
FAQ
What does dingtalk-contact integrate?
dingtalk-contact integrates Claude agents with DingTalk contact APIs for enterprise directory lookup, contact synchronization, and messaging workflows inside SaaS or internal tooling projects.
Who needs dingtalk-contact?
dingtalk-contact suits developers building enterprise applications that must read, sync, or message DingTalk organizational contacts through agent-driven API workflows.