139 lines
4.0 KiB
Markdown
139 lines
4.0 KiB
Markdown
# GitHub-GCC Bot
|
||
|
||
Cloudflare Worker that forwards GitHub or Gitea repository/organization events to an Enterprise WeChat group robot.
|
||
|
||
The Worker receives webhook payloads (GitHub sends GitHub headers natively; Gitea sends GitHub-compatible headers), verifies `X-Hub-Signature-256`, formats a short text notification, and posts it to the 企业微信群机器人 Webhook.
|
||
|
||
## What This Version Does
|
||
|
||
- Runs on Cloudflare Workers.
|
||
- Does not require your own server.
|
||
- Sends plain text Enterprise WeChat group robot messages.
|
||
- Supports GitHub webhooks and Gitea webhooks (including intranet Gitea instances, as long as the Gitea server has outbound internet access).
|
||
- Uses KV when configured for delivery de-duplication.
|
||
|
||
## Limits
|
||
|
||
- This version only sends text messages.
|
||
- It depends on 企业微信群机器人 Webhook availability and platform rate limits.
|
||
- The WeCom robot Webhook URL contains a secret key; store it only as a Cloudflare secret.
|
||
- Links in messages point to the Git host. For an intranet Gitea (e.g. `https://192.168.87.52:18473`), links are only reachable from the intranet/VPN.
|
||
|
||
## Setup
|
||
|
||
Install dependencies:
|
||
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
Create an optional KV namespace:
|
||
|
||
```bash
|
||
wrangler kv namespace create WEBHOOK_CACHE
|
||
```
|
||
|
||
Put the returned namespace id into `wrangler.toml` by uncommenting the `[[kv_namespaces]]` block.
|
||
|
||
Set Cloudflare Worker secrets:
|
||
|
||
```bash
|
||
wrangler secret put WEBHOOK_SECRET
|
||
wrangler secret put WECOM_WEBHOOK_URL
|
||
```
|
||
|
||
`WEBHOOK_SECRET` is a random string you generate; the same value goes into the Git host's webhook secret field.
|
||
|
||
`WECOM_WEBHOOK_URL` should look like:
|
||
|
||
```text
|
||
https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||
```
|
||
|
||
Optional non-secret variables can be set in `wrangler.toml`:
|
||
|
||
```toml
|
||
[vars]
|
||
MAX_MESSAGE_LENGTH = "1800"
|
||
DELIVERY_TTL_SECONDS = "600"
|
||
ALLOWED_ORGS = "my-org"
|
||
```
|
||
|
||
## Run
|
||
|
||
Local development:
|
||
|
||
```bash
|
||
npm run dev
|
||
```
|
||
|
||
Deploy:
|
||
|
||
```bash
|
||
npm run deploy
|
||
```
|
||
|
||
The webhook endpoint is:
|
||
|
||
```text
|
||
POST /github/webhook
|
||
POST /gitea/webhook
|
||
```
|
||
|
||
Both paths accept the same payload. Gitea can use either URL.
|
||
|
||
The health endpoint is:
|
||
|
||
```text
|
||
GET /healthz
|
||
```
|
||
|
||
## 企业微信群机器人配置
|
||
|
||
1. 在企业微信 App 中进入一个**内部群**(含微信联系人的外部群不支持群机器人)。
|
||
2. 群聊右上角「群设置」→「群机器人」→「添加机器人」,设置名字和头像后创建。
|
||
3. 复制机器人的 Webhook 地址(`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=...`)。
|
||
4. 用 `wrangler secret put WECOM_WEBHOOK_URL` 保存该地址。
|
||
|
||
## Gitea Webhook 配置
|
||
|
||
前提:Gitea 服务器能访问外网(能连 `workers.dev` 和 `qyapi.weixin.qq.com`)。如需代理,在 Gitea 的 `app.ini` 中配置 `[webhook] PROXY_URL`。
|
||
|
||
在仓库、组织或系统管理页面添加 webhook(Gitea 类型):
|
||
|
||
- 目标 URL: `https://github-gcc.sorrow404null.workers.dev/gitea/webhook`(`/github/webhook` 也可以)
|
||
- POST Content Type: `application/json`
|
||
- Secret: 与 `WEBHOOK_SECRET` 相同的值
|
||
- Trigger On: 按需选择 `Push Events`、`Issues`、`Issue Comment`、`Pull Request`、`Releases`、`Workflow Run` 等
|
||
- 保存后点「Test Delivery」发送一个模拟 push 事件验证;失败时在「最近推送记录」中查看请求/响应详情
|
||
|
||
## GitHub Organization Webhook
|
||
|
||
In GitHub organization settings, add a webhook:
|
||
|
||
- Payload URL: `https://github-gcc.sorrow404null.workers.dev/github/webhook`
|
||
- Content type: `application/json`
|
||
- Secret: the same value as `WEBHOOK_SECRET`
|
||
- SSL verification: enabled
|
||
- Events: select `push`, `pull_request`, `issues`, `issue_comment`, `release`, and `workflow_run`
|
||
|
||
`ping` events are accepted but do not send WeCom messages.
|
||
|
||
## Supported Events
|
||
|
||
- `push`
|
||
- `pull_request`
|
||
- `issues`
|
||
- `issue_comment` (and Gitea `pull_request_comment`)
|
||
- `release`
|
||
- `workflow_run` when completed
|
||
|
||
Unsupported events return success without sending a message, so the Git host will not retry them.
|
||
|
||
## Verify
|
||
|
||
```bash
|
||
npm test
|
||
npm run build
|
||
```
|