钉钉文件发送

SKILL开发

原名 dingtalk-file-send

开发 接触敏感数据 许可证明确 OpenClaw
安装这个技能

dingtalk-file-send 用于整理文档、README、Markdown 和说明材料,适合在 OpenClaw 中需要把零散信息整理成结构清晰的文档时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

累计安装 5,791 本周 232
GitHub 星标 1 仓库 dingtalk-file-send
下载量 1,875 技能市场下载数
权限级别 接触敏感数据 安装前请确认风险范围
许可证 许可证明确 MIT-0

安装

ClawHub 市场
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
openclaw skills install dingtalk-file-send

技能档案

开发
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方kenriou仓库 dingtalk-file-send · 版本 1.2.2
宿主客户端OpenClaw技能可被这些客户端加载
安装方式ClawHub 市场安装包 kenriou/dingtalk-file-send
权限级别接触敏感数据安装前请确认风险范围
许可证MIT-0许可证明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验2026-05-01上游最后核验时间 · 数据更新 未标注
正文体量10.0 KBSKILL.md 原文大小,越大说明说明书写得越细

能做什么

5 项能力
上游给出的能力概览与适用场景
  • 按任务关键词查找相关 Skills
  • 展示可复制的安装命令
  • 保留来源站点、仓库和原始说明,方便继续核验
  • 补充不同宿主或平台的使用分布数据
  • 展示第三方安全扫描或审计结果
OpenClaw 用户查找和安装 Skill 时用户想查找某类 Agent Skill 时需要根据任务场景推荐可安装能力包时需要对比不同来源的安装命令和来源信息时

权限与风险

接触敏感数据
装之前先读完这段

安装与使用指南

安装步骤

本站只展示命令,不托管安装包,也不自动执行。

怎么用

安装后应在对应宿主中按原始 README 的触发条件使用;当前草稿只做目录说明,具体调用方式由规则抽取,异常条目再复核。

SKILL.md 全文

10.0 KB
模型实际读到的说明书原文,来自技能仓库

DingTalk File Send Skill

Upload files to DingTalk media server and send them to specified users.

Automatically detects DingTalk account from current session binding.

When to Use

✅ USE this skill when:

  • "Send this PDF to [user]"
  • "Forward this document via DingTalk"
  • "Share this file with my boss"
  • "Upload and send [filename]"

Configuration (Automatic)

This skill automatically detects the DingTalk account from your current session:

How it works:
1. Reads current agent ID from OpenClaw runtime context
2. Looks up the binding in ~/.openclaw/openclaw.json
3. Matches agentId → accountId → DingTalk credentials

Binding example:

{
  "bindings": [
    {
      "agentId": "dingtalk-office",
      "match": {
        "channel": "dingtalk",
        "accountId": "office"
      }
    }
  ],
  "channels": {
    "dingtalk": {
      "accounts": {
        "office": {
          "clientId": "your_client_id",
          "clientSecret": "xxx",
          "robotCode": "your_robot_code"
        }
      }
    }
  }
}

Note: In DingTalk's API, clientId is used as appKey for authentication.

Workflow

1. Detect current agentId from session context
2. Look up binding: agentId → accountId
3. Read credentials from OpenClaw config by accountId
4. Get access token
5. Upload file to DingTalk media server
6. Send file message to recipient

Commands

Step 1: Detect Account from Current Session

OPENCLAW_CONFIG=~/.openclaw/openclaw.json

# Get current agent ID from environment (set by OpenClaw runtime)
AGENT_ID="${OPENCLAW_AGENT_ID:-dingtalk-office}"

# Look up accountId from bindings
ACCOUNT_ID=$(jq -r ".bindings[] | select(.agentId == \"$AGENT_ID\") | .match.accountId" $OPENCLAW_CONFIG)

# Fallback: if no binding found, use agent ID suffix
if [ -z "$ACCOUNT_ID" ] || [ "$ACCOUNT_ID" = "null" ]; then
  # Extract account from agent ID (e.g., "dingtalk-office" → "office")
  ACCOUNT_ID=$(echo "$AGENT_ID" | sed 's/dingtalk-//')
fi

# Read credentials (clientId is used as appKey)
APP_KEY=$(jq -r ".channels.dingtalk.accounts[\"$ACCOUNT_ID\"].clientId" $OPENCLAW_CONFIG)
APP_SECRET=$(jq -r ".channels.dingtalk.accounts[\"$ACCOUNT_ID\"].clientSecret" $OPENCLAW_CONFIG)
ROBOT_CODE=$(jq -r ".channels.dingtalk.accounts[\"$ACCOUNT_ID\"].robotCode" $OPENCLAW_CONFIG)

