飞书开放平台踩坑(自建应用接入经验)
本篇是从一个飞书自建应用(悬赏系统)的接入实践里提炼出来的经验教训,只留通用结论,不含任何凭据、App ID/Secret、群 ID、union_id 等标识。
#一、身份主键:用 union_id,别用 email
- 原计划用邮箱匹配用户身份,实测行不通,改用 union_id。
- 即使 scope 里显式带上
contact:user.email:readonly(飞书确实接受了该 scope),authen/v1/user_info返回的email仍是空字符串、enterprise_email为 null。 - 根因不是权限问题,而是该飞书账号的通讯录里本来就没填邮箱。email 字段一律按可空处理,绝不能作为身份依据。
- 更稳的做法:用
union_id作为用户表的唯一键(跨应用稳定)。 - 对比其它标识:
open_id是应用维度的,换应用就变,别拿它当业务主键;user_id是通讯录 member id;tenant_key是租户标识。
#二、几个身份标识的适用范围
| 标识 | 稳定范围 | 能否当业务主键 |
|---|---|---|
| union_id | 同一开发者主体下跨应用稳定 | ✅ 推荐 |
| open_id | 仅当前应用内稳定,换应用即变 | ❌ |
| user_id | 通讯录 member id | 视场景 |
| email / enterprise_email | 可能恒为空 | ❌ 不可依赖 |
#三、单向通知场景不需要事件回调
- 如果飞书只用来做单向通知(服务端主动发消息/卡片到群),就不需要配「事件与回调」,也不需要 Encrypt Key / Verification Token。
- 只有要接收用户消息、响应交互回调时才需要订阅事件。
#四、后台能力与权限要点
- 企业自建应用要发消息,需开通
im:message:send_as_bot权限,并把机器人拉进目标群。 - OAuth 登录链路要在后台把回调 URL 加进重定向白名单(线上域名 + 本地 localhost 都要加),否则跳转回来会失败。
- 应用要先创建版本并发布、经企业管理员审核通过,机器人才能真正发消息。
- 应用可用范围记得改为全员(或目标人群),否则部分用户匹配不到。
#五、知识库文档权限的坑
- 老板在自己账号下建的文档,员工点链接会 403。
- 若要全员能读同一批文档,必须建一个对全员开放阅读的知识库,把文档放进去。第一次真实发布前必须搞定。
#六、对外共享开关默认要关
- 应用发布页底部有「允许机器人被添加到外部群」和「允许外部用户与机器人单聊」两个开关,且默认可能是「无需审核」。
- 内部系统不该对外开口子,建议都关掉。
#七、Cloudflare wrangler 非交互环境必须用 API Token
- 这是接入过程中一并踩到的 Cloudflare 坑,一并记下:
- wrangler 在非 TTY 环境下拒绝使用 OAuth 凭据。
wrangler login成功后wrangler whoami能读到账号,但任何实际 API 操作(d1 create/d1 list等)都报「In a non-interactive environment, it's necessary to set a CLOUDFLARE_API_TOKEN」。 - Claude Code 的工具调用就是非交互环境,所以自动化部署必须走 API Token,不能只靠
wrangler login。
来源:配置信息/Knonii悬赏系统-凭据.md(整理于 2026-08-18)