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>
466 lines
12 KiB
Markdown
466 lines
12 KiB
Markdown
# 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`
|
|
|
|
```bash
|
|
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:**
|
|
```json
|
|
{
|
|
"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`
|
|
|
|
```ini
|
|
[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:**
|
|
```bash
|
|
# 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`
|
|
|
|
```nginx
|
|
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:**
|
|
```json
|
|
{
|
|
"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:**
|
|
```bash
|
|
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:**
|
|
```json
|
|
{
|
|
"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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|