← 返回 Skills 市场
kenriou

Dingtalk File Send

作者 kenriou · GitHub ↗ · v1.2.2 · MIT-0
cross-platform ✓ 安全检测通过
188
总下载
1
收藏
0
当前安装
5
版本数
在 OpenClaw 中安装
/install dingtalk-file-send
功能描述
Upload and send files to DingTalk users. Auto-detects account from current session. Use when: user asks to send/forward a file/document/PDF/image via DingTalk.
使用说明 (SKILL.md)

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 agentIdaccountId → 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 \x3Cfile_path> \x3Cuser_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 \x3Cfile_path> \x3Cuser_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
安全使用建议
This skill appears to do what it says: it reads your OpenClaw config (~/.openclaw/openclaw.json) to obtain DingTalk credentials, gets an access token, uploads the file, and sends it. Before installing or running it, verify the skill source (unknown here), inspect the SKILL.md yourself, and confirm the config file only contains accounts you expect. Treat the clientSecret/robotCode as sensitive: only use this skill if you trust it and consider testing in an isolated account or environment first. Also ensure curl/jq on your system are the real binaries (not replaced by malicious wrappers). If you lose confidence in the skill or its origin, rotate the DingTalk credentials referenced in your OpenClaw config.
能力评估
Purpose & Capability
Name and description describe sending files via DingTalk; the SKILL.md only requires curl/jq and access to the OpenClaw config to obtain DingTalk credentials and tokens, which is coherent with that purpose.
Instruction Scope
Instructions explicitly read ~/.openclaw/openclaw.json to extract clientId/clientSecret/robotCode and the optional OPENCLAW_AGENT_ID from environment, then call DingTalk APIs to upload and send files — all actions stay within the declared task but do involve reading local credentials.
Install Mechanism
Instruction-only skill with no install spec and no code files; it requires only common CLI tools (curl and jq) that are expected for the provided shell examples.
Credentials
Access to clientId/clientSecret/robotCode in the OpenClaw config is necessary to obtain an access token and is proportionate to the task; however the registry metadata lists no required env vars while the SKILL.md reads OPENCLAW_AGENT_ID (optional) and the local config, a minor metadata mismatch and a sensitive operation (reads secrets).
Persistence & Privilege
Skill does not request always:true, does not modify other skills, and does not install persistent components; autonomous invocation is allowed (platform default) but not elevated by the skill itself.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install dingtalk-file-send
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /dingtalk-file-send 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.2.2
Fix: Add config and env access declarations to metadata
v1.2.1
Fix: Replace example credentials with placeholders
v1.2.0
**Now auto-detects DingTalk account from OpenClaw session instead of requiring a separate config file.** - Automatically selects the correct DingTalk credentials by mapping the current agent/session to account profile in `~/.openclaw/openclaw.json`. - Removed manual config file setup; uses OpenClaw’s session and credentials for a more seamless experience. - Example bindings and config layout for multi-account support are documented. - All scripts updated to fetch credentials and robot code dynamically from OpenClaw runtime context. - Error messages guide users if account lookup or credential detection fails.
v1.1.0
**Now reads API credentials from a config file instead of inline.** - Requires a config file at `~/.clawhub/dingtalk-config.json` with `appKey`, `appSecret`, and `robotCode`. - All example scripts updated to load credentials from the config file. - Additional security instructions and file validation added. - Improved documentation on permissions, usage, and file validation steps. - Warns if the config file is missing or misconfigured.
v1.0.0
Initial release of the dingtalk-file-send skill. - Upload and send files (PDFs, documents, images, etc.) directly to DingTalk users via robot API. - Requires DingTalk robot credentials (appKey, appSecret, robotCode) and recipient userId. - Supports easy bash workflow: obtain access token, upload file, and send message. - Includes usage guide, troubleshooting, file type and size limits. - Provides complete example script for automated sending.
元数据
Slug dingtalk-file-send
版本 1.2.2
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 5
常见问题

Dingtalk File Send 是什么?

Upload and send files to DingTalk users. Auto-detects account from current session. Use when: user asks to send/forward a file/document/PDF/image via DingTalk. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 188 次。

如何安装 Dingtalk File Send?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install dingtalk-file-send」即可一键安装,无需额外配置。

Dingtalk File Send 是免费的吗?

是的,Dingtalk File Send 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

Dingtalk File Send 支持哪些平台?

Dingtalk File Send 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Dingtalk File Send?

由 kenriou(@kenriou)开发并维护,当前版本 v1.2.2。

💬 留言讨论