{"id":27958490,"url":"https://github.com/apts-1547/onebot-github-webhook","last_synced_at":"2025-10-08T03:40:11.508Z","repository":{"id":287744448,"uuid":"965623204","full_name":"AptS-1547/onebot-github-webhook","owner":"AptS-1547","description":"一个用于接收 GitHub Webhook 并通过 OneBot 协议将推送通知转发到 QQ 群的服务。","archived":false,"fork":false,"pushed_at":"2025-07-29T12:38:59.000Z","size":501,"stargazers_count":5,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-29T15:18:10.640Z","etag":null,"topics":["github-webhook","onebot"],"latest_commit_sha":null,"homepage":"http://onebot-github-webhook.docs.ecaps.top/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AptS-1547.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-13T15:12:35.000Z","updated_at":"2025-07-29T12:38:56.000Z","dependencies_parsed_at":"2025-07-29T14:39:17.387Z","dependency_job_id":"cb5dfa44-619e-4a3a-aac1-aed3c4b30711","html_url":"https://github.com/AptS-1547/onebot-github-webhook","commit_stats":null,"previous_names":["apts-1547/onebot-github-webhook"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/AptS-1547/onebot-github-webhook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AptS-1547%2Fonebot-github-webhook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AptS-1547%2Fonebot-github-webhook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AptS-1547%2Fonebot-github-webhook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AptS-1547%2Fonebot-github-webhook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AptS-1547","download_url":"https://codeload.github.com/AptS-1547/onebot-github-webhook/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AptS-1547%2Fonebot-github-webhook/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278886408,"owners_count":26062973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github-webhook","onebot"],"created_at":"2025-05-07T18:24:48.431Z","updated_at":"2025-10-08T03:40:11.503Z","avatar_url":"https://github.com/AptS-1547.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./docs/src/resources/logo.png\" alt=\"OneBot GitHub Webhook Logo\"\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n# OneBot GitHub Webhook\n\n_✨ GitHub Webhook 推送消息到 QQ 群 ✨_\n\n\u003ca href=\"https://www.codefactor.io/repository/github/AptS-1547/onebot-github-webhook/\"\u003e\n  \u003cimg src=\"https://www.codefactor.io/repository/github/AptS-1547/onebot-github-webhook/badge\" alt=\"CodeFactor\" /\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://github.com/AptS-1547/onebot-github-webhook/activity\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/last-commit/AptS-1547/onebot-github-webhook/master\" alt=\"Last Commit\"/\u003e\n\u003c/a\u003e\n\n\u003ca href=\"./LICENSE\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/license/AptS-1547/onebot-github-webhook\" alt=\"Apache License 2.0\" /\u003e\n\u003c/a\u003e\n\n\u003cimg src=\"https://img.shields.io/badge/python-3.9+-blue.svg\" alt=\"python\"\u003e\n\u003c/div\u003e\n\n## 功能特点\n\n### 现有功能\n\n- **Webhook 事件接收**：接收并处理 GitHub 的 Webhook 推送事件\n- **安全验证**：支持 Webhook 签名验证，确保请求安全性\n- **OneBot 协议支持**：通过 OneBot 协议将推送信息转发到指定的 QQ 群或私聊\n- **灵活配置**：可配置监听的仓库、分支和事件类型\n- **高级匹配规则**：\n  - **仓库匹配**：支持通配符模式（如 `user/*`、`*/*-api`、`org/[abc]*` 等）\n  - **分支匹配**：支持通配符模式（如 `main`、`release-*`、`feature/*` 等）\n  - 大小写不敏感匹配\n- **格式化消息**：结构化的推送通知，包含仓库、分支、推送者和最新提交信息\n\n### 计划实现功能\n\n- **GitHub API 轮询**：\n  - 为无法设置 Webhook 的场景提供定时轮询机制\n  - 支持自定义轮询间隔\n  - 检测提交、PR、Issue 等变化\n  \n- **自定义模板系统**：\n  - 支持用户自定义消息格式\n  - Jinja2 模板语法\n  - 支持不同事件类型的独立模板\n  - 多种消息格式（纯文本、Markdown、JSON 等）\n\n- **更多事件支持**：\n  - Issues 事件（创建、关闭、重新打开）\n  - Pull Request 事件（创建、合并、评论）\n  - Release 事件（发布、预发布）\n  - Discussion 事件\n\n- **统计与监控**：\n  - 处理事件统计\n  - 服务健康检查\n  - Prometheus 指标导出\n\n## 部署建议\n\n### Docker 部署\n\n**⚠️ 注意: 请确保 `config.yaml` 存在于当前目录下，否则 Docker 容器将无法找到配置文件。**\n\n首先，确保 Docker 和 Docker Compose 已安装。  \n并且请你复制项目中的 `config.example.yaml` 为 `config.yaml`，并根据需要修改配置。  \n然后，使用以下命令启动 Docker 容器：  \n\n```bash\ndocker run -d \\\n  --name onebot-github-webhook \\\n  -p 8000:8000 \\\n  -v $(pwd)/config.yaml:/app/config.yaml \\\n  e1saps/onebot-github-webhook:latest\n```\n\n或使用 Docker Compose，参考文件 `docker/docker-compose.yml`：\n\n```bash\ncd docker\ndocker-compose up -d\n```\n\n### Systemd 服务\n\n创建 `/etc/systemd/system/onebot-github-webhook.service`:\n\n```ini\n[Unit]\nDescription=OneBot GitHub Webhook Service\nAfter=network.target\n\n[Service]\nUser=www-data\nWorkingDirectory=/opt/onebot-github-webhook\nExecStart=/opt/onebot-github-webhook/.venv/bin/python -m uvicorn main:app --host 0.0.0.0 --port 8000\nRestart=on-failure\nRestartSec=5s\n\n[Install]\nWantedBy=default.target\n```\n\n启用服务:\n\n```bash\nsudo systemctl enable onebot-github-webhook\nsudo systemctl start onebot-github-webhook\n```\n\n## GitHub Webhook 设置\n\n1. 在 GitHub 仓库中前往 Settings -\u003e Webhooks -\u003e Add webhook\n2. Payload URL 设置为 `http://你的服务器地址:8000/github-webhook`\n3. Content type 选择 `application/json`\n4. Secret 填写与配置文件中 `SECRET` 相同的值\n5. 选择需要监听的事件（或选择 \"Send me everything\" 接收所有事件）\n6. 启用 webhook（勾选 \"Active\"）\n\n## 配置说明\n\n配置文件 config.yaml 的结构如下：\n\n```yaml\nENV: \"production\"  # 环境变量，可选值为 \"production\" 或 \"development\"\nONEBOT_URL: \"ws://localhost:8080/ws\"  # OneBot 连接地址\nONEBOT_TYPE: \"ws\"  # OneBot 连接类型，可选值为 \"ws\" 或 \"http\"\nONEBOT_ACCESS_TOKEN: \"your_token\"  # OneBot 访问令牌\n\nGITHUB_WEBHOOK:\n  - NAME: \"github\"  # webhook 名称\n    REPO:  # 监听的仓库列表，支持通配符匹配\n      - \"username/repo\"\n      - \"username/*\"\n      - \"*/*-api\"\n    BRANCH:  # 监听的分支列表，支持通配符匹配\n      - \"main\"\n      - \"develop\"\n      - \"feature/*\"\n      - \"release-*\"\n    SECRET: \"your_secret\"  # GitHub Webhook 密钥\n    EVENTS:  # 监听的事件类型\n      - \"push\"\n      - \"pull_request\"\n      - \"issues\"\n      - \"issue_comment\"\n      - \"release\"\n    ONEBOT:  # 通知的 OneBot 目标列表\n      - type: \"group\"  # 目标类型，可选值为 \"group\" 或 \"private\"\n        id: 123456789  # 目标 ID，群号或用户 ID\n```\n\n## 本地开发\n\n1. 克隆本仓库：\n\n```bash\ngit clone https://github.com/AptS-1547/onebot-github-webhook\ncd onebot-github-webhook\n```\n\n2. 创建并激活虚拟环境：\n\n```bash\npython -m venv .venv\nsource .venv/bin/activate  # Linux/Mac\n# 或者 .venv\\Scripts\\activate  # Windows\n```\n\n3. 安装依赖：\n\n```bash\npip install -r requirements.txt\n# 或者使用 Poetry\n# poetry install\n```\n\n4. 配置文件设置：\n\n在程序第一次运行时会自动生成 config.yaml 文件，您可以根据需要修改其中的配置项。  \n或者复制示例配置文件：\n\n```bash\ncp config.example.yaml config.yaml\n```\n\n### 运行\n\n```bash\nuvicorn main:app --host 0.0.0.0 --port 8000\n```\n\n或者直接执行：\n\n```bash\npython main.py\n```\n\n## 开发路线图\n\n### 1. GitHub API 轮询（计划中）\n\n对于无法使用 webhook 的场景（如私有仓库或受限环境），我们计划实现基于 GitHub API 的轮询机制。\n\n#### 设计概要\n\n- **配置方式**：\n\n```yaml\nGITHUB_API_POLLING:\n  - NAME: \"polling-example\"\n    REPO:\n      - \"username/repo\"\n    BRANCH:\n      - \"main\"\n    INTERVAL: 300  # 轮询间隔（秒）\n    EVENTS:\n      - \"push\"\n      - \"pull_request\"\n    TOKEN: \"github_personal_access_token\"  # GitHub 个人访问令牌\n    ONEBOT:\n      - type: \"group\"\n        id: 123456789\n```\n\n- **功能**：\n  - 定时检查仓库变更\n  - 对比上次轮询结果，只通知新变更\n  - 支持提交、PR、Issue 等多种数据类型轮询\n  - 优化请求频率，避免触发 GitHub API 限流\n\n- **实现计划**：\n  - 使用 `APScheduler` 实现定时任务\n  - 使用 `aiohttp` 实现异步 HTTP 请求\n  - 使用本地文件存储上次轮询状态 ~~（轻量化的玩意不可能给你上数据库 or Redis）~~\n  - 封装 GitHub API 客户端，处理认证和错误\n\n### 2. 自定义模板系统（计划中）\n\n允许用户自定义各类事件的通知消息格式，提供更灵活的展示方式。\n\n#### 设计概要\n\n- **模板存储**：\n  - 模板文件存储在 `templates/` 目录下\n  - 按照事件类型命名，如 `templates/push.txt`、`templates/issues.txt` 等\n  - 也可以创建自定义命名的模板文件用于不同场景\n\n- **配置方式**：\n\n  ```yaml\n  GITHUB_WEBHOOK:\n    - NAME: \"github\"\n      REPO:\n        - \"username/repo\"\n      BRANCH:\n        - \"main\"\n      SECRET: \"your_secret\"\n      EVENTS:\n        - \"push\"\n        - \"issues\"\n      TEMPLATES:  # 为不同事件类型指定自定义模板\n        push: \"custom_push.txt\"  # 使用自定义推送模板\n        issues: \"default\"  # 使用默认 issues 模板\n      ONEBOT:\n        - type: \"group\"\n          id: 123456789\n  ```\n\n- **模板示例** (`templates/push.txt`):\n\n  ```\n  📢 GitHub 推送通知\n  仓库：{{ repo_name }}\n  分支：{{ branch }}\n  推送者：{{ pusher }}\n  提交数量：{{ commit_count }}\n  {% for commit in commits %}\n  [{{ loop.index }}] {{ commit.id[:7] }} by {{ commit.author.name }}\n      {{ commit.message.split('\\n')[0] }}\n  {% endfor %}\n  ```\n\n- **模板示例** (`templates/issues.txt`):\n\n  ```\n  📋 Issue {{ action }}\n  仓库：{{ repo_name }}\n  标题：{{ issue.title }}\n  作者：{{ issue.user.login }}\n  链接：{{ issue.html_url }}\n  ```\n\n- **功能**：\n  - 基于 Jinja2 模板引擎\n  - 支持条件语句和循环\n  - 每个 Webhook 可以指定不同的模板集合\n  - 提供默认模板，无需配置即可使用\n  - 模板变量自动文档化（将提供变量参考）\n\n- **实现计划**：\n  - 引入 Jinja2 依赖\n  - 实现模板目录扫描和加载机制\n  - 开发模板缓存以提高性能\n  - 提供模板变量参考文档\n  - 添加模板验证功能，避免语法错误\n\n## 项目结构\n\n```\nonebot-github-webhook/\n│\n├── app/                      # 应用程序核心模块\n│   ├── api/                  # API 接口\n|   ├   └── github_webhook.py # GitHub Webhook 接口\n│   ├── core/                 # 核心功能\n│   │   └── github.py         # GitHub Webhook 处理逻辑\n│   ├── models/               # 数据模型\n│   │   └── config.py         # 配置模型\n|   ├── onebot/               # OneBot 发送器\n│   │   └── onebot.py         # OneBot 消息发送客户端\n│   └── utils/                # 工具函数\n|       ├── exceptions.py     # 异常处理\n│       └── matching.py       # 匹配规则工具\n│\n├── config/                   # 配置文件目录\n│   ├── config.example.yaml   # 示例配置文件\n│   └── templates/            # 消息模板目录\n│       ├── push/             # 推送事件模板\n│       ├── issues/           # Issue 事件模板\n│       └── pull_request/     # Pull Request 事件模板\n│\n├── docs/                     # 文档目录\n│   └── src/                  # mdBook 文档源\n│\n├── tests/                    # 测试目录\n│   ├── test_matching.py      # 匹配规则测试\n│   ├── test_onebot_sender.py # OneBot 发送器测试\n│   └── test_webhook_signature.py # Webhook 签名验证测试\n│\n├── docker/                   # Docker 相关文件\n│   └── docker-compose.yml    # Docker Compose 配置文件\n│\n├── main.py                   # 应用程序入口点\n├── Dockerfile                # Docker 构建文件\n├── pyproject.toml            # Python 项目配置\n├── poetry.lock               # Poetry 依赖锁定文件\n└── README.md                 # 项目说明文档\n```\n\n## 常见问题\n\n**Q: Webhook 触发但 QQ 未收到消息怎么办？**\n\nA: 请检查以下几点：\n\n1. OneBot 地址和 token 是否正确\n2. OneBot 实现是否支持 WebSocket/HTTP 连接\n3. QQ 机器人是否在目标群/好友中\n4. 查看日志获取详细错误信息\n\n**Q: 如何支持多个 QQ 机器人？**\n\nA: 本程序暂时不支持推送到多个 QQ 机器人\n\n## 贡献指南\n\n欢迎提交 Pull Request 或 Issue 来帮助改进本项目！\n\n1. Fork 本仓库\n2. 创建功能分支 (`git checkout -b feature/amazing-feature`)\n3. 提交更改 (`git commit -m 'Add some amazing feature'`)\n4. 推送到分支 (`git push origin feature/amazing-feature`)\n5. 创建 Pull Request\n\n## 许可证\n\n本项目采用 Apache License 2.0 许可证。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapts-1547%2Fonebot-github-webhook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapts-1547%2Fonebot-github-webhook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapts-1547%2Fonebot-github-webhook/lists"}