Skip to content

Repository files navigation

Version Issues

Discord Event And Thread Bot

Eve is a Discord bot for small-to-mid community servers (~20-100 members) that turns event announcements into organized threads with one click. When someone posts an event in a watched channel and mentions a configured role, Eve parses the message, shows the poster an editable preview, and on confirmation creates a thread, a Discord Scheduled Event, and links everything together. It also tracks emoji reactions to auto-pull interested users into the thread.

Features

  • One-click event creation — Post a message mentioning the trigger role, click the setup button, and Eve handles the rest
  • Smart event parsing — Uses spaCy NLP (dependency parsing + NER) and parsedatetime to extract dates, times, titles, and locations from natural language
  • Ephemeral setup flow — Only the event creator and mods see the setup UI; the channel stays clean
  • Discord Scheduled Events — Automatically creates a linked scheduled event with countdown
  • Reaction tracking — React with the RSVP emoji and get auto-added to the event thread (works even if you reacted before the event was created)
  • "Interested" tracking — Click "Interested" on the Discord Scheduled Event and get auto-added to the thread
  • Image support — Auto-detects images from the original message for the scheduled event cover
  • Voice channel events — Support for both address-based and voice channel locations
  • Interactive setup wizard — Configure channels, role, timezone, and emoji in one screen

Commands

All commands are subcommands under /eve and require the ManageGuild permission.

Command Description
/eve setup Interactive setup wizard
/eve channel add #channel Register an event channel
/eve channel remove #channel Unregister an event channel
/eve channel list Show all watched channels
/eve role set @role Set the trigger role
/eve emoji set Set the default RSVP emoji
/eve timezone set Set the server default timezone (25 major timezones)
/eve status Show current configuration

How It Works

Creating Events

Auto-Detection

  1. Someone posts an event message in a watched channel, mentioning the trigger role
  2. Eve replies with a detection message that pings the poster: "@user and mods can set this up"
  3. The poster (or a mod) clicks the setup button — the detection message is deleted and a private preview appears with parsed event details
  4. They can edit the title, date, time, location, timezone, and image
  5. On confirm, Eve creates a Discord Scheduled Event, a thread on the original message, and links them together. If event or thread creation fails, the entire flow fails with a clear error message
  6. Reactions with the RSVP emoji auto-add users to the thread (including any reactions placed before the event was created)
  7. Users who click "Interested" on the Discord Scheduled Event are also auto-added to the thread

Context Menu

Right-click any message → Apps → Create Event to create an event manually. Eve shows the same private preview and setup flow — no public "Event detected" message is posted. Works on any message in the server, regardless of channel or role.

Deleting Events

Auto-Detection

  1. When a tracked event message is deleted and the scheduled event still exists, Eve posts: "A tracked event message was deleted — Clean up?"
  2. Click "Clean Up" — the prompt is deleted and a delete modal opens showing event details, with an optional thread deletion checkbox
  3. Click "Dismiss" to remove tracking but keep the thread and scheduled event intact
  4. The cleanup prompt auto-deletes after 24 hours if no action is taken
  5. If the scheduled event was already deleted before the message, Eve silently cleans up the database — no prompt needed

Context Menu

Right-click a tracked event message → Apps → Delete Event. A modal appears showing event details and links as read-only text, a thread deletion checkbox, and a confirmation checkbox. On confirm, Eve deletes the scheduled event, the original message, optionally the thread, and removes tracking from the database. Only the event creator or users with Manage Events permission can use this.

Self-Hosting

Prerequisites

  • Docker and Docker Compose (recommended), or Node.js 22+ and Python 3.12+
  • A Discord bot token with the Message Content privileged intent enabled

Discord Setup

  1. Create a Discord application at https://discord.com/developers/applications
  2. Create a bot and enable the Message Content privileged intent
  3. Generate an invite link with these permissions:
    • Send Messages
    • Create Public Threads
    • Manage Threads
    • Add Reactions
    • Read Message History
    • Manage Events
    • Use External Emojis

Running with Docker Compose (recommended)

Eve is two containers: the bot, and an NLP sidecar that parses event details out of message text. The bot will not start until the sidecar reports healthy.

git clone https://github.com/UmushiUmushi/eve.git
cd eve
cp .env.example .env        # fill in DISCORD_TOKEN and DISCORD_CLIENT_ID
docker compose up -d --wait

--wait blocks until both containers pass their health checks, so the command fails loudly rather than leaving you to discover a broken stack later. First build takes a few minutes — the sidecar downloads a spaCy language model.

Running on a server from published images

