GitLab Bot Manager 是一个自部署的 GitLab Webhook 通知管理服务。它接收 GitLab 项目事件,使用 Mustache 模板渲染消息,并将结果推送到企业微信或飞书群机器人。
项目目标是把“代码事件通知”从硬编码脚本升级为可管理的平台:推送组、Webhook 地址、消息模板、用户映射、推送日志和可选的 CI 失败分析都可以通过 Web 控制台维护。
- 将 GitLab 的 Push、Merge Request、Pipeline、Tag、Issue、Note、Wiki、Deployment、Build 等事件转为群消息。
- 为不同项目、团队或环境创建独立推送组,避免所有通知混在一个群。
- 通过模板统一通知格式,让研发、测试、运维能够快速理解事件状态。
- 将 GitLab 用户映射到企业微信或飞书用户,实现更准确的 @ 提醒。
- 记录每次推送的原始事件、渲染消息、成功状态和错误原因,方便排查通知丢失。
- 可选接入 OpenAI 兼容 API,对失败的 CI Job 日志生成原因分析和修复建议。
- 使用 SQLite 和 Docker Compose 部署,适合小团队或内网环境快速落地。
GitLab 项目产生事件
|
v
GitLab Webhook 请求 POST /{推送组名称}
|
v
服务按 URL 路径查找启用的推送组
|
v
校验事件类型是否在该推送组订阅范围内
|
v
归一化 GitLab 事件类型并补充 GB_ 自定义变量
|
v
按平台、事件类型和推送组匹配消息模板
|
v
使用 Mustache 渲染企业微信或飞书消息
|
v
根据用户映射生成 @ 提醒文本
|
v
调用群机器人 Webhook 推送消息
|
v
写入 push_logs,保存成功或失败结果
推送组是消息路由的核心配置。一个推送组通常对应一个 GitLab Webhook URL 和一个 IM 群机器人。
每个推送组可以配置:
- 推送组名称:作为 Webhook URL 的路径。
- IM 平台:企业微信或飞书。
- 群机器人 Webhook URL。
- 订阅事件:例如
push、merge_request、pipeline。 - MR 动作过滤:例如只推送 Open、Merge、Close 等指定动作。
- 时区:用于消息中的时间格式化。
- GitLab 项目信息:可用于自动创建或同步项目 Webhook。
- 备注说明:用于区分团队、项目或环境。
示例 Webhook URL:
https://your-domain.example.com/backend-team
GitLab 请求该地址后,服务会查找名称为 backend-team 的推送组,并按该组配置完成消息转发。
模板使用 Mustache 语法,支持 GitLab 原始字段和服务生成的 GB_ 自定义变量。
常用变量示例:
| 变量 | 说明 |
|---|---|
{{user.name}} |
触发事件的用户名称 |
{{project.name}} |
GitLab 项目名称 |
{{project.web_url}} |
GitLab 项目地址 |
{{object_attributes.ref}} |
Pipeline 分支或引用 |
{{GB_branch}} |
归一化后的分支名称 |
{{GB_status.str}} |
归一化后的状态文本 |
{{GB_pipelineUrl}} |
Pipeline 完整地址 |
{{GB_failed_jobs}} |
失败 Job 列表 |
{{GB_success_jobs}} |
成功 Job 列表 |
{{GB_failure_analysis}} |
可选的 AI 失败分析结果 |
模板优先级:
推送组专属模板 > 平台事件默认模板 > 系统默认模板
这样可以做到同一类事件有统一格式,同时允许重点项目使用更细致的模板。
服务会从 GitLab Webhook payload 中提取用户信息,例如作者、提交人、MR 指派人、审核人等,然后查询用户映射表。
GitLab 用户 ID / 用户名
|
v
user_mappings
|
v
企业微信或飞书用户 ID
|
v
平台专属 @ 语法
平台格式:
- 企业微信:
<@userid> - 飞书:
<at id=userid></at>
推送日志用于审计和排障。日志会记录:
- 推送组
- GitLab 项目
- 事件类型
- 触发用户
- 分支或 MR 信息
- 原始 payload
- 渲染后的消息
- 推送成功状态
- 错误信息
- 创建时间
如果群机器人配置错误、网络失败、模板渲染异常或平台返回错误,可以通过日志页面追踪原因。
当 Pipeline 失败且功能启用时,服务可以读取失败 Job 日志,并调用 OpenAI 兼容接口生成分析结果。
该功能适合用于:
- 快速总结 CI 失败原因。
- 给出修复建议。
- 在通知中直接显示失败 Job、失败阶段和可能处理方式。
该能力是可选功能。没有配置 ONE_API_BASE_URL 和 ONE_API_KEY 时不会启用。
| 分类 | 功能 |
|---|---|
| Webhook 接收 | 接收 GitLab Push、MR、Pipeline、Tag、Issue、Note、Wiki、Deployment、Build 等事件 |
| 多平台推送 | 支持企业微信和飞书群机器人 |
| 推送组管理 | 创建、编辑、禁用、测试推送组,按组订阅事件 |
| 模板管理 | 按平台和事件维护模板,支持预览、测试推送和变量参考 |
| 用户映射 | 维护 GitLab 用户与 IM 用户关系,实现精准 @ |
| 日志审计 | 查询推送历史、成功率、错误信息和原始 payload |
| 仪表盘 | 查看今日推送量、成功率、活跃推送组和映射数量 |
| 集成配置 | 配置 GitLab API、企业微信通讯录、飞书通讯录等信息 |
| AI 分析 | 可选分析失败 Pipeline 的 Job 日志 |
| 部署 | 支持 Dockerfile 和 Docker Compose |
| 层级 | 技术 |
|---|---|
| 后端 | Hono、TypeScript、Drizzle ORM、better-sqlite3、Zod |
| 前端 | React、Vite、Tailwind CSS、TanStack Query、Zustand |
| 共享包 | TypeScript 类型和 Zod Schema |
| 模板引擎 | Mustache |
| 数据库 | SQLite |
| 包管理 | pnpm |
| Monorepo | Turborepo |
gitlab-bot/
├── apps/
│ ├── server/ # Hono 后端服务
│ │ ├── src/
│ │ │ ├── routes/ # Webhook 和管理 API
│ │ │ ├── services/ # Webhook、GitLab、企业微信、飞书、LLM 服务
│ │ │ ├── db/ # Drizzle Schema、启动修复和种子数据
│ │ │ ├── middleware/ # 认证和请求日志
│ │ │ └── lib/ # 工具函数和模板变量文档
│ │ ├── drizzle/ # SQL 迁移
│ │ └── data/ # SQLite 数据目录
│ └── web/ # React 管理界面
│ └── src/
│ ├── pages/ # 仪表盘、推送组、模板、映射、日志、设置
│ ├── components/ # 页面组件和配置组件
│ ├── api/ # API 请求封装
│ ├── hooks/ # 前端 Hooks
│ └── stores/ # Zustand 状态
├── packages/
│ └── shared/ # 前后端共享类型和 Schema
├── sample_json/ # GitLab Webhook 示例 payload
├── docs/images/ # README 图片资源
├── Dockerfile
├── docker-compose.yml
└── README.md
- Node.js 20+
- pnpm 10+
pnpm install
pnpm db:push
pnpm db:seed
pnpm dev默认访问地址:
| 服务 | 地址 |
|---|---|
| 后端 API | http://localhost:7001 |
| 前端界面 | http://localhost:5173 |
本地开发未配置环境变量时,后端会使用开发默认值:
- 管理员密码:
admin - 只读用户密码:默认关闭,设置
USER_PASSWORD后启用
生产或共享环境必须显式配置密码和 JWT 密钥。
复制环境变量示例:
cp .env.production.example .env至少设置:
JWT_SECRET=replace-with-a-long-random-secret
ADMIN_PASSWORD=replace-with-a-strong-admin-password启动服务:
docker compose up -d默认端口映射:
http://localhost:7002
SQLite 数据默认挂载到 ${DATA_DIR:-./data}。
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
NODE_ENV |
否 | Compose 中为 production |
运行环境 |
PORT |
否 | 7001 |
后端监听端口 |
JWT_SECRET |
生产必填 | 本地开发 fallback | JWT 签名密钥 |
ADMIN_PASSWORD |
生产必填 | 本地开发为 admin |
管理员登录密码 |
USER_PASSWORD |
否 | 空 | 可选只读用户密码 |
DATABASE_URL |
否 | file:./data/gitlab-bot.db |
SQLite 数据库路径 |
LOG_LEVEL |
否 | INFO |
日志级别 |
BASE_URL |
否 | 按本地端口生成 | 自动创建 GitLab Hook 时使用的公网地址 |
ONE_API_BASE_URL |
否 | 空 | OpenAI 兼容 API 地址 |
ONE_API_KEY |
否 | 空 | AI 分析 API Key |
ONE_API_MODEL |
否 | gpt-4o |
AI 分析模型 |
WECOM_CORP_ID |
否 | 空 | 企业微信通讯录集成 Corp ID |
WECOM_AGENT_SECRET |
否 | 空 | 企业微信通讯录集成 Secret |
- 登录管理界面并创建推送组。
- 在推送组里填写企业微信或飞书群机器人 Webhook。
- 复制该推送组对应的接入地址。
- 进入 GitLab 项目:Settings -> Webhooks。
- 填写 URL:
https://your-domain.example.com/{推送组名称}
- 勾选需要推送的事件:
- Push events
- Merge request events
- Pipeline events
- Tag push events
- Issues events
- Comments
- Wiki page events
- 保存后使用 GitLab 的 Test 功能验证通知是否送达。
管理接口位于 /api/v1。
| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/api/v1/login |
登录并获取 JWT |
GET |
/api/v1/groups |
获取推送组列表 |
POST |
/api/v1/groups |
创建推送组 |
PUT |
/api/v1/groups/:id |
更新推送组 |
DELETE |
/api/v1/groups/:id |
删除推送组 |
POST |
/api/v1/groups/:id/test |
发送测试消息 |
GET |
/api/v1/templates |
获取模板列表 |
POST |
/api/v1/templates |
创建模板 |
PUT |
/api/v1/templates/:id |
更新模板 |
DELETE |
/api/v1/templates/:id |
删除模板 |
GET |
/api/v1/mappings |
获取用户映射 |
POST |
/api/v1/mappings |
创建用户映射 |
PUT |
/api/v1/mappings/:id |
更新用户映射 |
DELETE |
/api/v1/mappings/:id |
删除用户映射 |
GET |
/api/v1/logs |
查询推送日志 |
GET |
/api/v1/logs/stats |
获取统计数据 |
GET |
/api/v1/system-config |
获取集成配置 |
PUT |
/api/v1/system-config |
更新集成配置 |
GET |
/api/v1/llm-config |
获取 AI 分析配置 |
PUT |
/api/v1/llm-config |
更新 AI 分析配置 |
Webhook 接收接口:
POST /{groupName}项目使用 SQLite 和 Drizzle ORM。
| 表 | 说明 |
|---|---|
webhook_groups |
推送组和订阅事件 |
message_templates |
消息模板 |
template_group_mappings |
模板与推送组关系 |
user_mappings |
GitLab 用户与 IM 用户映射 |
push_logs |
推送日志 |
system_config |
GitLab 和 IM 集成配置 |
roast_config |
AI 分析配置,保留历史表名以兼容旧迁移 |
数据库命令:
pnpm db:push
pnpm db:seed
pnpm db:generatepnpm dev
pnpm --filter @gitlab-bot/server dev
pnpm --filter @gitlab-bot/web dev
pnpm build
pnpm lint
pnpm test
pnpm format- 不要提交
.env、SQLite 数据库文件或生产密钥。 - 生产环境必须设置
JWT_SECRET和ADMIN_PASSWORD。 - 对外暴露服务时建议使用 HTTPS 和反向代理。
- 群机器人 Webhook URL 具备发消息能力,应按密钥处理。
- 如果 Webhook URL、API Key 或数据库曾经泄漏,应及时轮换。
push_logs会保存原始 payload 和渲染消息,生产环境需要评估日志保留周期。
本仓库已按公开发布标准处理:
- 移除私有 CI/CD 部署脚本。
- 移除私有服务器、内网仓库和私有镜像仓库地址。
- 移除硬编码生产密码。
- 移除本地
.env和数据库文件。 - 示例 payload 中的地址统一替换为公开示例域名。
MIT