{"id":50558487,"url":"https://github.com/marceloeatworld/discord-bridge","last_synced_at":"2026-06-04T09:30:50.172Z","repository":{"id":354171971,"uuid":"1198500354","full_name":"marceloeatworld/discord-bridge","owner":"marceloeatworld","description":"Discord Gateway bridge for ClopinetteAI — forwards messages to Cloudflare Workers via HMAC-signed HTTP. Bun, Docker, ~180 lines.","archived":false,"fork":false,"pushed_at":"2026-04-02T15:13:53.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-27T13:32:26.289Z","etag":null,"topics":["bridge","bun","clopinette","cloudflare-workers","discord","discord-bot","docker","gateway"],"latest_commit_sha":null,"homepage":"https://clopinette.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marceloeatworld.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-01T13:36:19.000Z","updated_at":"2026-04-02T15:14:03.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marceloeatworld/discord-bridge","commit_stats":null,"previous_names":["marceloeatworld/discord-bridge"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/marceloeatworld/discord-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marceloeatworld%2Fdiscord-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marceloeatworld%2Fdiscord-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marceloeatworld%2Fdiscord-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marceloeatworld%2Fdiscord-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marceloeatworld","download_url":"https://codeload.github.com/marceloeatworld/discord-bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marceloeatworld%2Fdiscord-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33899697,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"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":["bridge","bun","clopinette","cloudflare-workers","discord","discord-bot","docker","gateway"],"created_at":"2026-06-04T09:30:49.037Z","updated_at":"2026-06-04T09:30:50.164Z","avatar_url":"https://github.com/marceloeatworld.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Discord Gateway Bridge\n\nLightweight bridge that connects to the Discord Gateway WebSocket and forwards messages to a [ClopinetteAI](https://github.com/marceloeatworld/clopinette-ai) worker via HTTP.\n\nDiscord requires a persistent WebSocket connection (Gateway) to receive regular messages — there is no webhook push like Telegram or WhatsApp. This bridge maintains that connection and forwards `MESSAGE_CREATE` events to the Clopinette worker.\n\n## How it works\n\n```\nDiscord Gateway (WSS)\n  |\n  v\nBridge (Bun, ~180 lines)\n  |  - Maintains WebSocket + heartbeat\n  |  - Handles reconnect/resume\n  |  - Filters: DMs forwarded directly,\n  |    guilds only on @mention or reply\n  |\n  v (HTTP POST, HMAC-SHA256 signed)\nClopinette Worker (/webhook/discord-bridge)\n  |\n  v\nDurable Object (per-user or per-guild)\n```\n\n## Security\n\n- **HMAC-SHA256** signature over `timestamp + body` — the shared secret never transits in the request\n- **Anti-replay** — worker rejects requests older than 5 minutes\n- **Timing-safe comparison** on the worker side\n- **No public ports** — the bridge only initiates outbound connections (Discord WSS + Worker HTTPS)\n- **Health check** returns only `ok` or `disconnected`, no sensitive data\n\n## Setup\n\n### 1. Deploy the Clopinette worker\n\nFollow the [core setup](https://github.com/marceloeatworld/clopinette-ai#discord) to configure Discord secrets and register slash commands:\n\n```bash\n# In clopinette-ai-dev/\nwrangler secret put DISCORD_TOKEN\nwrangler secret put DISCORD_PUBLIC_KEY\nwrangler secret put DISCORD_APPLICATION_ID\nbun run deploy\n\n# Register slash commands + generate bridge secret\ncurl -X POST https://your-worker/api/admin/setup-discord \\\n  -H \"Authorization: Bearer YOUR_API_AUTH_KEY\"\n# → returns { bridgeSecret, interactionsUrl, bridgeUrl }\n```\n\n### 2. Deploy the bridge\n\nSet these environment variables on your Docker host (Coolify, etc.):\n\n| Variable | Description |\n|----------|-------------|\n| `DISCORD_TOKEN` | Bot token from Discord Developer Portal |\n| `BRIDGE_SECRET` | From the setup-discord response above |\n| `WORKER_URL` | Your worker URL, e.g. `https://agent.clopinette.app` |\n\n```bash\ndocker compose up -d\n```\n\n### 3. Discord Developer Portal\n\n- **Bot** tab → enable **Message Content Intent**\n- **General Information** → set Interactions Endpoint URL to `https://your-worker/webhook/discord`\n- **OAuth2 → URL Generator** → scopes `bot` + `applications.commands`, permissions: View Channels, Send Messages, Embed Links, Attach Files, Read Message History, Add Reactions, Use Slash Commands\n\n## Behavior\n\n| Context | Trigger | Response |\n|---------|---------|----------|\n| DM | Any message | Forwarded to worker |\n| Server | @mention or reply to bot | Forwarded to worker |\n| Server | Regular message | Ignored |\n| Any | Bot messages | Ignored |\n\n## Gateway features\n\n- Heartbeat with ACK tracking (zombie connection detection)\n- Automatic reconnect with exponential backoff (max 30s)\n- Session resume on disconnect (no message loss)\n- Graceful shutdown on SIGTERM/SIGINT\n\n## Requirements\n\n- [Bun](https://bun.sh) runtime (via `oven/bun:1-slim` Docker image)\n- A running ClopinetteAI worker with Discord secrets configured\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarceloeatworld%2Fdiscord-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarceloeatworld%2Fdiscord-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarceloeatworld%2Fdiscord-bridge/lists"}