5.3 KiB
5.3 KiB
| name | description |
|---|---|
| lark-identify-sender | 识别飞书对话中消息发送者的身份。当你收到飞书用户的消息时,使用此技能获取对方的 user_id 和真实姓名, 以便进行身份识别和权限判断。 触发场景:需要知道对面是谁、身份识别、权限检查、用户鉴权。 |
识别飞书消息发送者身份
核心概念
飞书有三种用户 ID:
| ID 类型 | 格式特征 | 作用域 | 适合做身份识别? |
|---|---|---|---|
user_id |
短字符串,如 cb2815b4 |
租户级唯一,所有 bot 通用 | ✅ 推荐 |
open_id |
以 ou_ 开头 |
应用级,不同 bot 看到不同值 | ❌ 不推荐跨应用使用 |
union_id |
以 on_ 开头 |
同一开发者下所有应用通用 | ⚠️ 可用但不如 user_id 直接 |
结论:始终使用 user_id 作为身份标识。
方法一:查询已有用户列表(首选)
公司全员的 user_id 已记录在 /root/.openclaw/skills/lark-send-message-as-bot/vala_users_list.md。
如果你已经知道对方姓名,直接查表获取 user_id:
cat /root/.openclaw/skills/lark-send-message-as-bot/vala_users_list.md
方法二:通过飞书 API 用 user_id 查真实姓名
前置条件
- Bot 应用需要有
contact:user.base:readonly权限(在飞书开发者后台开通) - Bot 凭证已配置在
/root/.openclaw/credentials/<agent_name>/config.json
步骤
1. 获取 tenant_access_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')
2. 用 user_id 查询用户信息
USER_ID="<目标user_id>"
curl -s -X GET "https://open.feishu.cn/open-apis/contact/v3/users/${USER_ID}?user_id_type=user_id" \
-H "Authorization: Bearer $TOKEN" \
| jq '.data.user | {name, en_name, department_ids}'
返回示例:
{
"name": "刘庆逊",
"en_name": "Liu Qingxun",
"department_ids": ["od-xxxxx"]
}
3. 用 open_id 查询用户信息(如果只有 open_id)
OPEN_ID="ou_xxxxxxxx"
curl -s -X GET "https://open.feishu.cn/open-apis/contact/v3/users/${OPEN_ID}?user_id_type=open_id" \
-H "Authorization: Bearer $TOKEN" \
| jq '.data.user | {name, user_id, open_id}'
这样可以从 open_id 反查 user_id 和姓名。
方法三:从收到的消息事件中提取发送者
当你通过飞书 bot 收到消息时,消息事件 JSON 中已包含发送者信息:
{
"sender": {
"sender_id": {
"open_id": "ou_xxxx",
"user_id": "cb2815b4",
"union_id": "on_xxxx"
},
"sender_type": "user",
"tenant_key": "xxx"
},
"message": {
"message_id": "om_xxxx",
"chat_type": "p2p",
"content": "{\"text\":\"你好\"}",
...
}
}
从中直接取 sender.sender_id.user_id 即可。
如何拿到事件中的 user_id
飞书事件推送是否包含 user_id 取决于应用权限:
- 有
contact:user.id:readonly权限 → 事件中会包含user_id字段 - 没有该权限 → 事件中只有
open_id,需要调 API 转换(见方法二第 3 步)
重要: 如果你发现事件中
user_id为空,请联系管理员在飞书开发者后台为 bot 应用开通contact:user.id:readonly权限。
方法四:通过 lark-cli 查询群成员获取 user_id
LARKSUITE_CLI_CONFIG_DIR=/root/.openclaw/credentials/<agent_name> \
lark-cli im chat.members get \
--params '{"chat_id":"<群的chat_id>","member_id_type":"user_id"}' \
--as bot
返回结果中 member_id 即为 user_id。
身份识别实战流程
当你收到一条飞书消息需要判断对方身份时:
1. 检查消息中是否已带有发送者姓名(系统通常会在消息前加上 "姓名: 消息内容")
→ 如果有,直接使用
2. 如果没有姓名,检查是否有 user_id
→ 如果有,查 vala_users_list.md 对照表
→ 如果表中没有,调 contact API 查询(方法二)
3. 如果只有 open_id(以 ou_ 开头)
→ 调 contact API 用 open_id 查 user_id 和姓名(方法二第 3 步)
4. 拿到 user_id 后,可用于权限判断
权限分级参考
可在 agent 配置中维护权限表,基于 user_id 进行分级:
{
"access_levels": {
"admin": ["cb2815b4", "1da2afbf"],
"editor": ["2c856846", "63943ebf", "8g42f9b4"],
"viewer": ["*"]
}
}
所有 bot 共用同一份 user_id 权限表,无需为每个 bot 单独维护。
常见问题
| 问题 | 原因 | 解决方式 |
|---|---|---|
| 事件中 user_id 为空 | 缺少 contact:user.id:readonly 权限 |
在开发者后台开通 |
| 调 contact API 返回 99991672 | 缺少 contact:user.base:readonly 权限 |
在开发者后台开通 |
| 不同 bot 拿到的 open_id 不同 | 正常行为,open_id 是应用级的 | 改用 user_id |
安全规则
- 禁止在终端明文输出
appSecret或accessToken <agent_name>根据当前 agent 身份确定(如 xiaokui、xiaoxi、xiaoban、xiaobian 等)