# Validate
if [ "$APP_KEY" = "null" ] || [ "$APP_SECRET" = "null" ] || [ "$ROBOT_CODE" = "null" ]; then
  echo "❌ Account '$ACCOUNT_ID' not found in OpenClaw config."
  echo "Current agent: $AGENT_ID"
  echo "Available accounts: $(jq -r '.channels.dingtalk.accounts | keys | join(", ")' $OPENCLAW_CONFIG)"
  exit 1
fi

Step 2: Get Access Token

ACCESS_TOKEN=$(curl -s -X POST "https://api.dingtalk.com/v1.0/oauth2/accessToken" \
  -H "Content-Type: application/json" \
  -d "{\"appKey\":\"$APP_KEY\",\"appSecret\":\"$APP_SECRET\"}" | jq -r '.accessToken')

if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
  echo "❌ Failed to get access token."
  exit 1
fi

Step 3: Upload File

FILE_PATH="$1"
FILE_NAME=$(basename "$FILE_PATH")

UPLOAD_RESULT=$(curl -s -X POST "https://oapi.dingtalk.com/media/upload?access_token=$ACCESS_TOKEN&type=file&robotCode=$ROBOT_CODE" \
  -F "media=@$FILE_PATH;filename=$FILE_NAME" \
  -H "Expect:")

MEDIA_ID=$(echo "$UPLOAD_RESULT" | jq -r '.media_id')

if [ -z "$MEDIA_ID" ] || [ "$MEDIA_ID" = "null" ]; then
  echo "❌ Upload failed: $UPLOAD_RESULT"
  exit 1
fi

Step 4: Send File Message

USER_ID="$2"
FILE_EXT="${FILE_NAME##*.}"

PAYLOAD=$(jq -n \
  --arg robotCode "$ROBOT_CODE" \
  --arg msgKey "sampleFile" \
  --arg mediaId "$MEDIA_ID" \
  --arg fileName "$FILE_NAME" \
  --arg fileType "$FILE_EXT" \
  --arg userId "$USER_ID" \
  '{
    robotCode: $robotCode,
    msgKey: $msgKey,
    msgParam: ({
      mediaId: $mediaId,
      fileName: $fileName,
      fileType: $fileType
    } | tojson),
    userIds: [$userId]
  }')

SEND_RESULT=$(curl -s -X POST "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend" \
  -H "Content-Type: application/json" \
  -H "x-acs-dingtalk-access-token: $ACCESS_TOKEN" \
  -d "$PAYLOAD")

PROCESS_KEY=$(echo "$SEND_RESULT" | jq -r '.processQueryKey // empty')

if [ -n "$PROCESS_KEY" ]; then
  echo "✅ File sent successfully!"
  echo "ProcessQueryKey: $PROCESS_KEY"
else
  echo "❌ Send failed: $SEND_RESULT"
  exit 1
fi

Complete Script

#!/bin/bash
# Usage: send_dingtalk_file.sh <file_path> <user_id>
# Automatically detects DingTalk account from current session

set -e

OPENCLAW_CONFIG=~/.openclaw/openclaw.json

# Check config file
if [ ! -f "$OPENCLAW_CONFIG" ]; then
  echo "❌ OpenClaw config not found: $OPENCLAW_CONFIG"
  exit 1
fi

# Check file argument
FILE_PATH="$1"
USER_ID="$2"

if [ -z "$FILE_PATH" ] || [ -z "$USER_ID" ]; then
  echo "Usage: $0 <file_path> <user_id>"
  exit 1
fi

if [ ! -f "$FILE_PATH" ]; then
  echo "❌ File not found: $FILE_PATH"
  exit 1
fi

# Get current agent ID from environment (set by OpenClaw runtime)
AGENT_ID="${OPENCLAW_AGENT_ID:-dingtalk-office}"

# Look up accountId from bindings
ACCOUNT_ID=$(jq -r ".bindings[] | select(.agentId == \"$AGENT_ID\") | .match.accountId" $OPENCLAW_CONFIG)

# Fallback: if no binding found, use agent ID suffix
if [ -z "$ACCOUNT_ID" ] || [ "$ACCOUNT_ID" = "null" ]; then
  ACCOUNT_ID=$(echo "$AGENT_ID" | sed 's/dingtalk-//')
fi

# Read credentials from OpenClaw config
APP_KEY=$(jq -r ".channels.dingtalk.accounts[\"$ACCOUNT_ID\"].clientId" $OPENCLAW_CONFIG)
APP_SECRET=$(jq -r ".channels.dingtalk.accounts[\"$ACCOUNT_ID\"].clientSecret" $OPENCLAW_CONFIG)
ROBOT_CODE=$(jq -r ".channels.dingtalk.accounts[\"$ACCOUNT_ID\"].robotCode" $OPENCLAW_CONFIG)

