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

210 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: lark-send-message-as-bot
description: |
以 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
**所有发送操作前必须先获取 token**token 有效期 2 小时,同一批操作复用即可:
```bash
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_id``receive_id` 填 user_id`4aagb443`
```bash
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_id``receive_id` 填群 ID`oc_xxx`
```bash
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再发送文件消息**。
### 步骤一:上传文件
```bash
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**
```bash
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**
```bash
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 报表到群组
```bash
#!/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 是否匹配 |
---
## 安全规则
- 发送前必须确认用户意图,禁止未经确认自动发送
- 禁止在终端明文输出 `appSecret``accessToken`
- `<agent_name>` 根据当前 agent 身份确定,参考上方凭证目录表