--- name: feishu-lark description: > 飞书 Lark 官方 CLI 封装。支持消息发送、文档操作、 日历管理、云盘文件、联系人查询等核心功能。 基于 larksuite/cli 工具,适配 Android/Termux 环境。 category: productivity tags: [feishu, lark, messaging, productivity, cli] author: Hermes Agent version: 1.0.0 requires: [lark-cli] --- # Feishu/Lark Skill 飞书官方 CLI 工具的封装,适配 Android/Termux 环境。 ## 前置要求 1. 安装 lark-cli: ```bash curl -L -o /tmp/lark-cli.tar.gz "https://github.com/larksuite/cli/releases/download/v1.0.57/lark-cli-1.0.57-linux-arm64.tar.gz" tar -xzf /tmp/lark-cli.tar.gz -C /data/data/com.termux/files/usr/bin/ chmod +x /data/data/com.termux/files/usr/bin/lark ``` 2. 配置环境变量(~/.hermes/.env): ``` FEISHU_APP_ID=cli_a91b01debab81cd1 FEISHU_APP_SECRET=your_app_secret_here ``` 3. 绑定应用: ```bash lark config bind --source hermes --app-id cli_a91b01debab81cd1 --identity user-default --force ``` ## 认证方式 由于 Android/Termux DNS 限制,使用 tenant_access_token 方式: ```bash # 获取 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":"cli_a91b01debab81cd1","app_secret":"your_secret"}' ``` ## 核心功能 ### 1. 消息管理 (IM) #### 发送文本消息到群聊 ```bash lark im message create \ --receive_id_type chat_id \ --receive_id "oc_xxxxxx" \ --msg_type text \ --content '{"text":"消息内容"}' ``` #### 发送富文本消息 ```bash lark im message create \ --receive_id_type chat_id \ --receive_id "oc_xxxxxx" \ --msg_type post \ --content '{"zh_cn":{"title":"标题","content":[[{"tag":"text","text":"内容"}]]}}' ``` #### 获取群聊列表 ```bash lark im chat list ``` #### 获取群成员 ```bash lark im chat member list --chat_id "oc_xxxxxx" ``` ### 2. 文档管理 (Docs) #### 创建文档 ```bash lark docs create --title "文档标题" --content "文档内容" ``` #### 获取文档内容 ```bash lark docs content get --document_id "doccnxxxxxx" ``` #### 列出文档 ```bash lark docs list ``` ### 3. 日历管理 (Calendar) #### 获取日历列表 ```bash lark api GET /open-apis/calendar/v4/calendars ``` #### 创建事件 ```bash lark calendar event create \ --calendar_id "primary" \ --summary "会议标题" \ --start_time "2026-06-25T10:00:00+08:00" \ --end_time "2026-06-25T11:00:00+08:00" ``` ### 4. 云盘管理 (Drive) #### 上传文件 ```bash lark drive file upload --file_path "/path/to/file" --parent_node "folder_token" ``` #### 列出文件 ```bash lark drive file list --parent_node "folder_token" ``` ### 5. 联系人管理 (Contact) #### 搜索用户 ```bash lark contact user search --query "用户名" ``` #### 获取用户信息 ```bash lark contact user get --user_id "ou_xxxxxx" ``` ### 6. 多维表格 (Base) #### 列出表格 ```bash lark base app list ``` #### 获取记录 ```bash lark base record list --app_token "bas_xxxxxx" --table_id "tbl_xxxxxx" ``` ## 常用 API 调用 ### 通用 API 调用方式 ```bash lark api GET [--params ''] lark api POST [--data ''] lark api PUT [--data ''] lark api DELETE ``` ### 示例:获取用户信息 ```bash lark api GET /open-apis/contact/v3/users/ou_xxxxxx ``` ### 示例:发送消息(注意 content 格式) ```bash # ❌ 错误:content 不是 JSON 字符串 lark api POST /open-apis/im/v1/messages \ --data '{ "receive_id": "oc_xxxxxx", "msg_type": "text", "content": {"text": "Hello"} # 错误! }' # ✅ 正确:content 必须是 JSON 字符串 lark api POST /open-apis/im/v1/messages \ --data '{ "receive_id": "oc_xxxxxx", "msg_type": "text", "content": "{\"text\":\"Hello\"}" # 正确! }' ``` **Python 辅助脚本**(处理 JSON 转义): ```python import json import urllib.request APP_ID = "cli_a91b01debab81cd1" APP_SECRET = "your_secret" # 获取 token token_data = json.dumps({"app_id": APP_ID, "app_secret": APP_SECRET}).encode('utf-8') token_req = urllib.request.Request( 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', data=token_data, headers={'Content-Type': 'application/json'}, method='POST' ) with urllib.request.urlopen(token_req, timeout=30) as response: token_result = json.loads(response.read().decode('utf-8')) TOKEN = token_result['tenant_access_token'] # 发送消息(content 自动转义) message_data = { "receive_id": "oc_xxxxxx", "msg_type": "text", "content": json.dumps({"text": "Hello"}) # 自动转义 } msg_req = urllib.request.Request( 'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id', data=json.dumps(message_data).encode('utf-8'), headers={ 'Authorization': f'Bearer {TOKEN}', 'Content-Type': 'application/json' }, method='POST' ) with urllib.request.urlopen(msg_req, timeout=30) as response: result = json.loads(response.read().decode('utf-8')) print(result) ``` ## 实用脚本 ### 快速发送消息(Bash) ```bash #!/bin/bash # send_feishu_msg.sh CHAT_ID="$1" MESSAGE="$2" if [ -z "$CHAT_ID" ] || [ -z "$MESSAGE" ]; then echo "Usage: $0 " exit 1 fi lark im message create \ --receive_id_type chat_id \ --receive_id "$CHAT_ID" \ --msg_type text \ --content "{\"text\":\"$MESSAGE\"}" ``` ### 发送消息(Python - 推荐,自动处理 JSON 转义) ```bash # 使用内置脚本(自动处理 content 格式) python3 ~/.hermes/skills/productivity/feishu-lark/scripts/send_message.py \ oc_xxxxxx "Hello World" # 发送卡片消息 python3 ~/.hermes/skills/productivity/feishu-lark/scripts/send_message.py \ oc_xxxxxx '{"config":{"wide_screen_mode":true},"header":{"title":{"tag":"plain_text","content":"标题"},"template":"blue"},"elements":[{"tag":"div","text":{"tag":"lark_md","content":"**内容**"}}]}' \ interactive ``` **Python 脚本优势**: - 自动处理 JSON 转义(避免 9499 错误) - 自动获取 token - 支持 text/post/interactive 消息类型 - 更好的错误提示 ### 获取 Token 脚本 ```bash #!/bin/bash # get_feishu_token.sh APP_ID="${FEISHU_APP_ID}" APP_SECRET="${FEISHU_APP_SECRET}" if [ -z "$APP_ID" ] || [ -z "$APP_SECRET" ]; then echo "Error: FEISHU_APP_ID and FEISHU_APP_SECRET must be set" exit 1 fi RESPONSE=$(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\"}") TOKEN=$(echo "$RESPONSE" | grep -o '"tenant_access_token":"[^"]*"' | cut -d'"' -f4) EXPIRE=$(echo "$RESPONSE" | grep -o '"expire":[0-9]*' | cut -d':' -f2) echo "Token: $TOKEN" echo "Expire: $EXPIRE seconds" ``` ## 故障排除 ### DNS 问题 如果在 Android/Termux 遇到 DNS 解析错误: ```bash # 配置 DNS echo "nameserver 8.8.8.8 nameserver 114.114.114.114" > /data/data/com.termux/files/usr/etc/resolv.conf # 手动添加 hosts echo "198.18.0.87 accounts.feishu.cn" >> /data/data/com.termux/files/usr/etc/hosts # 或使用 IP 直接访问 API curl -H "Host: open.feishu.cn" https://198.18.0.87/open-apis/... ``` ### 认证失败 ```bash # 检查配置 lark config show # 检查认证状态 lark auth status # 重新绑定 lark config bind --source hermes --app-id cli_a91b01debab81cd1 --identity user-default --force ``` ### Gateway 配置(接收消息) **问题**: 用户 @ 机器人但无回复 **原因**: 1. Gateway 未运行 2. 用户未授权 3. 日志目录权限问题 **解决方案**: 1. **配置 Gateway 允许所有用户** (~/.hermes/.env): ``` GATEWAY_ALLOW_ALL_USERS=true ``` 2. **配置飞书平台** (config.yaml): ```yaml platforms: feishu: streaming: true app_id: cli_a91b01debab81cd1 domain: feishu allow_all_users: true ``` 3. **授权特定用户**: ```bash # 用户首次使用会收到配对码 hermes pairing approve feishu ``` 4. **修复日志目录权限** (Termux 环境): ```bash # Gateway 日志默认写入 ~/.hermes/logs,但 Termux 可能有权限问题 mkdir -p /sdcard/.hermes/logs rm -rf ~/.hermes/logs ln -s /sdcard/.hermes/logs ~/.hermes/logs ``` 5. **启动 Gateway**: ```bash # 检查状态 hermes gateway status # 启动(前台) hermes gateway run # 或后台启动 nohup hermes gateway run > ~/.hermes/logs/gateway.log 2>&1 & ``` 6. **验证 Gateway 连接**: ```bash # 查看日志 tail -f ~/.hermes/logs/gateway.log # 应看到: # - "Connecting to feishu..." # - "[Feishu] Connected in websocket mode" # - "Gateway running with X platform(s)" ``` ### 常见错误 **错误**: `Unauthorized user: xxx on feishu` - **解决**: 设置 `GATEWAY_ALLOW_ALL_USERS=true` 或执行 `hermes pairing approve feishu ` **错误**: `Permission denied: '/.hermes'` - **解决**: 创建日志目录链接到 /sdcard **错误**: `cannot import name 'env_float' from 'utils'` - **解决**: 检查 Python 环境,可能需要更新 hermes-agent ## Hermes 飞书插件集成 ### hermes-feishu 插件 (推荐) **arkseek/hermes-feishu** - 增强 Hermes 飞书消息通道,支持卡片消息和表格渲染。 **安装**: ```bash hermes plugins install arkseek/hermes-feishu hermes plugins enable hermes-feishu ``` **配置环境变量** (~/.hermes/.env): ``` FEISHU_APP_ID=cli_a91b01debab81cd1 FEISHU_APP_SECRET=your_secret HERMES_FEISHU_CHAT_ID=oc_xxxxxx # 默认群聊ID ``` **提供的工具**: - `send_feishu_card` - 发送卡片消息(支持 Markdown + 表格) - `send_feishu_table` - 发送结构化表格数据 - `pre_llm_call` - 自动注入格式化指令 **使用示例**: ```bash # 发送卡片消息(注意:table 使用 columns 而不是 headers) lark api POST /open-apis/im/v1/messages \ --data '{ "receive_id": "oc_xxxxxx", "msg_type": "interactive", "content": "{\"config\":{\"wide_screen_mode\":true},\"header\":{\"title\":{\"tag\":\"plain_text\",\"content\":\"标题\"},\"template\":\"blue\"},\"elements\":[{\"tag\":\"div\",\"text\":{\"tag\":\"lark_md\",\"content\":\"**内容**\"}},{\"tag\":\"table\",\"columns\":[{\"tag\":\"text\",\"text\":\"列1\",\"width\":\"auto\",\"weight\":1},{\"tag\":\"text\",\"text\":\"列2\",\"width\":\"auto\",\"weight\":1}],\"rows\":[[{\"tag\":\"text\",\"text\":\"数据1\"},{\"tag\":\"text\",\"text\":\"数据2\"}]]}]}" }' ``` **卡片消息格式要点**: - `config.wide_screen_mode`: true(宽屏模式) - `header.title`: 标题(plain_text 或 lark_md) - `header.template`: 颜色模板(blue, red, green, orange, grey, default, wathet, turquoise, yellow, carmine, violet, purple, indigo) - `elements`: 内容元素数组 - `tag: div` - 文本块(text 支持 lark_md 格式) - `tag: table` - 表格(**使用 columns 而不是 headers**) - `tag: img` - 图片 - `tag: action` - 按钮 **常见错误**: - ❌ `headers` - 错误!table 不支持 headers - ✅ `columns` - 正确!table 使用 columns 定义表头 - ❌ 直接传递 Python dict - 错误!content 必须是 JSON 字符串 - ✅ `json.dumps(content)` - 正确!使用 json.dumps 转义 ### 机器人身份 **当前机器人**: pixel phone agent (cli_a91b01debab81cd1) - Open ID: ou_187699924a3759c17932ac8f3c685978 - 群聊: Lemonbot 全员+机器人群 (oc_3156253ca92a5f8649945c59769d9c52) **注意**: 群里可能有多个机器人,用户需要 @ 正确的机器人才能收到回复。 ## 参考文档 - 飞书开放平台:https://open.feishu.cn/ - API 文档:https://open.feishu.cn/document/ - lark-cli GitHub:https://github.com/larksuite/cli - hermes-feishu 插件:https://github.com/arkseek/hermes-feishu - **Gateway 配置详细指南**: `references/gateway-setup.md` - **故障排除速查**: `references/troubleshooting.md`