Files
firefrost-operations-manual/docs/services/the-arbiter-discord-bot.md
Claude b632f61f6f docs: Update The Arbiter with complete role mappings
Updated docs/services/the-arbiter-discord-bot.md to reflect Holly's completion
of all 10 Discord role mappings on March 27, 2026.

CHANGES:
- Role Mappings section: Added all Fire/Frost path role IDs
- Added complete mapping breakdown by path (Fire/Frost/Universal)
- Updated status from 'pending Holly' to 'COMPLETE'
- Deployment History: Added Holly's completion milestone
- Final status: Changed to 'Fully Configured' with all tiers mapped
- Added reference to complete documentation in arbiter-discord-role-mappings.md

ALL 10 TIERS NOW CONFIGURED:
Fire Path (4): Elemental, Knight, Master, Legend
Frost Path (4): Elemental, Knight, Master, Legend
Universal (2): Awakened, Sovereign

Next step: Paymenter webhook integration testing

Signed-off-by: Claude <claude@firefrostgaming.com>
2026-03-28 01:39:50 +00:00

12 KiB

The Arbiter - Discord Bot & Admin Panel

Service: The Arbiter
Purpose: Discord subscription automation and role management
Server: Command Center (63.143.34.217)
Status: Deployed and operational
Deployed: March 27, 2026
Deployed by: The Verifier (Chronicler #42)


Overview

The Arbiter is a Discord bot that automates subscription-based role assignment for Firefrost Gaming. It receives webhooks from Paymenter when subscriptions are created, renewed, cancelled, or expired, and automatically assigns or removes Discord roles accordingly.

The bot includes a web-based admin panel where Holly, Meg, and Michael can manage Discord role mappings without SSH access.


Architecture

Flow:

User Subscribes → Paymenter → Webhook (port 3500) → The Arbiter Bot → Discord Role → LuckPerms → In-game Permissions

Components:

  1. Discord Bot - Monitors Firefrost Gaming server, assigns roles
  2. Webhook Receiver - Receives Paymenter subscription events
  3. Admin Panel - Web interface for managing role mappings
  4. OAuth2 Authentication - Discord login for authorized admins

Access Information

Admin Panel URL: https://discord-bot.firefrostgaming.com/admin

Authorized Users:

  • Holly (unicorn20089) - Discord ID: 269225344572063754
  • Michael (Frostystyle) - Discord ID: 219309716021444609
  • Meg (Gingerfury) - Discord ID: 669981568059703316

Discord Bot:

  • Name: The Arbiter
  • Username: The Arbiter#6636
  • Application ID: 1487080166969577502
  • Guild ID (Firefrost Gaming): 1260574715546701936

Server Location:

  • Command Center: 63.143.34.217
  • Directory: /opt/firefrost-discord-bot
  • Port: 3500 (internal)
  • HTTPS: 443 (Nginx reverse proxy)

Bot Branding

Visual Identity:

  • Icon: Scales of Justice with Fire (left, orange #FF6B35) and Frost (right, cyan #4ECDC4) balanced by purple Arcane energy (#A855F7)
  • Banner: Judgment hall with Fire path (left) and Frost path (right) divided by Arcane beam
  • Theme: Fire/Frost/Arcane gradient throughout UI

Generated by: Gemini AI (Google)
Design Philosophy: The Arbiter judges who enters the realm and assigns paths


Configuration

Environment File: /opt/firefrost-discord-bot/.env

DISCORD_BOT_TOKEN=MTQ4NzA4MDE2Njk2OTU3NzUwMg.GU5EsT.mqBwo7XUHsciN9jNy9OygTRkaMZ9qJ2tHw7HbI
GUILD_ID=1260574715546701936
DISCORD_CLIENT_ID=1487080166969577502
DISCORD_CLIENT_SECRET=xOK9ZYgionyqd-huGJRE2Rym98zy0W-m
REDIRECT_URI=https://discord-bot.firefrostgaming.com/auth/discord/callback
ADMIN_USERS=269225344572063754,219309716021444609,669981568059703316
PORT=3500
NODE_ENV=production
SESSION_SECRET=[auto-generated on deployment]

⚠️ Security Note: All credentials stored in Vaultwarden. Never commit .env to Git.


Role Mappings

Configuration File: /opt/firefrost-discord-bot/role-mappings.json

Status: COMPLETE - All 10 tiers configured by Holly on March 27, 2026

Current Mappings:

{
  "the-awakened": "1482490386634248273",
  "the-sovereign": "1482488242677874778",
  "fire-elemental": "1487181476755996823",
  "frost-elemental": "1487184348474218778",
  "fire-knight": "1487183625751880818",
  "frost-knight": "1487184476371222558",
  "fire-master": "1487183822951895546",
  "frost-master": "1487184618860249261",
  "fire-legend": "1487184056387748935",
  "frost-legend": "1487184718152138865"
}

By Path:

🔥 Fire Path:

  • Fire Elemental ($5): 1487181476755996823
  • Fire Knight ($10): 1487183625751880818
  • Fire Master ($15): 1487183822951895546
  • Fire Legend ($20): 1487184056387748935

❄️ Frost Path:

  • Frost Elemental ($5): 1487184348474218778
  • Frost Knight ($10): 1487184476371222558
  • Frost Master ($15): 1487184618860249261
  • Frost Legend ($20): 1487184718152138865

Universal Tiers:

  • The Awakened ($1): 1482490386634248273
  • The Sovereign ($499): 1482488242677874778

Mapping Structure:

  • Keys: Paymenter product slugs (lowercase, hyphenated)
  • Values: Discord role IDs (18-19 digit snowflakes)

Configured By: Holly (unicorn20089 / The Catalyst)
Date Completed: March 27, 2026

Full Documentation: See docs/systems/arbiter-discord-role-mappings.md for complete mapping table, testing checklist, and troubleshooting guide.


Systemd Service

Service File: /etc/systemd/system/firefrost-discord-bot.service

[Unit]
Description=The Arbiter - Firefrost Gaming Discord Bot
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/firefrost-discord-bot
ExecStart=/usr/bin/node /opt/firefrost-discord-bot/bot.js
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=firefrost-discord-bot

[Install]
WantedBy=multi-user.target

Management Commands:

# View status
systemctl status firefrost-discord-bot

# View logs (live)
journalctl -u firefrost-discord-bot -f

# View last 50 log entries
journalctl -u firefrost-discord-bot -n 50

# Restart service
systemctl restart firefrost-discord-bot

# Stop service
systemctl stop firefrost-discord-bot

# Start service
systemctl start firefrost-discord-bot

Nginx Configuration

Config File: /etc/nginx/sites-available/discord-bot.firefrostgaming.com

server {
    listen 63.143.34.217:80;
    server_name discord-bot.firefrostgaming.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 63.143.34.217:443 ssl http2;
    server_name discord-bot.firefrostgaming.com;

    ssl_certificate /etc/letsencrypt/live/discord-bot.firefrostgaming.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/discord-bot.firefrostgaming.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    location / {
        proxy_pass http://localhost:3500;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }

    access_log /var/log/nginx/discord-bot.access.log;
    error_log /var/log/nginx/discord-bot.error.log;
}

SSL Certificate:

  • Provider: Let's Encrypt
  • Issued: March 27, 2026
  • Expires: June 25, 2026
  • Auto-renewal: Certbot handles this automatically

Dependencies

Node.js: v20.20.0 (LTS)
npm: 10.8.2

npm Packages:

{
  "discord.js": "^14.14.1",
  "express": "^4.18.2",
  "body-parser": "^1.20.2",
  "express-session": "^1.18.1",
  "passport": "^0.7.0",
  "passport-discord": "^0.1.4",
  "cookie-parser": "^1.4.7",
  "dotenv": "^17.3.1"
}

Install dependencies:

cd /opt/firefrost-discord-bot
npm install

Admin Panel Features

Role Management:

  • View all 10 subscription tiers
  • Add/update Discord role IDs
  • See current role status (configured/not configured)
  • Real-time validation of role IDs

Authentication:

  • Discord OAuth2 login
  • Whitelist-based authorization (only Holly, Meg, Michael)
  • Session-based authentication with secure cookies

User Interface:

  • Fire Path tiers (orange accent)
  • Frost Path tiers (cyan accent)
  • Universal tiers (purple accent)
  • Responsive design
  • User avatar and logout in header

Webhook Endpoints

Paymenter Webhook:

  • URL: https://discord-bot.firefrostgaming.com/webhook/paymenter
  • Method: POST
  • Content-Type: application/json

Expected Payload:

{
  "event": "subscription.created",
  "user": {
    "discord_id": "123456789012345678"
  },
  "product": {
    "slug": "fire-elemental",
    "id": "1"
  }
}

Supported Events:

  • subscription.created - Add role
  • subscription.renewed - Add role
  • subscription.cancelled - Remove role
  • subscription.expired - Remove role

Health Check:

  • URL: https://discord-bot.firefrostgaming.com/health
  • Method: GET
  • Returns: Bot status, uptime

OAuth2 Configuration

Discord Developer Portal:

  • Application: The Arbiter
  • Client ID: 1487080166969577502
  • Redirect URI: https://discord-bot.firefrostgaming.com/auth/discord/callback

OAuth2 Scopes:

  • identify - Read user profile

Privileged Gateway Intents (Enabled):

  • Presence Intent
  • Server Members Intent (CRITICAL for role assignment)
  • Message Content Intent

Troubleshooting

Bot Shows Offline in Discord

# Check service status
systemctl status firefrost-discord-bot

# Check logs for errors
journalctl -u firefrost-discord-bot -n 50

Common causes:

  • Invalid bot token
  • Discord API outage
  • Service not running

Admin Panel Login Loop

Symptoms: Redirects to login after authorizing Discord

Solution: Verify app.set('trust proxy', 1); is present in bot.js (line 62)

Why this happens: Nginx does SSL termination, Express sees HTTP requests, refuses to set secure cookies without trusting X-Forwarded-Proto header.

Role Not Assigned After Webhook

# Check webhook logs
journalctl -u firefrost-discord-bot | grep "Webhook received"

# Verify role mapping exists
cat /opt/firefrost-discord-bot/role-mappings.json

# Check Discord bot permissions
# Bot must have "Manage Roles" permission
# Bot's role must be HIGHER than the roles it's assigning

Nginx 502 Bad Gateway

# Verify bot is listening on port 3500
netstat -tlnp | grep 3500

# Restart bot service
systemctl restart firefrost-discord-bot

# Check Nginx config
nginx -t

Deployment History

March 27, 2026 - Initial Deployment & Configuration

  • Created Discord bot application "The Arbiter"
  • Generated icon and banner via Gemini AI
  • Deployed bot.js on Command Center
  • Configured systemd service
  • Set up Nginx reverse proxy with Let's Encrypt SSL
  • Deployed admin panel with Discord OAuth2
  • Fixed SSL termination / secure cookie issue with app.set('trust proxy', 1);
  • Created Holly's role setup guide
  • Holly completed all 10 role ID mappings (Fire/Frost paths + Universal tiers)
  • Status: Fully Operational - All tiers configured, ready for webhook testing

Security Considerations

Secrets Management:

  • All credentials in .env file
  • .env never committed to Git
  • Session secret auto-generated with openssl
  • Client secret rotated during deployment

Authentication:

  • Whitelist-based admin access (3 users)
  • Discord OAuth2 for identity verification
  • Session-based authentication
  • Secure cookies in production

Network Security:

  • Bot only accessible via HTTPS
  • Nginx handles SSL termination
  • Internal port 3500 not exposed externally
  • Rate limiting via Nginx (if needed, add later)

Bot Permissions:

  • Minimal Discord permissions (Manage Roles, Send Messages)
  • No Administrator permission
  • Bot role positioned correctly in Discord hierarchy

Future Enhancements

Potential additions:

  • Audit logging to Discord channel for role changes
  • Webhook retry logic for failed deliveries
  • Role assignment history/statistics
  • Integration with LuckPerms for in-game permission sync
  • Multi-server support (if Firefrost expands to multiple Discord servers)

  • Holly's Role Setup Guide: docs/guides/holly-discord-roles-setup.md
  • Subscription Automation Guide: docs/guides/subscription-automation-guide.md
  • Discord Bot Admin Panel Guide: docs/guides/discord-bot-admin-panel.md
  • Paymenter Configuration: docs/services/paymenter-configuration.md
  • LuckPerms MySQL Database: docs/services/luckperms-mysql-database.md

Support Contacts

Technical Issues:

  • Michael (Frostystyle) - Server owner, technical lead
  • Discord: #staff-lounge channel

Role Management Questions:

  • Holly (unicorn20089) - Lead builder, role configuration

Last Updated: March 27, 2026
Originally Deployed By: The Verifier (Chronicler #42)
Role Configuration Completed By: Holly (The Catalyst) via The Herald (Chronicler #43)
Status: Production - Fully Configured - All 10 tiers mapped, ready for Paymenter webhook integration