docker-compose.prod.yml pulls eve and eve-nlp from GitHub Container Registry, so the server never needs a source checkout.

It does not declare a Watchtower container, on the assumption that one already runs on the host. Both services are labelled com.centurylinklabs.watchtower.enable=true, so they are picked up whether or not that instance uses --label-enable. Since both declare real health checks, Watchtower waits for a replacement to pass its check before retiring the container it replaces.

# On the server: only these two files plus .env are needed
curl -O https://raw.githubusercontent.com/UmushiUmushi/eve/main/docker-compose.prod.yml
cp .env.example .env        # fill in your token
docker compose -f docker-compose.prod.yml up -d --wait

Verifying it works

docker compose ps                        # both services should read (healthy)
docker compose logs -f eve               # structured JSON logs
docker compose exec eve node dist/health-check.js

Then, in Discord:

  1. Run /eve setup and pick a watched channel, a trigger role and a timezone
  2. Post a message in that channel mentioning the trigger role, e.g. Game night tomorrow at 7pm at Central Park @Events
  3. Eve should reply with a detection prompt within a second or two

If nothing happens, check the logs — Eve reports at startup whether the NLP service is reachable, and logs every parse failure with the guild and message ID.

Running from source

git clone https://github.com/UmushiUmushi/eve.git
cd eve
cp .env.example .env
# Set NLP_SERVICE_URL=http://localhost:24000 for a locally-run sidecar

# Terminal 1 — the NLP service
cd nlp-service
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python -m spacy download en_core_web_sm
uvicorn main:app --port 24000

# Terminal 2 — the bot
npm install
npm run build
npm start

better-sqlite3 is a native module compiled against a specific Node ABI. If you see NODE_MODULE_VERSION errors, run npm rebuild better-sqlite3. The repo pins a Node version in .nvmrc; nvm use avoids the problem.

Environment Variables

Variable Required Default Description
DISCORD_TOKEN Yes Bot token from the Discord developer portal
DISCORD_CLIENT_ID Yes Application ID, used for command registration
NLP_SERVICE_URL No http://eve-nlp:24000 URL of the NLP sidecar
DISCORD_DEV_GUILD_ID No Register commands to one guild for instant updates while developing
LOG_LEVEL No info Minimum level to emit; each includes everything more severe. trace, debug, info, warn, error, fatal — left is more output
EVE_DB_PATH No ./data/eve.db SQLite location. Tests use :memory:
EVE_HEARTBEAT_PATH No ./data/heartbeat.json Liveness file read by the health check
EVE_DEBUG No Set on the sidecar to expose its /debug parse inspector

Slash commands are registered automatically on bot startup.

Backups

The database is a single SQLite file in the eve-data volume. It runs in WAL mode, so copying the .db file alone can capture a torn state — use SQLite's backup command:

docker compose exec eve node -e "
  const db = require('better-sqlite3')('/app/data/eve.db');
  db.backup('/app/data/backup.db').then(() => console.log('done'));
"
docker compose cp eve:/app/data/backup.db ./eve-backup.db

Development

npm run dev            # hot-reload development server
npm run build          # type-check and compile
npm test               # unit tests
npm run test:coverage  # unit tests with coverage thresholds
npm run lint           # lint
npm run check          # lint + build + coverage, the same gates CI runs

cd nlp-service && python -m pytest    # NLP service tests

Database migrations

Schema lives in src/database/migrations/ as plain SQL, applied automatically at startup before the bot connects to Discord.

npm run db:status      # what's applied and what's pending
npm run db:migrate     # apply pending migrations
npm run db:rollback    # reverse the most recent migration

Migrations are checksummed by their SQL. Never edit one that has been applied — add a new one. Never delete one; the runner refuses to start if a recorded migration has vanished from the code.

Tech Stack

  • TypeScript with discord.js v14
  • SQLite via better-sqlite3 (no external database needed), with SQL migrations
  • pino for structured JSON logging
  • Python FastAPI sidecar for NLP processing
  • spaCy for NER and dependency parsing (title/location extraction)
  • parsedatetime for structured date/time resolution
  • Vitest and pytest, with coverage thresholds enforced in CI
  • Docker multi-stage builds, health checks on both services

Future Ideas (not in v1)

  • Pluggable LLM-based event parser (local Ollama, OpenAI, Anthropic)
  • Recurring events
  • Event reminders
  • Web dashboard
  • Multi-role support
  • Event templates
  • Multi-day events
  • Edit event flow
  • 'Remove from thread' handlers

About

Another Discord event bot

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages