Discord bot built with Carbon on Cloudflare Workers.
@buape/carbon- Cloudflare Workers (
@buape/carbon/adapters/fetch) - Gateway forwarding:
forwarder/Bun process usingGatewayForwarderPlugin - Cloudflare D1 + Drizzle ORM
- Install deps:
bun install- Create
.envfrom.env.example.
Required:
BASE_URL=
DEPLOY_SECRET=
DISCORD_CLIENT_ID=
DISCORD_PUBLIC_KEY=
DISCORD_BOT_TOKEN=Optional:
DISCORD_DEV_GUILDS=
FORWARDER_PUBLIC_KEY=
ANSWER_OVERFLOW_API_KEY=
HELPER_THREAD_WELCOME_PARENT_ID=
HELPER_THREAD_WELCOME_TEMPLATE=
THREAD_LENGTH_CHECK_INTERVAL_HOURS=- Configure
wrangler.jsoncD1 binding:
- set
d1_databases[0].database_idto your real D1 database id - keep
binding = "DB"
- Apply D1 migrations:
bun run db:apply:local
# or
bun run db:apply:remote- Run locally:
bun run devbun run dev→wrangler dev --env-file .envbun run deploy→ deploy worker locally with.envbun run deploy:cf→ apply remote D1 migrations, then deploy Worker for Cloudflare Buildsbun run deploy:dry-run→ validate the Worker bundle without deployingbun run cf-typegen→ regenerateworker-configuration.d.tsbun run typecheck→ TypeScript checkbun run test→ generate Forms styles, then run the test suite (requires ImageMagick and the WebP CLI tools)bun run db:generate→ generate Drizzle SQLbun run db:apply:local/db:apply:remote→ apply D1 migrations
GitHub Actions runs frozen installs and typechecks for both Bun packages, a Worker dry-run build, and the full test suite on pull requests and pushes to main. These checks share one Ubuntu job with a 20-minute timeout; CI installs ImageMagick 7 and the WebP tools needed by the artwork tests. The workflow does not deploy or require deployment secrets.
Cloudflare Workers Builds deploys pushes to main. The deploy command should apply D1 migrations before deploying the Worker:
bun run deploy:cfDrizzle only generates SQL migrations. Wrangler applies them to D1:
bun run db:generate
bun run db:apply:remoteThe main bot runs as a Cloudflare Worker. Gateway events are forwarded by the Bun app in forwarder/, usually running on Krill's machine.
Forwarder setup:
cd forwarder
bun install
bun run devForwarder production start:
cd forwarder
bun run startForwarder env:
BASE_URL=
DEPLOY_SECRET=
DISCORD_CLIENT_ID=
DISCORD_PUBLIC_KEY=
DISCORD_BOT_TOKEN=
FORWARDER_PRIVATE_KEY=The Worker must have the matching public key:
bunx wrangler secret put FORWARDER_PUBLIC_KEY- Answer Overflow base URL is hardcoded to
https://www.answeroverflow.com. - Helper thread monitor runs via Worker cron (
wrangler.jsonctriggers.crons). - The old Cloudflare Gateway Durable Object path is not the active gateway setup.