Files
zwitschi cf564f2886
CI-CD / Bot Lint Test Build (push) Successful in 1m24s
CI-CD / Dashboard Lint Build (push) Successful in 14s
CI-CD / Deploy to Coolify (push) Failing after 3s
feat: Update CI/CD workflow to trigger separate backend and dashboard deployments; enhance deployment documentation with Nginx proxy details and OAuth callback URLs
2026-05-17 19:08:26 +02:00

7.2 KiB

Discord Bot for Open Mic Odyssey

A modular Discord bot + admin platform that syncs community engagement between Discord and openmicodyssey.com. The system includes onboarding roles, stage queue management, mileage progression, content syndication, an admin API, and a React admin dashboard.

Core Features

The Call Sheet (Onboarding + Roles)

  • Reaction-role onboarding message with emoji-to-role bindings
  • Role hierarchy safety checks before assignment/removal
  • Optional onboarding completion role and welcome-channel message

The Tour Schedule (Stage Queue)

  • /sign-up subcommands: join, leave, list, next, clear
  • FIFO queue per guild
  • Optional stage-speaker promotion and queue announcement dispatch

The Dailies (Content Syndication)

  • Adapter-based polling pipeline
  • YouTube RSS adapter implemented
  • Discord webhook dispatch with duplicate suppression

Mileage Engine

  • PostgreSQL-backed mileage event/user persistence
  • Configurable event scoring
  • Role-tier upgrades on threshold milestones
  • Retry behavior for transient write failures

Admin API + Dashboard

  • Express Admin API for config, queue, stats, OAuth bridge, configuration DB
  • React/Vite dashboard for OAuth login + analytics views

OAuth2 Bridge

  • Discord OAuth2 code exchange to user profile
  • Ephemeral session issuance
  • Optional sync callback to openmicodyssey.com backend

Configuration Database

  • bot_settings, content_schedules, engagement_stats tables
  • Admin CRUD endpoints for settings/schedules
  • Engagement snapshot persistence from runtime events

