文章目录
-
- 前言
- 环境说明
- 一、安装
- 二、快速开始
-
- [2.1 命令行方式](#2.1 命令行方式)
- [2.2 Python API 方式](#2.2 Python API 方式)
- 三、自动化流程详解
-
- [3.1 应用管理](#3.1 应用管理)
- [3.2 权限配置](#3.2 权限配置)
- [3.3 事件订阅](#3.3 事件订阅)
- [3.4 回调配置](#3.4 回调配置)
- [3.5 版本管理](#3.5 版本管理)
- 四、技术方案
-
- [4.1 为什么用 DrissionPage 而不是 Selenium](#4.1 为什么用 DrissionPage 而不是 Selenium)
- [4.2 API 监听机制](#4.2 API 监听机制)
- [4.3 浏览器懒加载与复用](#4.3 浏览器懒加载与复用)
- [4.4 弹窗自动处理](#4.4 弹窗自动处理)
- [4.3 项目结构](#4.3 项目结构)
- 五、常见问题
- 总结
前言
用 OpenClaw 对接飞书时,每次都要手动创建应用、勾权限、配事件订阅,操作虽然不复杂但很繁琐。这个工具的作用就是把这些操作全部自动化------一行命令完成飞书应用从创建到配置的全部流程。
手动配置下来大概七八分钟,说长不长说短不短,但架不住反复做。尤其用 OpenClaw 对接飞书的时候,经常要创建测试应用,漏配一个权限 Agent 就收不到消息。而且每个操作之间还有先后依赖------不配权限就没法发版,不发版权限就不生效,不启动长连接就保存不了事件订阅。
feishu-auto 把这些依赖关系全部编排好了,跑一遍就完事。
完整源码地址: https://github.com/cicbyte/feishu-atuo(MIT 协议开源)
环境说明
| 项目 | 要求 |
|---|---|
| 操作系统 | Windows(目前仅 Windows 测试通过) |
| Python | >= 3.12 |
| 浏览器 | Chrome |
| 核心依赖 | DrissionPage >= 4.0.0, lark-oapi >= 1.0.0, pyperclip >= 1.8.0 |
一、安装
bash
pip install feishu-auto
也可以用 uv:
bash
uv pip install feishu-auto
安装完成后会自动注册 feishu-auto 命令行工具。
二、快速开始
2.1 命令行方式
bash
# 使用默认应用名称(openclaw)
feishu-auto
# 指定应用名称
feishu-auto -n my-bot
# 指定浏览器调试端口
feishu-auto -p 9223
# 开启 DEBUG 日志
feishu-auto -l DEBUG
首次运行会自动打开 Chrome 浏览器跳转到飞书登录页,扫码登录后重新运行命令即可。之后会保持登录状态,不需要重复扫码。
运行日志示例:
2026-04-05 10:00:00 - feishu_auto - INFO - ==================================================
2026-04-05 10:00:00 - feishu_auto - INFO - 飞书开放平台自动化配置工具
2026-04-05 10:00:00 - feishu_auto - INFO - - 版本: 0.1.0
2026-04-05 10:00:00 - feishu_auto - INFO - - 应用名称: my-bot
2026-04-05 10:00:01 - feishu_auto - INFO - [访问] 正在打开飞书页面
2026-04-05 10:00:03 - feishu_auto - INFO - [权限检查] 正在监听接口
2026-04-05 10:00:05 - feishu_auto - INFO - [权限导入] 缺少 42 个权限,开始导入...
2026-04-05 10:00:15 - feishu_auto - INFO - [事件订阅] 检查事件配置状态...
2026-04-05 10:00:20 - feishu_auto - INFO - [完成] 飞书应用配置完成!
2.2 Python API 方式
适合在代码中集成或做更灵活的控制:
python
from feishu_auto import FeishuBrowser, create_event_client
# 创建实例并自动完成全部配置
feishu = FeishuBrowser(app_name="my-bot")
tab = feishu.open_feishu()
# 启动事件订阅客户端(后台运行)
client = create_event_client(app_name="my-bot")
client.start(block=False)
自定义配置:
python
from feishu_auto import FeishuBrowser
from feishu_auto.config import Config, set_config
config = Config(
debug_port=9223,
default_app_name="custom-app",
default_version="1.0.0",
)
set_config(config)
feishu = FeishuBrowser(app_name="custom-app")
tab = feishu.open_feishu()
三、自动化流程详解
一行命令背后,工具会按顺序完成以下流程:
版本发布
事件与回调
权限与能力
应用管理
初始化
未登录
已登录
唯一匹配
多个匹配
未找到
选择已有
创建新应用
有缺失
权限完整
是
否
打开飞书首页
检查登录状态
提示扫码登录
程序退出
跳转开放平台
检查应用是否存在
自动选择应用
用户选择应用
创建新应用
获取 App Secret
添加机器人能力
检查权限差异
批量导入权限
跳过
配置事件订阅
配置 card.action.trigger 回调
有更新操作?
自动创建并发布新版本
跳过
完成
3.1 应用管理
工具通过监听开放平台的 /developers/v1/app/list 接口来检查应用是否存在,根据返回结果做不同处理:
| 场景 | 处理方式 |
|---|---|
| 没有同名应用 | 自动创建新应用 |
| 有 1 个同名应用 | 自动选择并跳转 |
| 有多个同名应用 | 交互式让用户选择 |
创建完成后会自动获取 App ID 和 App Secret,并缓存到内存中供后续步骤使用。
3.2 权限配置
这是手动操作时最耗时的环节。飞书的权限列表有上百个,手动一个个勾选不仅慢,还容易漏。
工具的做法是自动对比差异 ,通过 API 监听获取当前应用已开通的权限列表,与 ~/.feishu-auto/auth.json 中的目标权限做差集,只导入缺失的部分:
python
# 权限差异检查核心逻辑
target_permissions = self._get_target_permissions() # 从配置文件读取目标权限
applied_permissions = {scope["name"] for scope in body["data"]["scopes"]} # 从 API 获取已有权限
missing = target_permissions - applied_permissions # 差集 = 需要导入的权限
已导入的权限不会重复操作,已配齐的应用直接跳过整个权限导入流程。
默认内置 70+ 个常用权限(tenant 和 user 两大类),大部分权限申请后会自动通过,不需要管理员审批。如果需要自定义权限,编辑配置文件即可:
json
{
"scopes": {
"tenant": [
"im:message:send_as_bot",
"im:chat:read"
],
"user": [
"contact:user.base:readonly"
]
}
}
配置文件路径:~/.feishu-auto/auth.json,如果文件不存在,首次运行会自动创建默认配置。
3.3 事件订阅
飞书的事件订阅配置有一个时序问题:必须先启动一个 WebSocket 长连接客户端,飞书后台验证连接成功后,才能保存订阅方式配置。手动操作的时候特别容易忘这一步,导致配了半天保存不上。
feishu-auto 的处理方式:
新应用 --- 获取到 App Secret 后立刻启动长连接,等 6 秒确保连接建立,然后去配事件订阅。
旧应用 --- 先通过 API 检查事件订阅状态(eventMode 是否为 4),需要更新才启动长连接,不需要就跳过。
配置完成后会自动添加三个默认事件:
| 事件类型 | 说明 |
|---|---|
im.message.receive_v1 |
接收消息 |
im.message.message_read_v1 |
消息已读 |
im.message.reaction.deleted_v1 |
表情反应删除 |
3.4 回调配置
自动检查并配置 card.action.trigger 回调事件,同样支持长连接模式。流程与事件订阅类似:先检查状态,需要更新才操作,不需要就跳过。
3.5 版本管理
配置变更后自动创建新版本并发布,版本号采用递增策略------自动将最后一位版本号加一:
python
# 版本号递增逻辑
current = "1.0.5"
parts = current.split(".")
parts[-1] = str(int(parts[-1]) + 1)
new_version = ".".join(parts) # "1.0.6"
如果所有配置都没有变更,则不会创建新版本。同时工具只管前两个版本的自动发布------已有 2 个以上版本说明用户可能已手动介入,工具不再越俎代庖,交给用户自己管理。
四、技术方案
4.1 为什么用 DrissionPage 而不是 Selenium
Selenium 其实也支持调试端口连接、浏览器复用和登录状态保持,这些并非 DrissionPage 独有的优势。
选择 DrissionPage 的核心原因是它原生内置了网络请求监听能力 。本项目最关键的技术点是 API 监听------拦截浏览器请求、读取响应内容。DrissionPage 直接提供了 tab.listen.start() 和 tab.listen.steps() 接口,开箱即用。用 Selenium 做同样的事需要自己封装 CDP 协议或引入 selenium-wire 等额外依赖。
另外 DrissionPage 不需要单独安装和管理 WebDriver,API 更轻量。
4.2 API 监听机制
飞书开放平台是动态渲染的前端,纯靠 XPath 解析 DOM 来判断状态不稳定------页面结构稍微改一下就挂了。工具的做法是监听浏览器发出的 API 请求,直接读取接口返回的 JSON:
python
# 监听权限 API
api_url_pattern = f"scope/applied/{app_id}"
self.tab.listen.start(api_url_pattern)
for packet in self.tab.listen.steps(timeout=10):
body = json.loads(packet.response.body)
applied = {scope["name"] for scope in body["data"]["scopes"]}
missing = target_permissions - applied # 差集
这种方式的优点是从数据源头获取状态,不依赖页面元素的 class 名称或层级结构,飞书前端改版对工具的影响降到最低。
工具在整个流程中监听了以下接口:
| 功能 | 监听接口 | 用途 |
|---|---|---|
| 应用列表 | /developers/v1/app/list |
检查应用是否存在 |
| 应用创建 | /developers/v1/app |
监听获取新创建的 app_id |
| 权限检查 | /developers/v1/scope/applied/{app_id} |
比对权限差异 |
| 版本检查 | /developers/v1/app/version/list |
检查版本是否存在 |
| 事件配置 | /developers/v1/app/event/subscribe/info |
检查事件订阅状态 |
| 回调配置 | /developers/v1/app/bot/card/callback/info |
检查回调配置状态 |
4.3 浏览器懒加载与复用
浏览器实例采用懒加载模式,且支持复用已运行的实例:
python
@property
def browser(self) -> ChromiumPage:
if self._browser is None:
if self._is_port_in_use(self.port):
# 端口被占用 → 直接接管已有浏览器
self._browser = ChromiumPage(addr_or_opts=self.port)
else:
# 端口可用 → 启动新浏览器
co = self._create_options()
self._browser = ChromiumPage(addr_or_opts=co)
return self._browser
如果你已经手动打开了 Chrome 并登录了飞书,工具会通过调试端口直接接管这个浏览器实例,不用重新打开和扫码。
4.4 弹窗自动处理
飞书首页会不定期弹出广告弹窗,如果不关掉会遮挡后续操作。工具在打开页面时会自动检测并关闭弹窗,采用了多个选择器逐个尝试的方式,应对弹窗样式的变化:
python
xpath_selectors = [
"x://div[contains(@class, 'popup-close') and contains(@class, 'popup-close-pc')]",
"x://div[contains(@class, 'popup-close-pc')]",
"x://div[contains(@class, 'popup-close')]",
]
for xpath in xpath_selectors:
ele = self.tab.ele(xpath, timeout=3)
if ele:
ele.click()
return True
找不到弹窗元素也不会报错,静默跳过继续执行。
4.3 项目结构
src/feishu_auto/
├── __init__.py # 包入口,导出 FeishuBrowser, create_event_client
├── cli.py # 命令行接口(argparse)
├── config.py # 配置管理(dataclass + 内存缓存)
├── browser.py # 浏览器基础类(懒加载、复用)
├── app.py # 应用管理 Mixin
├── auth.py # 权限管理 Mixin
├── version.py # 版本管理 Mixin
├── feishu.py # 主类,组合所有 Mixin
└── event.py # WebSocket 长连接客户端
采用 Mixin 模式组织代码,扩展新功能只需新增 Mixin 类:
python
class FeishuBrowser(BrowserBase, AppMixin, AuthMixin, VersionMixin):
"""组合所有功能模块"""
每个 Mixin 职责单一,互不干扰:
| 模块 | 文件 | 职责 |
|---|---|---|
BrowserBase |
browser.py | 浏览器生命周期管理、懒加载、复用 |
AppMixin |
app.py | 应用创建、查找、跳转 |
AuthMixin |
auth.py | 权限差异检查、导入、申请 |
VersionMixin |
version.py | 版本创建、发布、版本号递增 |
FeishuEventClient |
event.py | WebSocket 长连接、事件处理 |
这种设计的好处是扩展方便------比如要加一个"自动配置机器人菜单"的功能,只需要新增一个 MenuMixin,然后加到 FeishuBrowser 的继承列表即可,不用动现有代码。
五、常见问题
Q: 首次运行提示需要登录怎么办?
A: 正常现象。首次运行会打开浏览器到飞书登录页,扫码登录后重新运行命令即可。之后会保持登录状态。
Q: 支持哪些操作系统?
A: 目前仅在 Windows 平台测试通过,Linux/macOS 未验证。
Q: 权限申请需要管理员审批吗?
A: 大部分权限申请后会自动通过,不需要管理员审批。整个流程可以无人值守。
Q: 自定义权限怎么配?
A: 编辑 ~/.feishu-auto/auth.json 文件,按 tenant / user 分类填写权限名称即可。如果文件不存在,首次运行会自动创建默认配置。
Q: 浏览器复用是什么意思?
A: 如果你已经手动打开了 Chrome 并登录了飞书,工具会通过调试端口直接接管这个浏览器实例,不用重新打开和扫码。
Q: 配置完成后怎么接收飞书消息?
A: 配置完成后,使用 Python API 启动事件订阅客户端即可:
python
from feishu_auto import create_event_client
client = create_event_client(app_name="your-app")
client.start(block=True) # 阻塞运行,持续监听事件
客户端基于 lark-oapi SDK 的 WebSocket 长连接,默认注册了 im.message.receive_v1 事件处理。
Q: 飞书页面改版了怎么办?
A: 工具的状态判断主要依赖 API 监听而非 XPath 解析,页面改版对核心流程的影响较小。但部分操作(如点击按钮)仍然依赖 XPath 定位,如果遇到问题可以提交 Issue。
总结
feishu-auto 把飞书应用配置流程完全自动化:创建应用 → 权限配置 → 事件订阅 → 回调配置 → 版本发布,一行命令搞定。特别适合用 OpenClaw 对接飞书、频繁创建测试应用的场景。
几个核心设计点:
- API 监听而非 DOM 解析 --- 状态判断基于接口返回数据,不依赖页面结构,稳定性高
- 智能跳过已配置步骤 --- 不重复操作,已配齐的步骤直接跳过
- 自动处理长连接时序 --- 事件订阅的 WebSocket 先后顺序问题完全自动化
- Mixin 模式可扩展 --- 新增功能只需加 Mixin,不动现有代码