Skip to content

osmocn/reva-discord-bot

Repository files navigation

Reva

A Discord bot that tracks user timezones and tells you if someone is likely awake. Built on Cloudflare Workers with Hono, Drizzle ORM, Cloudflare D1 and with help from Claude Code.

Adding Reva to your server

  1. Invite Reva to your server
  2. Run /set-timezone to set your timezone
  3. Ask others to do the same, then anyone can check anyone's local time with /time @user

Commands

Command Description
/time [@user] Show a user's local time. Omit @user to see your own.
/set-timezone Set your timezone via an interactive select menu
/help Show all available commands

Setup

Prerequisites

1. Install dependencies

pnpm install

2. Configure environment

Create .dev.vars in the project root for local development:

DISCORD_PUBLIC_KEY=your_bot_public_key
DISCORD_APPLICATION_ID=your_application_id
DISCORD_BOT_TOKEN=your_bot_token
DISCORD_GUILD_ID=your_guild_id   # optional — for instant guild-scoped registration

DISCORD_BOT_TOKEN and DISCORD_GUILD_ID are only used by the command registration script, not the worker itself.

3. Set up the database

pnpm db:local:migrate     # creates the local D1 database

4. Register slash commands

pnpm discord

Select Guild scope for instant updates during development, Global for production.

5. Run locally

pnpm dev

The worker starts at http://localhost:8787. Point your Discord application's Interactions Endpoint URL to your ngrok/tunnel URL + /api/interactions.

Deployment

pnpm deploy

Set production secrets in Cloudflare:

wrangler secret put DISCORD_PUBLIC_KEY
wrangler secret put DISCORD_APPLICATION_ID

Apply the database migration to production:

pnpm db:prod:migrate

Development

Project structure

src/
  bot/            Discord interaction handling (commands, components, router)
  db/             Schema, Drizzle factory, and query functions
  content/        Response templates and render utility
  ui/             Discord component builders (select menus)
  scripts/        CLI for managing Discord slash commands

Adding a command

  1. Create src/bot/commands/<name>.ts:
import { ResponseType, type ApplicationCommandInteraction } from "../discord"
import type { Context } from "hono"
import type { Bindings } from "../../types/binding"

export const definition = {
  name: "my-command",
  description: "Does something",
} as const

export async function handler(c: Context<{ Bindings: Bindings }>, interaction: ApplicationCommandInteraction): Promise<Response> {
  return c.json({ type: ResponseType.CHANNEL_MESSAGE, data: { content: "Hello!" } })
}
  1. Add it to src/bot/registry.ts:
import * as myCommand from "./commands/my-command"
const modules = [awake, setTimezone, help, myCommand] as const
  1. Register with Discord:
pnpm discord

Database changes

# 1. Edit src/db/schema.ts
# 2. Generate migration
pnpm db:generate
# 3. Apply locally
pnpm db:local:migrate
# 4. Apply to production when ready
pnpm db:prod:migrate

Tests

pnpm test

Tests run inside the actual Cloudflare Workers runtime via @cloudflare/vitest-pool-workers.

About

A Discord bot that lets anyone in the server check what time it is for any other member.

Topics

Resources

Stars

Watchers

Forks

Contributors