chore: auto-fix lint & formatting [skip ci]

This commit is contained in:
github-actions[bot] 2026-08-13 22:46:35 +00:00
parent 6f1a334150
commit 811f8646e0
26 changed files with 304 additions and 306 deletions

View file

@ -7,7 +7,7 @@ After [linking your GitHub account](#linking-your-account), you can act on GitHu
You must link your GitHub account once before using any command:
| Platform | Command | Effect |
|----------|-----------------------------------|------------------------------------------------------------------|
| -------- | --------------------------------- | ---------------------------------------------------------------- |
| Discord | `/gh login` | Returns an ephemeral OAuth link to authorize your GitHub account |
| Discord | `/gh logout` | Unlinks your GitHub account |
| Telegram | `/gh login` (reply to a message) | Returns an OAuth link |
@ -44,7 +44,7 @@ Notifications for open PRs include **合并 / 关闭** (merge/close) buttons:
### Requirements
| Item | How |
|--------------|----------------------------------------------------------------------------------------------------|
| ------------ | -------------------------------------------------------------------------------------------------- |
| Public key | `DISCORD_PUBLIC_KEY` set + Interactions Endpoint URL configured |
| Invite scope | Bot invited with `applications.commands` (see [Discord Bot Setup](./deployment#discord-bot-setup)) |
| OAuth | `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET` and `BASE_URL` configured |

View file

@ -21,7 +21,7 @@ Routes belong to groups. Groups scope admin access and can restrict which events
```
| Field | Type | Required | Description |
|------------------|----------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ---------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | string | Yes | Lowercase id (`a-z0-9`, `-`); referenced by each route's `groupId`. Editable: renaming a group re-points its routes, per-group webhook secret and pending invites |
| `name` | string | Yes | Human-readable group name |
| `members` | object[] | No | `{ login, role }` entries; role is `owner`, `admin`, or `viewer` |
@ -38,7 +38,7 @@ Routes belong to groups. Groups scope admin access and can restrict which events
Every group member has one of three roles. Super admins (`ADMIN_USER_IDS`) always bypass them.
| Role | View routes/logs | Edit routes | Manage members & invites | Edit group settings |
|----------|------------------|-------------|--------------------------|---------------------|
| -------- | ---------------- | ----------- | ------------------------ | ------------------- |
| `owner` | ✓ | ✓ | ✓ | ✓ (except `owners`) |
| `admin` | ✓ | ✓ | ✗ | ✗ |
| `viewer` | ✓ (read-only) | ✗ | ✗ | ✗ |

View file

@ -13,7 +13,7 @@ Translation overrides are merged from KV under the key `i18n:<lang>` as a flat J
```jsonc
// KV key: i18n:zh
{
"events.push.title": "{repo}: 推送了 {count} 个提交到 {ref}"
"events.push.title": "{repo}: 推送了 {count} 个提交到 {ref}",
}
```

View file

@ -5,7 +5,7 @@
WebHooker ingests webhooks from multiple forges through the same `POST /webhook` endpoint; the provider is auto-detected from the request headers, so point every forge's webhook at `{BASE_URL}/webhook`.
| Provider | Event header | Signature header | Signature format | Secret |
|----------|------------------|-----------------------|----------------------------|-------------------------|
| -------- | ---------------- | --------------------- | -------------------------- | ----------------------- |
| GitHub | `X-GitHub-Event` | `X-Hub-Signature-256` | `sha256=<hex>` HMAC-SHA256 | `GITHUB_WEBHOOK_SECRET` |
| Gitea | `X-Gitea-Event` | `X-Gitea-Signature` | plain hex HMAC-SHA256 | `GITEA_WEBHOOK_SECRET` |
@ -51,7 +51,7 @@ Payload schema:
```
| Field | Type | Description |
|---------------|----------|------------------------------------------------------------------------------------------------------------------|
| ------------- | -------- | ---------------------------------------------------------------------------------------------------------------- |
| `title` | string | Message title (falls back to "Custom message") |
| `description` | string | Optional message body |
| `color` | string | Optional embed color: a word (`red`, `green`, `yellow`, `blue`, `purple`, `orange`, `cyan`, `gray`) or `#rrggbb` |

View file

@ -4,25 +4,25 @@
Every dispatch attempt is recorded in the D1 `send_logs` table and browsable in the console (**Logs** tab). Fields:
| Field | Meaning |
|--------------|-------------------------------------------------------------------------|
| `routeId` | Route that matched |
| `groupId` | Route's group |
| `event` | Event type (e.g. `push`, `pull_request`, `custom`) |
| `repo` | Repository full name (when present) |
| `target` | Target id the message was sent to |
| `platform` | `discord` or `telegram` |
| `ok` | Whether the send succeeded |
| `status` | HTTP status from the platform API (when applicable) |
| `error` | Error message (when failed) |
| `errorCode` | Stable error code (e.g. `NO_TARGET`, `NO_TOKEN`, `RATE_LIMITED`) |
| `attempts` | Send attempts including retries |
| `durationMs` | Time spent sending |
| `deliveryId` | Webhook delivery id (when provided) |
| `messageId` | Platform message id (used for in-place edits) |
| `actor` | Sender login |
| `action` | Event action (when present) |
| `detail` | Extra JSON details (when present) |
| Field | Meaning |
| ------------ | ---------------------------------------------------------------- |
| `routeId` | Route that matched |
| `groupId` | Route's group |
| `event` | Event type (e.g. `push`, `pull_request`, `custom`) |
| `repo` | Repository full name (when present) |
| `target` | Target id the message was sent to |
| `platform` | `discord` or `telegram` |
| `ok` | Whether the send succeeded |
| `status` | HTTP status from the platform API (when applicable) |
| `error` | Error message (when failed) |
| `errorCode` | Stable error code (e.g. `NO_TARGET`, `NO_TOKEN`, `RATE_LIMITED`) |
| `attempts` | Send attempts including retries |
| `durationMs` | Time spent sending |
| `deliveryId` | Webhook delivery id (when provided) |
| `messageId` | Platform message id (used for in-place edits) |
| `actor` | Sender login |
| `action` | Event action (when present) |
| `detail` | Extra JSON details (when present) |
The console's **Logs** tab lists recent entries (filterable by group) and shows full details for a single entry. Entries are written best-effort — a failed insert never breaks dispatch.

View file

@ -32,7 +32,7 @@ There are **no default routes** — each route must define its own target. If no
Each entry of `targets` is a push destination, so one route can forward to several channels at once (e.g. a Discord channel **and** a Telegram group). `target.platform` selects the platform: `discord` (default) or `telegram`. For **Discord**, `target.channelId` is required (a thread in `target.threadId` is optional). For **Telegram**, `target.chatId` (the group/supergroup chat id, e.g. `-1001234567890`) is required and `target.topicId` (the `message_thread_id` of a topic, equivalent of a Discord thread) is optional. There is no fallback to a default channel.
| Field | Type | Required | Description |
|------------------|----------|----------|-------------------------------------------------------------------------------------------------|
| ---------------- | -------- | -------- | ----------------------------------------------------------------------------------------------- |
| `groupId` | string | Yes | Id of the [group](./groups) this route belongs to |
| `fallback` | boolean | No | When `true`, fires only if no non-fallback route matched the event; its own filters are ignored |
| `stop` | boolean | No | When `true` and this route matches, no further routes are evaluated for this event |

View file

@ -3,7 +3,7 @@
## KV Storage Layout
| Key Pattern | Value | TTL |
|--------------------------------|-------------------------------------------------------------------------------|--------------------|
| ------------------------------ | ----------------------------------------------------------------------------- | ------------------ |
| `config:routes` | JSON array of routes | Permanent |
| `config:groups` | JSON array of groups | Permanent |
| `session:{id}` | Admin session `{ userId, login }` | 7 days |
@ -26,7 +26,7 @@
The D1 database (`DB` binding, database `webhooker`) holds four tables:
| Table | Purpose |
|------------------|------------------------------------------------------------------------------------------------|
| ---------------- | ---------------------------------------------------------------------------------------------- |
| `send_logs` | One row per dispatch attempt (route id, event, target, ok/error, duration, error code, detail) |
| `audit_logs` | One row per admin operation (login/logout, group/route/member/invite changes) |
| `discord_links` | Maps `discord_user_id``github_user_id` for `/gh` Discord commands |

View file

@ -3,7 +3,7 @@
WebHooker runs three maintenance tasks on the scheduled trigger (`*/5 * * * *`, every 5 minutes). They only run on the deployed worker (Cloudflare cron); local `wrangler dev` runs them when triggered via `wrangler dev --test-scheduled`.
| Task | Purpose |
|-----------------|------------------------------------------------------------------------------------------------------------------|
| --------------- | ---------------------------------------------------------------------------------------------------------------- |
| `discord-sync` | Registers the Discord slash/context-menu commands: per-guild (instant) and globally (24h dedup, ~1h propagation) |
| `telegram-sync` | Calls `setWebhook` to `{BASE_URL}/telegram/webhook` (with `TELEGRAM_WEBHOOK_SECRET` as `secret_token` when set) |
| `audit-prune` | Deletes `audit_logs` entries older than `AUDIT_RETENTION_DAYS` (default 90) |