Files
GiteaToFeishuMsg/README.md

242 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gitea 到飞书 Webhook 中转服务
将 Gitea 的工单事件(创建、更新、关闭等)通过 Webhook 接收,转换为美观的飞书卡片消息,并转发到飞书群聊。
## 功能特性
- 接收 Gitea Webhook 事件(支持工单相关动作)
- 验证 Webhook 签名(可选)
- 将事件转换为飞书交互式卡片
- 支持自定义卡片标题、颜色、字段
- 完整的错误处理和日志记录
- 健康检查端点
- 易于部署和配置
## 系统架构
```
Gitea → Webhook → 中转服务 (Express) → 飞书机器人 → 飞书群聊
```
## 快速开始
### 前提条件
- Node.js 18+
- 一个飞书机器人,并获取其 Webhook URL
- Gitea 实例(版本 1.20+
### 安装
1. 克隆仓库
```bash
git clone <repository-url>
cd gitea-feishu-webhook-relay
```
2. 安装依赖
```bash
npm install
```
3. 配置环境变量
复制 `.env.example``.env` 并填写实际值:
```bash
cp .env.example .env
```
编辑 `.env`
```env
PORT=3000
GITEA_WEBHOOK_SECRET=your_gitea_webhook_secret
FEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/xxx
LOG_LEVEL=info
```
### 运行
开发模式(使用 nodemon
```bash
npm run dev
```
生产模式:
```bash
npm start
```
服务将在 `http://localhost:3000` 启动。
## 配置 Gitea Webhook
### 重要:选择正确的 Webhook 类型
确保在 Gitea 中创建 Webhook 时选择 **“Gitea”** 类型而不是“飞书”或其他类型。Gitea 类型会发送结构化的 JSON 数据,便于解析。
### 详细字段填写(根据用户界面)
在 Gitea 的 Webhook 创建页面中,请按以下说明填写:
| 字段 | 填写示例 | 说明 |
|------|----------|------|
| **目标 URL** | `http://192.168.0.15:3001``http://192.168.0.15:3001/webhook/gitea` | 根据你的服务地址和端口默认为3000若修改了环境变量 `PORT` 则对应调整)。如果服务部署在本地,请使用内网 IP。 |
| **HTTP 方法** | `POST` | 保持默认。 |
| **内容类型** | `application/json` | 保持默认。 |
| **授权标头** | (留空) | 除非你的服务需要 Bearer 或 Basic 认证,否则不需要填写。 |
| **密钥** | (可选)填写与 `GITEA_WEBHOOK_SECRET` 环境变量相同的字符串 | 用于验证 Webhook 请求的签名,增强安全性。如果留空,服务将跳过签名验证。 |
| **触发事件** | 勾选 **“工单事件”**Issue | 可根据需要勾选其他事件,但本服务目前只处理工单事件。 |
### 步骤
1. 进入 Gitea 仓库的设置 → Webhooks → 添加 Webhook。
2. 选择 **“Gitea”** 类型(不要选“飞书”或“自定义”)。
3. 按照上表填写各字段。
4. 点击“添加 Webhook”保存。
### 验证
保存后Gitea 会立即发送一个测试事件ping。检查服务日志以确认接收成功。如果看到日志输出 `Received Gitea webhook` 且没有错误,说明配置正确。
## 飞书机器人配置
1. 在飞书开放平台创建一个自定义机器人,获取 Webhook URL。
2. 将机器人添加到目标群聊。
3. 将 Webhook URL 填入 `FEISHU_WEBHOOK_URL`
## API 端点
- `GET /health` 健康检查
- `POST /webhook/gitea` 接收 Gitea Webhook推荐
- `POST /` 接收 Gitea Webhook备用兼容旧配置
## 日志
日志使用 Winston 输出到控制台和文件:
- `logs/error.log` 错误日志
- `logs/combined.log` 所有日志
## Docker 部署
提供 Dockerfile 便于容器化部署。
构建镜像:
```bash
docker build -t gitea-feishu-relay .
```
运行容器:
```bash
docker run -p 3000:3000 --env-file .env gitea-feishu-relay
```
## 环境变量
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| PORT | 服务监听端口 | 3000 |
| GITEA_WEBHOOK_SECRET | Gitea Webhook 签名密钥 | (空) |
| FEISHU_WEBHOOK_URL | 飞书机器人 Webhook URL | (必需) |
| LOG_LEVEL | 日志级别 (error, warn, info, debug) | info |
| NODE_ENV | 运行环境 (development, production) | development |
## 开发
### 项目结构
```
src/
├── server.js # Express 服务器入口
├── config.js # 配置管理
├── webhooks/
│ └── gitea.js # Webhook 处理器
├── transformers/
│ └── giteaToFeishu.js # 消息转换器
├── clients/
│ └── feishu.js # 飞书 API 客户端
└── utils/
└── logger.js # 日志工具
```
### 测试
运行单元测试:
```bash
npm test
```
## 测试建议
### 1. 启动服务
确保服务已运行并监听正确端口:
```bash
npm start
```
检查控制台输出是否有 `Server listening on port 3001`(或你设置的端口)。
### 2. 健康检查
使用 curl 或浏览器访问健康检查端点:
```bash
curl http://localhost:3001/health
```
应返回 `{"status":"ok","timestamp":"..."}`
### 3. 模拟 Gitea Webhook 请求
你可以使用 `curl` 发送一个模拟的 Gitea 工单事件来测试转换和转发功能:
```bash
curl -X POST http://localhost:3001/webhook/gitea \
-H "Content-Type: application/json" \
-H "X-Gitea-Signature: sha256=..." \
-d '{
"action": "opened",
"issue": {
"id": 123,
"number": 45,
"title": "测试工单",
"body": "这是一个测试工单",
"state": "open",
"created_at": "2025-12-02T05:00:00Z",
"user": {
"id": 1,
"login": "testuser",
"full_name": "测试用户"
},
"assignee": null,
"labels": [],
"milestone": null
},
"repository": {
"id": 1,
"name": "test-repo",
"full_name": "org/test-repo",
"html_url": "https://gitea.example.com/org/test-repo"
},
"sender": {
"id": 1,
"login": "testuser"
}
}'
```
如果配置了 `FEISHU_WEBHOOK_URL`,服务会将转换后的卡片发送到飞书群聊。检查服务日志和飞书群聊以确认消息送达。
### 4. 查看日志
日志文件位于 `logs/` 目录,或直接在控制台查看。关注 `info``error` 级别的消息。
## 故障排除
1. **收不到飞书消息**
- 检查 `FEISHU_WEBHOOK_URL` 是否正确
- 查看日志中是否有错误信息
- 确认飞书机器人已加入群聊
2. **Gitea Webhook 验证失败**
- 确保 `GITEA_WEBHOOK_SECRET` 与 Gitea 中设置的密钥一致
- 检查请求头中是否包含 `X-Gitea-Signature`
3. **服务无法启动**
- 确认端口未被占用
- 检查 Node.js 版本
4. **Webhook 请求被忽略**
- 确认 Gitea 发送的 JSON 格式符合预期(包含 `action``issue``repository`
- 检查日志中是否有 `Event ignored` 消息,可能是动作被过滤(如 `labeled`
## 许可证
MIT