lark-send-message-as-bot.vala/SKILL.md

7.0 KiB
Raw Permalink Blame History

name description
lark-send-message-as-bot 以 Bot 身份通过飞书发送消息和文件。支持两种目标: (1) 给个人用户发私聊消息(基于 user_id[注意] ./vala_users_list.md中已经记录了vala全员的user_id请首先查询这个文档 (2) 给群组发消息(基于 chat_id 当 agent 需要主动推送消息、通知用户、向群组发送信息时使用。 触发场景发消息、通知某人、推送到群、Bot 发消息、主动消息、发文件、发报表。

以 Bot 身份发送飞书消息和文件

前置条件

  • Bot 应用的凭证已配置在 /root/.openclaw/credentials/<agent_name>/config.json
  • 目标用户必须在 Bot 应用的可用范围内(开发者后台配置)
  • 目标群必须已将 Bot 添加为群成员

Agent 凭证目录

Agent 凭证路径
xiaoxi /root/.openclaw/credentials/xiaoxi/config.json
xiaoban /root/.openclaw/credentials/xiaoban/config.json
xiaobian /root/.openclaw/credentials/xiaobian/config.json
xiaokui /root/.openclaw/credentials/xiaokui/config.json
xiaoyan /root/.openclaw/credentials/xiaoyan/config.json

第一步:获取 tenant_access_token

所有发送操作前必须先获取 tokentoken 有效期 2 小时,同一批操作复用即可:

APP_ID=$(jq -r '.apps[0].appId' /root/.openclaw/credentials/<agent_name>/config.json)
APP_SECRET=$(jq -r '.apps[0].appSecret' /root/.openclaw/credentials/<agent_name>/config.json)

TOKEN=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d "{\"app_id\":\"$APP_ID\",\"app_secret\":\"$APP_SECRET\"}" \
  | jq -r '.tenant_access_token')

⚠️<agent_name> 替换为当前 agent 名称xiaoxi / xiaoban / xiaokui 等)


发送文本消息

给个人发消息user_id

使用 receive_id_type=user_idreceive_id 填 user_id4aagb443

curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "receive_id": "<user_id>",
    "msg_type": "text",
    "content": "{\"text\":\"消息内容\"}"
  }'

📋 user_id 查询:首先查阅 ./vala_users_list.md 获取对应的 user_id

给群组发消息chat_id

使用 receive_id_type=chat_idreceive_id 填群 IDoc_xxx

curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "receive_id": "<chat_id>",
    "msg_type": "text",
    "content": "{\"text\":\"消息内容\"}"
  }'

发送文件

文件发送分两步:先上传文件获取 file_key再发送文件消息

步骤一:上传文件

UPLOAD_RESP=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/files" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file_type=<类型>" \
  -F "file_name=<显示文件名>" \
  -F "file=@<本地文件路径>")

FILE_KEY=$(echo "$UPLOAD_RESP" | jq -r '.data.file_key')

file_type 对照表:

file_type 适用文件
xls Excel 文件(.xlsx / .xls
pdf PDF 文件
doc Word 文档(.docx / .doc
ppt PPT 演示文稿(.pptx / .ppt
stream 其他任意格式文件(通用)

⚠️ file_name 是飞书消息中展示的文件名,可以是中文(如 每周报表.xlsx),会自动 URL 编码

步骤二:发送文件消息

发送给个人user_id

curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"receive_id\":\"<user_id>\",\"msg_type\":\"file\",\"content\":\"{\\\"file_key\\\":\\\"${FILE_KEY}\\\"}\"}"

发送给群组chat_id

curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"receive_id\":\"<chat_id>\",\"msg_type\":\"file\",\"content\":\"{\\\"file_key\\\":\\\"${FILE_KEY}\\\"}\"}"

完整示例:发送 Excel 报表到群组

#!/bin/bash
# 获取token
APP_ID=$(jq -r '.apps[0].appId' /root/.openclaw/credentials/<agent_name>/config.json)
APP_SECRET=$(jq -r '.apps[0].appSecret' /root/.openclaw/credentials/<agent_name>/config.json)
TOKEN=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d "{\"app_id\":\"$APP_ID\",\"app_secret\":\"$APP_SECRET\"}" \
  | jq -r '.tenant_access_token')

# 上传Excel
FILE_KEY=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/files" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file_type=xls" \
  -F "file_name=每周报表.xlsx" \
  -F "file=@/tmp/report.xlsx" | jq -r '.data.file_key')

if [ -z "$FILE_KEY" ] || [ "$FILE_KEY" = "null" ]; then
    echo "ERROR: 文件上传失败"
    exit 1
fi

# 发送到群组
SEND_RESP=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"receive_id\":\"oc_xxx\",\"msg_type\":\"file\",\"content\":\"{\\\"file_key\\\":\\\"${FILE_KEY}\\\"}\"}")

MSG_ID=$(echo "$SEND_RESP" | jq -r '.data.message_id')
if [ -z "$MSG_ID" ] || [ "$MSG_ID" = "null" ]; then
    echo "ERROR: 消息发送失败: $(echo $SEND_RESP | jq -r '.msg')"
    exit 1
fi
echo "发送成功: $MSG_ID"

消息类型参考

msg_type content 格式 用途
text {"text":"纯文本"} 普通文本消息
file {"file_key":"file_v3_xxx"} 文件消息(需先上传)
post {"zh_cn":{"title":"标题","content":[[{"tag":"text","text":"正文"}]]}} 富文本(支持@、链接、图片)
interactive 卡片 JSON 消息卡片

ID 类型说明

ID 类型 格式 用途 获取方式
user_id 4aagb443 给个人发消息 查阅 ./vala_users_list.md
chat_id oc_xxx 给群组发消息 lark-cli im chats list

重要: 使用 user_id(租户级唯一标识),不要使用 open_id(应用级标识,不同 Bot 看到的同一用户 open_id 不同)。


常见错误

错误码 含义 解决方式
230013 Bot 没有该用户的可用范围权限 在开发者后台将用户加入应用的可用范围
230001 Bot 不在目标群中 将 Bot 添加到目标群
99992351 无效的 ID 格式 检查 receive_id_type 与 receive_id 是否匹配

安全规则

  • 发送前必须确认用户意图,禁止未经确认自动发送
  • 禁止在终端明文输出 appSecretaccessToken
  • <agent_name> 根据当前 agent 身份确定,参考上方凭证目录表