Files
GiteaToFeishuMsg/README.md

6.6 KiB
Raw Blame History

Gitea 到飞书 Webhook 中转服务

将 Gitea 的工单事件(创建、更新、关闭等)通过 Webhook 接收,转换为美观的飞书卡片消息,并转发到飞书群聊。

功能特性

  • 接收 Gitea Webhook 事件(支持工单相关动作)
  • 验证 Webhook 签名(可选)
  • 将事件转换为飞书交互式卡片
  • 支持自定义卡片标题、颜色、字段
  • 完整的错误处理和日志记录
  • 健康检查端点
  • 易于部署和配置

系统架构

Gitea → Webhook → 中转服务 (Express) → 飞书机器人 → 飞书群聊

快速开始

前提条件

  • Node.js 18+
  • 一个飞书机器人,并获取其 Webhook URL
  • Gitea 实例(版本 1.20+

安装

  1. 克隆仓库
git clone <repository-url>
cd gitea-feishu-webhook-relay
  1. 安装依赖
npm install
  1. 配置环境变量 复制 .env.example.env 并填写实际值:
cp .env.example .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

npm run dev

生产模式:

npm start

服务将在 http://localhost:3000 启动。

配置 Gitea Webhook

重要:选择正确的 Webhook 类型

确保在 Gitea 中创建 Webhook 时选择 “Gitea” 类型而不是“飞书”或其他类型。Gitea 类型会发送结构化的 JSON 数据,便于解析。

详细字段填写(根据用户界面)

在 Gitea 的 Webhook 创建页面中,请按以下说明填写:

字段 填写示例 说明
目标 URL http://192.168.0.15:3001http://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 便于容器化部署。

构建镜像:

docker build -t gitea-feishu-relay .

运行容器:

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      # 日志工具

测试

运行单元测试:

npm test

测试建议

1. 启动服务

确保服务已运行并监听正确端口:

npm start

检查控制台输出是否有 Server listening on port 3001(或你设置的端口)。

2. 健康检查

使用 curl 或浏览器访问健康检查端点:

curl http://localhost:3001/health

应返回 {"status":"ok","timestamp":"..."}

3. 模拟 Gitea Webhook 请求

你可以使用 curl 发送一个模拟的 Gitea 工单事件来测试转换和转发功能:

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/ 目录,或直接在控制台查看。关注 infoerror 级别的消息。

故障排除

  1. 收不到飞书消息

    • 检查 FEISHU_WEBHOOK_URL 是否正确
    • 查看日志中是否有错误信息
    • 确认飞书机器人已加入群聊
  2. Gitea Webhook 验证失败

    • 确保 GITEA_WEBHOOK_SECRET 与 Gitea 中设置的密钥一致
    • 检查请求头中是否包含 X-Gitea-Signature
  3. 服务无法启动

    • 确认端口未被占用
    • 检查 Node.js 版本
  4. Webhook 请求被忽略

    • 确认 Gitea 发送的 JSON 格式符合预期(包含 actionissuerepository
    • 检查日志中是否有 Event ignored 消息,可能是动作被过滤(如 labeled

许可证

MIT