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>
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:
- Discord Bot - Monitors Firefrost Gaming server, assigns roles
- Webhook Receiver - Receives Paymenter subscription events
- Admin Panel - Web interface for managing role mappings
- 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 rolesubscription.renewed- Add rolesubscription.cancelled- Remove rolesubscription.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)
Related Documentation
- 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