Implemented Modules

  • src/bot.ts: gateway client lifecycle, command dispatch, service wiring
  • src/call-sheet.ts: reaction role onboarding and role hierarchy guards
  • src/tour-schedule.ts: FIFO queue, stage speaker promotion, announcements
  • src/mileage.ts: mileage persistence, scoring, role-upgrade triggers
  • src/dailies/*: adapter/poller/webhook syndication pipeline
  • src/admin-api.ts: operational and configuration endpoints
  • src/oauth-bridge.ts: Discord code exchange + openmic session sync
  • src/configuration-database.ts: bot settings, schedules, engagement snapshots
  • admin-dashboard/src/*: admin SPA, OAuth callback flow, analytics views

Architecture Documentation (arc42)

This project uses the arc42 template. Chapters are in docs/.

Architecture & Tech Stack

Layer Choice
Runtime Node.js + TypeScript
Discord SDK discord.js
Database PostgreSQL
Admin API Express
Admin Dashboard React + Vite
Auth Discord OAuth2
Hosting Coolify + Nixpacks

Getting Started

Prerequisites

  • Node.js 22+
  • npm 10+
  • Discord Developer Application (bot token + OAuth2 app)
  • PostgreSQL instance
  • Discord server where you can install bots with role/channel permissions

Discord Bot Setup (Portal)

  1. Open Discord Developer Portal and create a new application.
  2. In Bot tab, click Add Bot.
  3. Copy these values for runtime config (bot_settings):
    • DISCORD_TOKEN from Bot tab (Reset Token if needed)
    • DISCORD_CLIENT_ID from OAuth2 > General
    • OAUTH_BRIDGE_REDIRECT_URI as exact callback URL, recommended: https://admin.openmicodyssey.com/oauth/discord/callback
  4. In Bot > Privileged Gateway Intents, enable only:
    • Server Members Intent (required by current code)
  5. Keep these disabled unless code changes require them:
    • Message Content Intent
    • Presence Intent

Current gateway intents used by this project (src/bot.ts):

  • Guilds
  • GuildMembers (privileged)
  • GuildMessageReactions

Discord Bot Install (OAuth2 URL)

  1. Open OAuth2 > URL Generator.
  2. Select scopes:
    • bot
    • applications.commands
  3. Select bot permissions (minimum recommended for current features):
    • View Channels
    • Send Messages
    • Read Message History
    • Add Reactions
    • Manage Roles (call-sheet role assignment)
    • Manage Channels (queue moderation paths)
  4. Use generated URL to add bot to your server.

Installation

  1. Clone repository:
git clone https://git.allucanget.biz/allucanget/omo-bot.git
cd omo-bot
  1. Install root dependencies:
npm install
  1. Configure bootstrap environment variables (.env from .env.example):
DATABASE_URL=postgres://...
CONFIG_DB_ENABLED=true
DISCORD_GUILD_ID=... # optional seed scope
  1. Register slash commands:
npm run register:commands
  1. Run bot in development:
npm run dev
  1. Build and run production bundle:
npm run build
npm start

Admin Dashboard

cd admin-dashboard
npm install
npm run dev

Dashboard environment template: admin-dashboard/.env.example.

Recommended production OAuth callback URL:

  • https://admin.openmicodyssey.com/oauth/discord/callback

This same URL must match:

  • Discord OAuth2 redirect whitelist
  • VITE_DISCORD_REDIRECT_URI
  • OAUTH_BRIDGE_REDIRECT_URI

Validation Commands

npm run lint
npm run build
npm run test

Database Setup Commands

DATABASE_URL is required for each command.

npm run db:migrate
npm run db:seed
npm run db:setup
  • db:migrate: applies schema migrations tracked in schema_migrations
  • db:seed: ensures migrations are applied, then inserts initial config values from environment into bot_settings when missing
  • db:setup: runs migrate then seed

Runtime Config Source

Runtime reads configuration keys from bot_settings table first, then falls back to environment values.

  • Global scope: guild_id = __global__
  • Guild override scope: guild_id = DISCORD_GUILD_ID
  • Key names match previous env variable names (examples: DISCORD_TOKEN, DISCORD_CLIENT_ID, ADMIN_API_TOKEN)

Recommended flow:

  1. Set bootstrap env (DATABASE_URL, optional DISCORD_GUILD_ID).
  2. Run npm run db:migrate.
  3. Run npm run db:seed once while legacy env vars are still present.
  4. Remove legacy runtime vars from .env after confirming bot_settings contains required keys.

Deployment

Deployment setup and domain configuration moved to DEPLOYMENT.md.

  • Coolify project/resource setup
  • Real domain DNS/TLS and routing patterns
  • Discord OAuth production redirect alignment
  • Gitea Actions secret configuration for deploy hooks
  • Two-resource deploy flow (omo-bot-backend + omo-bot-dashboard)

Dashboard quality check:

cd admin-dashboard
npm run lint
npm run build

Admin API Endpoints

  • GET /health
  • GET /admin/config
  • GET /admin/stats?guildId=...
  • GET /admin/schedule?guildId=...
  • POST /admin/schedule/clear
  • POST /admin/oauth/discord/exchange
  • GET /admin/oauth/session/:sessionId
  • GET /admin/db/settings?guildId=...
  • PUT /admin/db/settings
  • GET /admin/db/schedules?guildId=...
  • PUT /admin/db/schedules
  • DELETE /admin/db/schedules/:guildId/:scheduleKey
  • GET /admin/db/engagement/latest?guildId=...

CI/CD (Gitea Actions)

Pipeline file: .gitea/workflows/ci-cd.yml

For full deployment flow, webhook secret strategy, and two-resource Coolify deployment, see DEPLOYMENT.md.

Contributing

Internal development only. See CONTRIBUTING.md.