公司动态

飞书CLI自动化工具开发指南:从API集成到工作流实战

📅 2026/8/13 10:59:59
飞书CLI自动化工具开发指南:从API集成到工作流实战
1. 项目概述当自动化工具遇上协同平台如果你和我一样每天的工作流都深度绑定在飞书上——审批、文档、群聊、机器人通知但同时又需要频繁地在本地终端敲命令、跑脚本、处理数据那你一定幻想过要是能让飞书直接“听懂”我的命令行或者让我的脚本能直接操作飞书里的内容该多好。这个想法就是“Codex × 飞书Cli实战指南”这个项目的核心。它不是一个官方产品而是一种将强大的命令行界面CLI工具与飞书开放平台深度集成的实践方案旨在为开发者、运维乃至业务人员打造一套无缝衔接本地工作流与云端协同的“数字手脚”。简单来说Codex在这里并非特指某个AI模型而是一个象征代表着你本地环境中那些高效、可编程的自动化脚本和工具链飞书Cli则是指通过飞书开放平台提供的API构建出的命令行控制能力。这个项目的目标就是打通二者之间的壁垒。想象一下你可以在终端里一条命令创建飞书日程用脚本自动解析群消息并触发CI/CD流程或是将服务器日志实时聚合到飞书多维表格进行分析。这不仅仅是节省几次点击而是从根本上重塑了人、本地工具与云端协同空间交互的方式。我最初尝试这个方向是因为被一些重复且割裂的操作搞得不胜其烦。比如每天需要手动从十几个飞书群聊里收集日报链接汇总到一个文档。后来我用Python脚本配合飞书API实现了自动抓取和整理但每次运行还是要打开IDE或找到脚本文件。最终我将这个脚本封装成了一个全局的CLI命令比如叫做feishu-daily-report现在只需要在终端输入这一行所有事情就自动搞定了。这种“化繁为简一步到位”的体验正是本指南想要带你实现的。2. 核心思路与架构设计2.1 为什么是CLI 飞书API在自动化方案选型上我们有很多选择比如开发一个完整的Web应用、做一个浏览器插件或者使用RPA机器人流程自动化工具。但CLIAPI的组合对于开发者而言往往是最直接、最灵活、也最强大的。首先CLI是开发者的母语。我们天生习惯在终端里工作grep,awk,curl,jq这些工具链组合起来能爆发出惊人的生产力。将飞书的能力封装成CLI命令意味着你可以用管道|将飞书数据与其他Unix工具连接可以用cron或systemd定时任务来驱动也可以无缝嵌入到现有的Shell脚本或Makefile中成为自动化流水线的一环。其次飞书开放平台提供了完备的API。从消息发送、通讯录管理、云文档操作到审批流程、机器人互动几乎所有的飞书功能都提供了相应的HTTP接口。这为我们用程序控制飞书提供了坚实的基础。CLI工具的本质就是一个友好的、封装了API调用细节的命令行客户端。最后这种架构轻量且易于分发。一个CLI工具通常就是一个可执行二进制文件或Python脚本不需要部署服务器不需要维护数据库除非必要开箱即用。团队成员可以通过包管理器如pip,brew,npm一键安装快速获得同样的自动化能力。2.2 整体技术栈与组件选型要实现一个健壮的飞书CLI工具我们需要以下几层组件飞书API客户端层这是与飞书服务器直接对话的基础。不建议从零开始封装HTTP请求应该选择成熟的SDK。对于Python技术栈官方提供的lark-oapiSDK是首选。它封装了签名、令牌管理、请求重试等繁琐细节并且与API文档保持同步更新。对于Node.js生态则有larksuite-oapi/core等可选。CLI框架层我们需要一个框架来解析命令行参数、生成帮助信息、管理子命令等。Python世界里click和typer是两个极佳的选择。typer基于Python的类型提示用起来非常现代和简洁是我个人的推荐。它能让你的CLI代码像定义函数一样自然同时自动生成漂亮的帮助文档。配置与认证管理层安全地管理飞书应用的App ID和App Secret是关键。我们不能将这些敏感信息硬编码在脚本里。通常的做法是使用一个配置文件如~/.config/feishu-cli/config.yaml来存储应用凭证。首次运行时引导用户进行OAuth2授权或应用商店安装获取tenant_access_token。使用操作系统提供的密钥环如macOS的Keychain、Linux的Secret Service来加密存储令牌而不是明文存放在配置文件中。业务逻辑与工具链集成层这是体现价值的地方。根据你的需求编写具体的命令逻辑。例如一个send命令用于发送消息一个doc命令用于操作文档。更重要的是思考如何与现有工具链集成。比如你的git commit钩子中可以调用CLI向飞书群同步提交信息你的监控脚本如Prometheus Alertmanager可以通过Webhook触发CLI发送告警。一个典型的项目目录结构可能如下所示feishu-cli/ ├── pyproject.toml # 项目依赖和配置 (使用现代Python打包标准) ├── src/ │ └── feishu_cli/ │ ├── __init__.py │ ├── main.py # CLI入口点使用typer │ ├── auth.py # 认证管理逻辑 │ ├── config.py # 配置加载与管理 │ ├── api/ # 飞书API封装模块 │ │ ├── __init__.py │ │ ├── message.py │ │ └── bitable.py # 多维表格操作 │ └── commands/ # 具体命令实现 │ ├── send.py │ └── report.py └── README.md3. 从零开始构建你的第一个飞书CLI命令3.1 环境准备与飞书应用创建工欲善其事必先利其器。首先确保你的Python环境在3.8以上。我强烈建议使用uv或pdm这类现代Python包管理器和虚拟环境工具它们比传统的venvpip组合更快、更一致。# 使用uv初始化项目如果没有可以用 pip install uv 安装 uv init feishu-cli cd feishu-cli uv add typer lark-oapi rich python-dotenv接下来前往 飞书开放平台 创建你的企业自建应用。这一步至关重要因为后续所有API调用都基于这个应用的身份。登录开放平台点击“创建企业自建应用”。填写应用名称比如My Awesome CLI Tool。进入应用后在“凭证与基础信息”页面记录下App ID和App Secret。这就是你的应用的“身份证”。配置权限根据你CLI工具想要实现的功能在“权限管理”页面添加对应的权限。例如发送消息需要“以应用身份发送消息”、“获取用户发给机器人的单聊消息”等。读取通讯录需要“获取部门信息”、“获取用户信息”等。操作云文档需要“获取访问某个云文档的权限”等。务必注意添加权限后需要“申请发布”并由管理员在飞书管理后台审核通过该权限才会生效。对于测试你可以将应用添加到仅包含你自己的“测试企业”中并授予全部权限以便快速验证。3.2 实现认证与配置管理安全地处理App ID和App Secret是我们的首要任务。我们将使用环境变量和本地配置文件结合的方式。首先创建一个.env文件在项目根目录切记将其加入.gitignoreFEISHU_APP_IDcli_xxxxxx FEISHU_APP_SECRETxxxxxxxxxxxx然后我们实现配置加载模块src/feishu_cli/config.pyimport os from pathlib import Path from typing import Optional import yaml from dotenv import load_dotenv from pydantic import BaseSettings, Field load_dotenv() # 加载 .env 文件中的环境变量 class Settings(BaseSettings): app_id: str Field(..., envFEISHU_APP_ID) app_secret: str Field(..., envFEISHU_APP_SECRET) # 可以添加其他配置如默认接收者、API超时时间等 default_receive_id: Optional[str] None default_receive_id_type: str open_id # open_id, user_id, email, chat_id class Config: env_file .env # 全局配置实例 settings Settings() def get_config_path() - Path: 获取用户配置目录路径 config_dir Path.home() / .config / feishu-cli config_dir.mkdir(parentsTrue, exist_okTrue) return config_dir / config.yaml def load_user_config(): 加载用户运行时配置如令牌、默认空间ID等 config_file get_config_path() if config_file.exists(): with open(config_file, r) as f: return yaml.safe_load(f) or {} return {} def save_user_config(config: dict): 保存用户运行时配置 config_file get_config_path() with open(config_file, w) as f: yaml.dump(config, f)接下来是认证模块src/feishu_cli/auth.py。飞书API主要使用tenant_access_token应用维度和user_access_token用户维度。对于CLI工具我们通常使用前者因为它代表应用本身无需用户每次授权。import time import json from typing import Optional, Tuple import requests from .config import settings, save_user_config, load_user_config class AuthManager: _token: Optional[str] None _expire: int 0 classmethod def _get_cache_key(cls): return ftoken_{settings.app_id} classmethod def get_tenant_access_token(cls, force_refresh: bool False) - str: 获取或刷新租户访问令牌带内存和简单文件缓存 now int(time.time()) # 内存缓存检查 if not force_refresh and cls._token and cls._expire now 60: # 提前60秒视为过期 return cls._token # 文件缓存检查示例生产环境建议用更安全的存储 user_config load_user_config() cached_token user_config.get(cls._get_cache_key()) if cached_token and cached_token.get(expire, 0) now 60: cls._token cached_token[token] cls._expire cached_token[expire] return cls._token # 请求新令牌 url https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal payload { app_id: settings.app_id, app_secret: settings.app_secret } resp requests.post(url, jsonpayload) resp.raise_for_status() data resp.json() if data.get(code) ! 0: raise Exception(fFailed to get token: {data.get(msg)}) cls._token data[tenant_access_token] cls._expire now data[expire] # 飞书返回的是有效时间单位秒 # 更新文件缓存注意此处为简化示例令牌应加密存储 user_config[cls._get_cache_key()] { token: cls._token, expire: cls._expire } save_user_config(user_config) return cls._token classmethod def get_headers(cls) - dict: 获取带认证头的通用请求头 token cls.get_tenant_access_token() return { Authorization: fBearer {token}, Content-Type: application/json; charsetutf-8 }注意上面的文件缓存仅为示例tenant_access_token虽然不像user_access_token那样敏感但也不建议明文持久化在本地文件。生产级工具应考虑使用操作系统提供的安全存储如keyring库。3.3 打造“发送消息”核心命令有了认证基础我们就可以实现第一个也是最常用的功能发送消息。我们将使用typer来构建CLI。在src/feishu_cli/main.py中import typer from typing import Optional import json from .commands.send import send_message app typer.Typer( namefeishu, help 你的飞书命令行瑞士军刀让自动化触手可及。, add_completionFalse ) # 挂载子命令 app.command()(send_message) if __name__ __main__: app()在src/feishu_cli/commands/send.py中实现具体的发送逻辑import typer import requests import json from typing import Optional from pathlib import Path from ..auth import AuthManager app typer.Typer() app.command() def send_message( receive_id: str typer.Argument(..., help接收者的ID。可以是 open_id, user_id, email 或 chat_id。), msg_type: str typer.Option(text, --type, -t, help消息类型text, post, image, interactive (卡片)等。), content: Optional[str] typer.Option(None, --content, -c, help消息内容。对于文本直接传入对于复杂类型可传JSON字符串或文件路径。), content_file: Optional[Path] typer.Option(None, --file, -f, help从文件读取消息内容JSON格式。), receive_id_type: str typer.Option(open_id, --id-type, help接收者ID类型open_id, user_id, email, chat_id。), ): 向指定的飞书用户、群组或机器人发送一条消息。 示例 feishu send-message ou_xxxx --type text --content Hello from CLI! feishu send-message oc_xxxx --id-type chat_id --type interactive -f ./card.json # 构建消息内容 if content_file: with open(content_file, r, encodingutf-8) as f: msg_content json.load(f) elif content: if msg_type text: msg_content {text: content} else: # 尝试将content解析为JSON如果失败则报错 try: msg_content json.loads(content) except json.JSONDecodeError: typer.echo(错误对于非文本消息--content 参数必须是有效的JSON字符串。) raise typer.Exit(code1) else: typer.echo(错误必须提供 --content 或 --file 参数之一。) raise typer.Exit(code1) # 构造API请求体 url https://open.feishu.cn/open-apis/im/v1/messages params {receive_id_type: receive_id_type} payload { receive_id: receive_id, msg_type: msg_type, content: json.dumps(msg_content, ensure_asciiFalse) } headers AuthManager.get_headers() try: response requests.post(url, paramsparams, jsonpayload, headersheaders) response.raise_for_status() result response.json() if result.get(code) 0: message_id result[data][message_id] typer.echo(f✅ 消息发送成功消息ID: {message_id}) else: typer.echo(f❌ 消息发送失败: {result.get(msg)}) raise typer.Exit(code1) except requests.exceptions.RequestException as e: typer.echo(f❌ 网络请求失败: {e}) raise typer.Exit(code1) # 为了方便我们将这个函数暴露给主程序调用 send_message_app app现在通过uv run python -m feishu_cli.main send-message --help你就可以看到自动生成的帮助文档。使用uv install -e .将包以可编辑模式安装后就可以直接使用feishu send-message命令了。3.4 进阶发送富文本与消息卡片仅仅发送文本是远远不够的。飞书强大的消息能力在于富文本和交互式卡片。我们的CLI工具必须支持这些。发送富文本Post 飞书的post消息类型支持复杂的富文本格式。我们需要构建一个符合飞书格式的JSON。可以创建一个辅助函数来简化构建过程或者直接接受一个JSON文件。更优雅的做法是支持从Markdown文件转换因为Markdown是开发者更熟悉的写作格式。发送交互卡片 这是将CLI工具变成“智能助手”的关键。卡片可以包含按钮、选择器、倒计时等交互元素用户点击后可以通过飞书机器人回调你的服务。对于CLI工具一种常见模式是CLI触发一个异步任务如数据备份然后发送一张带有“查看进度”或“取消任务”按钮的卡片。当用户点击按钮时触发一个你预先配置好的Webhook再由你的后台服务处理。在send.py中我们可以增加一个专门处理卡片的子命令或选项# 在 send.py 中新增一个函数或扩展原函数 def build_simple_card(title: str, content: str, button_text: str 确认, button_url: str None): 构建一个简单的消息卡片JSON card { config: {wide_screen_mode: True}, header: { title: {tag: plain_text, content: title} }, elements: [ { tag: div, text: {tag: lark_md, content: content} }, { tag: action, actions: [{ tag: button, text: {tag: plain_text, content: button_text}, type: primary, url: button_url # 可以是飞书内部链接或外部链接 }] } ] } return json.dumps(card)然后在调用时如果msg_type是interactive且内容是一个字符串可以尝试用这个函数构建。4. 实战场景将CLI深度融入工作流4.1 场景一自动化日报/周报收集与汇总这是最经典的应用。假设团队要求成员每天在飞书群内以固定格式提交日报。你可以编写一个CLI命令feishu report collect它完成以下工作拉取群消息使用获取群消息API过滤出指定时间段内、符合日报格式的消息。解析内容用正则表达式或简单的文本解析提取出关键字段如今日工作、明日计划、问题。结构化存储将解析后的数据写入本地CSV文件或直接插入到飞书多维表格Bitable中形成团队知识库。生成汇总报告对收集的数据进行简单分析如统计关键词并自动生成一份汇总Markdown报告通过feishu send-message发送给主管群。这个命令可以配置到你的个人电脑的crontab或 Windows 任务计划程序中每天下午6点自动运行完全无需人工干预。4.2 场景二CI/CD流水线通知与交互在现代开发运维中CI/CD流水线如GitHub Actions, GitLab CI, Jenkins会产生大量事件。将这些事件智能地通知到飞书并能快速响应极大提升效率。构建状态通知在GitHub Actions的.yml配置中在job的最后步骤添加一个run命令调用你的CLI工具将构建成功/失败的结果、耗时、代码变更链接等信息以卡片形式发送到指定的飞书群。卡片可以用颜色区分状态绿色成功红色失败。部署审批对于生产环境部署可以设置为手动审批。CLI工具在流水线中发送一张包含“批准”和“拒绝”按钮的交互卡片到审批群。审批者点击按钮后触发一个Webhook该Webhook服务再调用CI/CD平台的API来继续或终止流水线。这样审批流程就从外部系统无缝嵌入到了日常沟通工具中。错误告警聚合监控系统如Prometheus Alertmanager可以配置Webhook接收器将告警信息发送给你的一个中间服务该服务对告警进行去重、聚合然后通过CLI工具按需发送到飞书。避免刷屏同时提供更清晰的上下文。4.3 场景三飞书多维表格作为轻量级数据库飞书多维表格Bitable是一个功能强大的在线表格其API可以让我们把它当作一个轻量级的、可协作的数据库来使用。CLI工具可以成为操作这个数据库的客户端。例如管理一个服务器资产清单feishu bitable list-records --app-token xxxx --table-id xxxx列出所有服务器。feishu bitable add-record ...添加一台新服务器通过命令行参数传入IP、负责人、环境等信息。feishu bitable query --where 环境生产查询所有生产环境服务器。更进一步你可以结合其他CLI工具。比如用一个nmap扫描脚本扫描网段将发现的服务器信息自动录入飞书多维表格或者用一个健康检查脚本定期读取表格中的服务器IP进行探测并将状态更新回表格的“健康状态”字段。4.4 场景四个人效率助手CLI工具也可以服务于个人效率。快速创建日程feishu calendar create --title 团队同步会 --start-time 2023-10-27 15:00 --end-time 2023-10-27 16:00 --participants user1company.com。你可以为常用的会议模板设置别名。知识库速记feishu wiki create-page --title CLI工具踩坑记录 --content $(pbpaste)这条命令可以将你剪贴板里的内容快速粘贴成一个飞书云文档页面。通讯录查询feishu contact find --name 张三或feishu contact find --department 技术部快速找到同事信息结合mailto:或open命令直接发起邮件或聊天。5. 高级技巧与避坑指南5.1 权限管理与安全实践最小权限原则在飞书开放平台为你的应用申请权限时只勾选它真正需要的权限。例如如果只是发送消息就不要申请读取通讯录的权限。这能降低安全风险。令牌安全存储如前所述tenant_access_token有一定有效期需要缓存。切勿将缓存文件上传到Git等版本控制系统。使用keyring库是更好的选择。对于需要user_access_token的场景代表具体用户操作由于其权限更高且包含刷新令牌安全性要求更高应考虑使用OAuth 2.0的授权码模式并在服务端妥善保管。敏感信息输入对于App Secret等优先从环境变量或加密的配置文件中读取。如果必须交互式输入可以使用typer的typer.prompt(..., hide_inputTrue)功能来隐藏输入。5.2 性能优化与可靠性请求重试与退避网络请求可能失败。在封装API调用时应实现重试逻辑并采用指数退避策略。lark-oapiSDK内部已经实现了一些重试机制但了解其原理很重要。异步支持如果你的CLI工具需要发送大量消息或执行批量操作如给全部门员工发送通知同步请求会非常慢。可以考虑使用asyncio和aiohttp实现异步并发请求但要注意飞书API的速率限制。速率限制处理飞书API有明确的调用频率限制。在代码中需要捕获429 Too Many Requests错误并按照响应头中的Retry-After信息进行等待。批量操作时主动在请求间添加微小延迟如100ms是良好的实践。结果缓存对于一些不常变化的数据如部门列表、用户基本信息可以在本地进行短期缓存例如5分钟避免频繁调用API提升CLI响应速度。5.3 提升CLI工具的开发者体验丰富的输出与日志使用rich或click的样式功能为CLI的输出着色让成功、失败、警告等信息一目了然。提供--verbose或-v选项来输出详细的调试日志。自动补全typer和click都支持为ShellBash, Zsh, Fish生成自动补全脚本。在你的CLI工具中实现这个功能能极大提升使用效率。可以通过typer --install-completion来体验。配置向导提供一个feishu init或feishu setup命令以交互式问答的方式引导用户完成应用凭证的配置、权限的检查等初始化工作降低上手门槛。子命令的模块化组织当命令越来越多时将不同的功能集拆分成独立的typer.Typer()实例然后在主程序中用app.add_typer()进行挂载。这样代码结构更清晰也便于团队协作开发。5.4 常见错误排查code: 99991663msg: “tenant access token invalid”令牌无效或已过期。确保你的App ID和App Secret正确并检查认证逻辑中的令牌刷新机制是否正常工作。有时在飞书后台重置App Secret后需要清除本地的令牌缓存。code: 99991668msg: “internal server error”飞书服务器内部错误。通常是暂时的重试即可。如果持续出现检查你请求的API路径、参数格式特别是JSON是否正确。code: 99991664msg: “no permission to access”无权限访问。这是最常见的问题之一。请依次检查应用是否已添加所需权限权限是否已申请发布发布申请是否已被管理员审核通过应用是否已被安装到目标群组或企业对于机器人发送消息需要将机器人添加到群对于访问通讯录需要企业安装该应用。发送消息成功但用户收不到确认receive_id和receive_id_type匹配正确。一个常见的错误是使用了user_id但传入了open_id。确认接收方是否已经安装了该应用对于单聊或机器人是否已在群内对于群聊。检查消息内容格式是否符合对应msg_type的要求。特别是interactive卡片其JSON结构必须严格遵循飞书文档。CLI工具执行缓慢检查网络连接。确认是否在每次命令调用时都重新获取令牌应使用缓存。检查是否有同步的批量操作考虑改为异步。将飞书的能力通过CLI延伸到命令行本质上是扩展了开发者的操作空间。它让那些隐藏在图形界面后的、需要多次点击的流程变成了可编程、可组合、可自动化的原子操作。从简单的消息发送到复杂的交互式工作流这种集成带来的效率提升是线性的而是指数级的。当你习惯了用命令feishu report auto-generate来结束一天的工作或者用feishu deploy approve --env prod来触发一次线上发布时你会发现这套“长出的手脚”已经成为了你数字身体不可或缺的一部分。