手把手教你用Python脚本给飞书机器人“喂”数据:Gerrit事件通知实战
Python自动化实战用飞书机器人构建Gerrit事件通知系统每当团队协作开发时代码审查状态的实时同步总是让人头疼。想象一下你刚提交的代码被同事点赞或是某个关键补丁集终于通过审核——这些重要时刻如果能在飞书群里即时提醒整个团队的协作效率将大幅提升。本文将带你用Python打造一个智能通知系统把Gerrit代码审查事件转化为飞书的交互式卡片消息。1. 环境准备与基础配置在开始编写自动化脚本前我们需要完成两项基础工作Gerrit服务器钩子配置和飞书机器人创建。Gerrit的钩子机制允许我们在特定事件如代码提交、合并、评审人添加发生时触发自定义脚本这正是我们需要的触发器。飞书机器人创建步骤打开目标飞书群组点击右上角「设置」图标选择「群机器人」→「添加机器人」→「自定义机器人」设置机器人名称和描述如Gerrit助手记录生成的Webhook地址形如https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx在安全设置中建议选择「自定义关键词」并设置为Gerrit# Gerrit服务器上验证钩子目录存在 ls -l $GERRIT_SITE/hooks/提示确保运行脚本的机器能够访问Gerrit服务器的SSH端口默认29418和飞书API域名2. 解析Gerrit钩子参数与数据增强Gerrit触发钩子时会传递一组参数但这些基础信息往往不足以构建丰富的通知内容。我们需要通过SSH连接Gerrit查询更多元数据。以下代码展示了如何解析参数并获取完整的变更集信息#!/usr/bin/env python3 import sys import os import json from subprocess import run, PIPE # 基础参数解析 hook_type sys.argv[1] # 如patchset-created change_ref sys.argv[2] # 变更引用ID # SSH查询Gerrit获取完整变更信息 gerrit_cmd fssh -p 29418 gerrit-admingerrit.example.com gerrit query {change_ref} --formatJSON --patch-sets result run(gerrit_cmd.split(), stdoutPIPE, stderrPIPE, textTrue) if result.returncode ! 0: sys.exit(fGerrit query failed: {result.stderr}) change_data json.loads(result.stdout.splitlines()[0])关键数据字段说明字段名描述示例project代码库名称android/platform/frameworksbranch目标分支refs/heads/masterowner变更所有者{name: 张三, email: zhangsanexample.com}urlGerrit变更页面URLhttp://gerrit.example.com/c/12345commitMessage提交消息首行Fix memory leak in Bitmap handling3. 构建飞书交互式消息卡片飞书机器人支持多种消息类型其中交互式卡片最适合代码审查通知。卡片可以包含文本、分割线、按钮等元素还能设置不同的颜色主题。下面是我们设计的消息结构def build_feishu_card(hook_type, change_data): event_titles { patchset-created: 新代码提交, change-merged: 代码已合并, reviewer-added: 新增评审人 } message_elements [ { tag: div, text: { tag: lark_md, content: f**项目**: {change_data[project]}\n**分支**: {change_data[branch]}\n**提交者**: {change_data[owner][name]} } }, {tag: hr} ] if commitMessage in change_data: message_elements.insert(0, { tag: div, text: { tag: lark_md, content: f**变更描述**: {change_data[commitMessage].split(\n)[0]} } }) return { msg_type: interactive, card: { config: {wide_screen_mode: True}, header: { title: { tag: plain_text, content: fGerrit通知 - {event_titles.get(hook_type, hook_type)} }, template: wathet if hook_type change-merged else blue }, elements: message_elements [{ tag: action, actions: [{ tag: button, text: {tag: plain_text, content: 查看变更}, type: primary, url: change_data[url] }] }] } }注意飞书卡片消息有大小限制约32KB当变更描述特别长时需要做截断处理4. 异常处理与消息发送网络请求和外部命令执行都可能失败健壮的脚本需要妥善处理这些异常情况。我们使用Python的requests库发送消息并添加重试机制import requests from time import sleep def send_feishu_message(webhook_url, message, max_retries3): for attempt in range(max_retries): try: response requests.post( webhook_url, jsonmessage, headers{Content-Type: application/json}, timeout5 ) response.raise_for_status() return True except requests.exceptions.RequestException as e: if attempt max_retries - 1: print(fFailed to send message after {max_retries} attempts: {e}) return False sleep(2 ** attempt) # 指数退避 # 主执行逻辑 if __name__ __main__: webhook_url https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_KEY card_message build_feishu_card(hook_type, change_data) if not send_feishu_message(webhook_url, card_message): sys.exit(Message delivery failed)常见错误处理策略SSH连接失败检查Gerrit服务器SSH配置和网络连通性JSON解析错误验证gerrit query命令的输出格式飞书API限流实现退避重试逻辑如代码所示安全验证失败确认飞书机器人关键词或签名配置正确5. 部署与扩展实践将脚本部署到Gerrit服务器后需要将其设置为对应钩子的处理器。例如对于patchset-created事件# 在Gerrit的hooks目录下创建可执行文件 cat /path/to/gerrit/hooks/patchset-created EOF #!/bin/sh python3 /opt/gerrit-notify/feishu_notify.py $ EOF chmod x /path/to/gerrit/hooks/patchset-created系统扩展方向多平台支持同样的架构可以适配企业微信、钉钉等平台只需修改消息构建逻辑消息模板定制通过配置文件定义不同事件的消息格式审批流程集成在飞书卡片中添加通过/拒绝按钮通过飞书审批驱动Gerrit评审数据持久化将通知记录存入数据库便于后续分析团队代码审查效率# 扩展示例支持企业微信的消息格式转换 def convert_to_wecom_message(feishu_card): return { msgtype: text, text: { content: Gerrit通知 extract_plain_text(feishu_card) } }6. 性能优化与监控当代码库活跃度高时通知系统可能面临性能压力。以下是几个优化方向SSH连接池优化from persistent_ssh import PersistentSSH # 复用SSH连接而不是每次新建 ssh_client PersistentSSH( hostgerrit.example.com, port29418, usernamegerrit-admin ) def query_gerrit(ref): stdin, stdout, stderr ssh_client.exec_command( fgerrit query {ref} --formatJSON ) return json.load(stdout)监控指标收集指标名称采集方式告警阈值钩子触发频率脚本日志统计50次/分钟消息发送延迟时间戳差值5秒失败通知比例错误日志分析5%在团队实际使用中这套系统将代码审查事件的响应时间从人工主动检查的几小时缩短到实时通知特别是对于跨时区协作的团队效果更为明显。一个实用的建议是为不同类型的通知设置不同的飞书卡片颜色如合并成功用绿色新提交用蓝色这样在群聊中能快速识别事件重要性。