Skip to content

botflare

botflare

Discord bots on Cloudflare Workers.

Answer commands, buttons and modals over HTTP or over the gateway. The REST client takes its types from Discord's own API spec. Everything a bot imports is 13 kB gzipped.

npm install botflare
const roll = command(
{
name: 'roll',
description: 'Roll a die',
options: { sides: option('integer', { description: 'Sides' }) },
},
(c) => {
const sides = c.options.sides ?? 6;
const rolled = 1 + Math.floor(Math.random() * sides);
return c.reply(`You rolled ${rolled}`, {
buttons: [{ id: `again:${sides}`, label: 'Roll again' }],
});
},
);

/roll sides:20
my-bot You rolled 17 · Roll again

How a bot runs

One Worker answers interactions. A Durable Object holds the gateway connection, so events reach the same handlers without a public URL.

Discord

interactions, events

Sends slash commands, clicks and form submits, and gateway events such as member joins.

Worker

bot()

Checks the Ed25519 signature, runs the matching handler and returns the answer.

Durable Object

gateway()

Keeps the WebSocket open, resumes after a drop, and passes interactions to bot().

POST / over HTTP, for bots with an Interactions Endpoint URL.

wss://gateway.discord.gg from the Durable Object, for bots that need events.

Gateway or HTTP

Pick one per bot. Both run the same handlers.

GatewayHTTP
Commands, buttons, menus, modalsYesYes
Events, such as member joinsYesNo
Needs a public URLNoYes, the Interactions Endpoint URL
Durable Object timeAbout 11,000 GB-s a dayNone

Workers Free includes 13,000 GB-s a day, enough for one gateway bot. Source: Durable Objects pricing.

Typed from the spec

Every route, path value, query, body and result comes from discord/discord-api-spec.

await rest.post('/channels/{channel_id}/messages', {
path: { channel_id },
body: { content: 1 },
// ~~~~~~~ Type 'number' is not assignable to type 'string'.
});

The types cover 157 paths, generated from commit 4e75626 of the spec. When Discord adds a route, bun run gen:routes brings it in. On a 429, rest waits for retry_after and tries again, up to three tries.

botflare is an unofficial library. It is not affiliated with Discord Inc. or Cloudflare, Inc.

MIT · GitHub · npm