# Validate credentials
if [ "$APP_KEY" = "null" ] || [ "$APP_SECRET" = "null" ] || [ "$ROBOT_CODE" = "null" ]; then
  echo "❌ Account '$ACCOUNT_ID' not found in OpenClaw config."
  echo "Current agent: $AGENT_ID"
  echo "Available accounts: $(jq -r '.channels.dingtalk.accounts | keys | join(", ")' $OPENCLAW_CONFIG)"
  exit 1
fi

FILE_NAME=$(basename "$FILE_PATH")
FILE_EXT="${FILE_NAME##*.}"

# Get access token
ACCESS_TOKEN=$(curl -s -X POST "https://api.dingtalk.com/v1.0/oauth2/accessToken" \
  -H "Content-Type: application/json" \
  -d "{\"appKey\":\"$APP_KEY\",\"appSecret\":\"$APP_SECRET\"}" | jq -r '.accessToken')

if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
  echo "❌ Failed to get access token."
  exit 1
fi

# Upload file
UPLOAD_RESULT=$(curl -s -X POST "https://oapi.dingtalk.com/media/upload?access_token=$ACCESS_TOKEN&type=file&robotCode=$ROBOT_CODE" \
  -F "media=@$FILE_PATH;filename=$FILE_NAME" \
  -H "Expect:")

MEDIA_ID=$(echo "$UPLOAD_RESULT" | jq -r '.media_id')

if [ -z "$MEDIA_ID" ] || [ "$MEDIA_ID" = "null" ]; then
  echo "❌ Upload failed: $UPLOAD_RESULT"
  exit 1
fi

# Send file
PAYLOAD=$(jq -n \
  --arg robotCode "$ROBOT_CODE" \
  --arg msgKey "sampleFile" \
  --arg mediaId "$MEDIA_ID" \
  --arg fileName "$FILE_NAME" \
  --arg fileType "$FILE_EXT" \
  --arg userId "$USER_ID" \
  '{robotCode:$robotCode,msgKey:$msgKey,msgParam:({mediaId:$mediaId,fileName:$fileName,fileType:$fileType}|tojson),userIds:[$userId]}')

SEND_RESULT=$(curl -s -X POST "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend" \
  -H "Content-Type: application/json" \
  -H "x-acs-dingtalk-access-token: $ACCESS_TOKEN" \
  -d "$PAYLOAD")

PROCESS_KEY=$(echo "$SEND_RESULT" | jq -r '.processQueryKey // empty')

if [ -n "$PROCESS_KEY" ]; then
  echo "✅ File sent successfully!"
  echo "ProcessQueryKey: $PROCESS_KEY"
else
  echo "❌ Send failed: $SEND_RESULT"
  exit 1
fi

Supported File Types

Type Extensions Max Size
PDF .pdf 20 MB
Document .doc, .docx, .xls, .xlsx, .ppt, .pptx 20 MB
Image .jpg, .jpeg, .png, .gif, .bmp 10 MB
Other .txt, .zip, .rar 20 MB

Environment Variables

Variable Description Required
OPENCLAW_AGENT_ID Current agent ID (auto-set by OpenClaw runtime) Auto

Response Handling

Success response:

{
  "flowControlledStaffIdList": [],
  "invalidStaffIdList": [],
  "processQueryKey": "xxx="
}

Check delivery status:

curl -s -X GET "https://api.dingtalk.com/v1.0/robot/oToMessages/status?processQueryKey=$PROCESS_KEY" \
  -H "x-acs-dingtalk-access-token: $ACCESS_TOKEN"

Notes

  • Fully automatic — detects account from current session, no configuration needed
  • Media files expire after 30 days on DingTalk server
  • Max file size: 20 MB for files, 10 MB for images
  • Access token expires after 2 hours
  • Rate limit: ~100 requests/second per app
  • Works with any DingTalk account bound in OpenClaw config

Common Issues

"Account not found in OpenClaw config"
→ Check bindings: jq '.bindings[] | select(.agentId == "current-agent-id")' ~/.openclaw/openclaw.json
→ Verify account exists: jq '.channels.dingtalk.accounts | keys' ~/.openclaw/openclaw.json

"Failed to get access token"
→ Verify clientId/clientSecret in OpenClaw config are correct and not expired.

"Invalid media_id"
→ File upload failed or expired. Re-upload and get new media_id.

"Invalid userId"
→ Check the recipient's DingTalk user ID format.

File shows but can't open
→ Ensure file is valid (not HTML renamed to .pdf, etc.)

Security Notes

  • No hardcoded credentials — reads from OpenClaw config only
  • Session-based account detection — uses current agent's bound account
  • Access token is generated on-demand and not stored
  • Credentials never leave your machine except for DingTalk API calls

安全信息

审计结论
未标注不代表已通过审计
安全审计VirusTotal、ClawScan、Static analysis第三方安全审计平台给出的结论

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 2026-05-01。