Files
firefrost-operations-manual/docs/guides/subscription-automation-guide.md
Claude (Chronicler #47) f815525f81 fix: rename Founder tier to Sovereign across all active docs
The top subscription tier is Sovereign, not Founder.
This has been corrected multiple times across sessions — fixing at source.

FILES UPDATED:
- docs/core/tasks.md
- docs/core/project-scope.md
- docs/tasks/rank-system-deployment/rank-structure.md
- docs/tasks/paymenter-pterodactyl-integration/README.md
- docs/archive/2026-02-09-consolidation/luckperms-structure.md
- docs/planning/subscription-tiers.md
- docs/planning/awakened-gateway.md
- docs/guides/subscription-automation-guide.md
- docs/guides/holly-discord-roles-setup.md
- docs/guides/holly-wanderer-permissions-setup.md
- docs/systems/arbiter-discord-role-mappings.md
- docs/branding/trinity-leadership-artwork.md

NOTE: References to 'founders' meaning Michael/Meg/Holly as company
founders were intentionally preserved. Only tier name updated.

Signed-off-by: claude@firefrostgaming.com
2026-03-29 19:42:01 +00:00

1931 lines
50 KiB
Markdown

# Firefrost Gaming - Subscription Automation Guide
**Version:** 1.0
**Date:** March 23, 2026
**Author:** Chronicler #40
**Audience:** Holly (Lead Builder) + Michael (for Discord bot setup)
**Purpose:** Automate subscriber tier assignment from Paymenter purchase to in-game ranks
---
## 📋 TABLE OF CONTENTS
1. [Overview](#overview)
2. [Architecture](#architecture)
3. [Prerequisites](#prerequisites)
4. [Part 1: Discord Bot Setup](#part-1-discord-bot-setup)
5. [Part 2: Discord Roles Configuration](#part-2-discord-roles-configuration)
6. [Part 3: LuckPerms Groups & Permissions](#part-3-luckperms-groups-permissions)
7. [Part 4: LuckPerms Discord Integration](#part-4-luckperms-discord-integration)
8. [Part 5: Paymenter Webhook Configuration](#part-5-paymenter-webhook-configuration)
9. [Testing & Verification](#testing-verification)
10. [Troubleshooting](#troubleshooting)
---
## 🎯 OVERVIEW
### What This Guide Does
This guide sets up **fully automated subscription management**:
1. User purchases subscription in Paymenter
2. Paymenter sends webhook to Discord bot
3. Discord bot assigns appropriate role to user
4. LuckPerms detects Discord role and syncs to in-game rank
5. Player automatically gets correct permissions on all 13 servers
**No manual work required after setup.**
### The Flow
```
User Subscribes ($1-$499)
Paymenter (billing.firefrostgaming.com)
Webhook fires (new purchase detected)
Discord Bot receives webhook
Bot assigns Discord role (The Awakened, Fire Elemental, etc.)
LuckPerms syncs Discord role → In-game group
Player gets permissions on all 13 servers instantly
Player can join servers, claim chunks, set homes (based on tier)
```
### Time Estimate
- **Discord Bot Setup:** 1-2 hours (Michael + Holly)
- **Discord Roles:** 30 minutes (Holly)
- **LuckPerms Configuration:** 2-3 hours (Holly, across all 13 servers)
- **Paymenter Webhooks:** 1 hour (Michael + Holly testing)
**Total:** 4-6 hours
---
## 🏗️ ARCHITECTURE
### Components
1. **Paymenter** (billing.firefrostgaming.com) - Billing system
2. **Discord Server** - Community hub
3. **Discord Bot** - Automation middleman
4. **LuckPerms** - Permission management (all 13 game servers)
5. **MySQL Database** - Shared permission storage
### Why This Design?
**Why not direct Paymenter → LuckPerms?**
- Discord is the community hub - subscribers want Discord access too
- Discord roles provide social status and channel access
- Discord bot can handle complex logic (upgrades, downgrades, cancellations)
- Easier to troubleshoot (can see Discord roles visually)
**Why LuckPerms syncs FROM Discord?**
- Industry standard approach
- Discord becomes "source of truth" for subscriber status
- If someone loses subscriber role in Discord, they automatically lose in-game perks
- Prevents desync between Discord and game servers
---
## ✅ PREREQUISITES
### Before You Start
**Complete these first:**
- [ ] **Server-Side Mod Deployment Guide** completed on ALL 13 servers
- [ ] LuckPerms installed and connected to MySQL on all servers
- [ ] Michael has created MySQL database and provided credentials
- [ ] You have admin access to Firefrost Gaming Discord server
- [ ] You have access to Paymenter admin panel
### What You'll Need
**From Michael:**
- Discord bot token (Michael will create this)
- Paymenter admin credentials
- MySQL database credentials (already provided for LuckPerms)
**Access Required:**
- Discord server admin permissions
- Pterodactyl panel access (to restart servers)
- SSH access to game servers (for LuckPerms testing)
- **Admin panel access** (for managing Discord role mappings) - see `docs/guides/discord-bot-admin-panel.md`
---
## 🤖 PART 1: DISCORD BOT SETUP
---
## 🔧 MICHAEL'S PRE-SETUP (Complete BEFORE Holly Starts)
**STOP: Michael must complete this entire section BEFORE handing the guide to Holly.**
### Task 1: Create Discord Application & Bot
**Michael's steps:**
1. Go to https://discord.com/developers/applications
2. Click **New Application**
3. Name: "Firefrost Subscription Manager"
4. Click **Create**
### Task 2: Configure Bot Settings
1. In the application, go to **Bot** tab (left sidebar)
2. Click **Add Bot****Yes, do it!**
3. Under **Privileged Gateway Intents**, enable:
-**Server Members Intent** (REQUIRED - bot needs to assign roles)
-**Message Content Intent** (REQUIRED - bot needs to read webhook data)
4. Click **Save Changes**
### Task 3: Get Bot Token
1. Under **Bot** tab, find **Token** section
2. Click **Reset Token** (confirm if asked)
3. Click **Copy** to copy the token
4. **SAVE THIS TOKEN SECURELY** - you'll give it to Holly later
**The token looks like:**
```
MTxxxxxxxxxxxxxxxxxxxxxx.xxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxx
```
**⚠️ NEVER share this token publicly or commit it to git!**
### Task 4: Invite Bot to Discord Server
1. Go to **OAuth2** tab → **URL Generator** (left sidebar)
2. Under **Scopes**, select:
-`bot`
-`applications.commands`
3. Under **Bot Permissions**, select:
-**Manage Roles** (REQUIRED - assigns subscriber roles)
-**Send Messages** (for welcome DMs)
-**Read Message History** (optional)
-**Use Slash Commands** (future-proofing)
4. Scroll down and **Copy** the generated URL
5. Open the URL in a new browser tab
6. Select **Firefrost Gaming** server from dropdown
7. Click **Authorize**
8. Complete the CAPTCHA
**The bot should now appear in your Discord server's member list (offline status is normal - it's not running yet).**
### Task 5: Get Discord Server ID (Guild ID)
1. Open Discord
2. Go to **User Settings** (gear icon)
3. Go to **Advanced** (left sidebar)
4. Enable **Developer Mode**
5. Close settings
6. Right-click your **Firefrost Gaming** server icon
7. Click **Copy Server ID**
8. **Save this ID** - you'll give it to Holly
**The ID looks like:**
```
123456789012345678
```
### Task 6: Deploy Bot Code on Command Center
**SSH to Command Center:**
```bash
ssh root@63.143.34.217
```
**Install Node.js (if not already installed):**
```bash
# Check if Node.js is installed
node --version
# If not installed or version < 18, install Node.js 20:
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs
# Verify
node --version # Should show v20.x.x
npm --version # Should show 10.x.x
```
**Create bot directory:**
```bash
mkdir -p /opt/firefrost-discord-bot
cd /opt/firefrost-discord-bot
```
**Create package.json:**
```bash
cat > package.json << 'EOF'
{
"name": "firefrost-discord-bot",
"version": "1.0.0",
"description": "Firefrost Gaming subscription automation bot",
"main": "bot.js",
"scripts": {
"start": "node bot.js"
},
"dependencies": {
"discord.js": "^14.14.1",
"express": "^4.18.2",
"body-parser": "^1.20.2"
}
}
EOF
```
**Install dependencies:**
```bash
npm install
```
**Create bot.js file:**
```bash
cat > bot.js << 'EOF'
// Firefrost Gaming - Discord Subscription Bot
// Handles Paymenter webhooks and assigns Discord roles
const { Client, GatewayIntentBits } = require('discord.js');
const express = require('express');
const bodyParser = require('body-parser');
// Configuration - REPLACE THESE VALUES
const DISCORD_TOKEN = 'YOUR_BOT_TOKEN_HERE';
const GUILD_ID = 'YOUR_GUILD_ID_HERE';
// Product ID to Role ID mapping (from Paymenter)
// Holly will fill these in after creating Discord roles
const PRODUCT_ROLE_MAP = {
'2': 'AWAKENED_ROLE_ID',
'3': 'FIRE_ELEMENTAL_ROLE_ID',
'4': 'FROST_ELEMENTAL_ROLE_ID',
'5': 'FIRE_KNIGHT_ROLE_ID',
'6': 'FROST_KNIGHT_ROLE_ID',
'7': 'FIRE_MASTER_ROLE_ID',
'8': 'FROST_MASTER_ROLE_ID',
'9': 'FIRE_LEGEND_ROLE_ID',
'10': 'FROST_LEGEND_ROLE_ID',
'11': 'SOVEREIGN_ROLE_ID'
};
// Initialize Discord client
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers
]
});
// Initialize Express for webhook receiver
const app = express();
app.use(bodyParser.json());
// Discord bot ready event
client.once('ready', () => {
console.log(`✅ Bot logged in as ${client.user.tag}`);
console.log(`🔗 Connected to ${client.guilds.cache.size} server(s)`);
});
// Webhook endpoint - Paymenter sends POST here
app.post('/webhook/paymenter', async (req, res) => {
try {
console.log('📬 Received webhook from Paymenter');
console.log('Payload:', JSON.stringify(req.body, null, 2));
const { event, product_id, user_email, discord_id } = req.body;
// Validate webhook
if (!event || !product_id) {
console.error('❌ Invalid webhook data - missing event or product_id');
return res.status(400).json({ error: 'Missing required fields' });
}
if (!discord_id) {
console.error('⚠️ No discord_id provided - cannot assign role');
return res.status(400).json({ error: 'Missing discord_id' });
}
console.log(`📦 Event: ${event}, Product: ${product_id}, Discord ID: ${discord_id}`);
// Get Discord guild
const guild = client.guilds.cache.get(GUILD_ID);
if (!guild) {
console.error('❌ Guild not found');
return res.status(500).json({ error: 'Guild not found' });
}
// Get member
const member = await guild.members.fetch(discord_id);
if (!member) {
console.error('❌ Member not found in Discord server');
return res.status(404).json({ error: 'Member not found' });
}
// Get role ID for this product
const roleId = PRODUCT_ROLE_MAP[product_id];
if (!roleId || roleId.includes('ROLE_ID')) {
console.error(`❌ No role mapped for product ${product_id} (or role ID not configured)`);
return res.status(400).json({ error: 'Unknown product or role not configured' });
}
// Handle event
if (event === 'subscription.created' || event === 'payment.completed') {
// Add role
await member.roles.add(roleId);
console.log(`✅ Added role ${roleId} to ${member.user.tag}`);
// Send welcome DM
try {
await member.send(`🎉 Welcome to Firefrost Gaming! Your subscription is now active. Check out the server - your perks are ready!`);
console.log(`📨 Sent welcome DM to ${member.user.tag}`);
} catch (err) {
console.log('⚠️ Could not send DM (user has DMs disabled)');
}
} else if (event === 'subscription.cancelled' || event === 'subscription.expired') {
// Remove role
await member.roles.remove(roleId);
console.log(`❌ Removed role ${roleId} from ${member.user.tag}`);
} else {
console.log(`⚠️ Unknown event type: ${event}`);
}
res.status(200).json({ success: true });
} catch (error) {
console.error('❌ Webhook processing error:', error);
res.status(500).json({ error: 'Internal server error', details: error.message });
}
});
// Health check endpoint
app.get('/health', (req, res) => {
res.status(200).json({
status: 'healthy',
bot: client.user ? client.user.tag : 'disconnected',
uptime: process.uptime()
});
});
// Start Express server
const PORT = 3100;
app.listen(PORT, () => {
console.log(`🌐 Webhook server listening on port ${PORT}`);
console.log(`📍 Webhook URL: http://localhost:${PORT}/webhook/paymenter`);
});
// Start Discord bot
client.login(DISCORD_TOKEN);
EOF
```
**Edit bot.js and add your credentials:**
```bash
nano bot.js
```
**Find these lines:**
```javascript
const DISCORD_TOKEN = 'YOUR_BOT_TOKEN_HERE';
const GUILD_ID = 'YOUR_GUILD_ID_HERE';
```
**Replace with:**
```javascript
const DISCORD_TOKEN = 'MTxxxx...'; // Your actual bot token from Task 3
const GUILD_ID = '123456789012345678'; // Your actual server ID from Task 5
```
**Save and exit** (Ctrl+X, Y, Enter)
**Create systemd service:**
```bash
cat > /etc/systemd/system/firefrost-discord-bot.service << 'EOF'
[Unit]
Description=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
[Install]
WantedBy=multi-user.target
EOF
```
**Enable and start the bot:**
```bash
# Reload systemd
systemctl daemon-reload
# Enable auto-start on boot
systemctl enable firefrost-discord-bot
# Start the bot
systemctl start firefrost-discord-bot
# Check status
systemctl status firefrost-discord-bot
```
**You should see:**
```
● firefrost-discord-bot.service - Firefrost Gaming Discord Bot
Loaded: loaded
Active: active (running)
```
**View logs to confirm it's working:**
```bash
journalctl -u firefrost-discord-bot -f
```
**You should see:**
```
✅ Bot logged in as Firefrost Subscription Manager#1234
🔗 Connected to 1 server(s)
🌐 Webhook server listening on port 3100
```
**If you see errors about invalid token:**
- Double-check you copied the token correctly
- Make sure there are no extra spaces
- Verify the token hasn't been reset/revoked
**Press Ctrl+C to exit log view when done.**
### Task 7: Set Up DNS (Cloudflare)
**Before setting up Nginx, add DNS record:**
1. Go to https://dash.cloudflare.com
2. Select **firefrostgaming.com** domain
3. Go to **DNS****Records**
4. Click **Add record**
5. Configure:
- **Type:** A
- **Name:** webhook
- **IPv4 address:** 63.143.34.217 (Command Center IP)
- **Proxy status:** 🟠 DNS only (turn OFF the orange cloud)
- **TTL:** Auto
6. Click **Save**
**Wait 1-2 minutes for DNS to propagate.**
**Verify DNS is working:**
```bash
# Test DNS resolution
dig webhook.firefrostgaming.com
# Should show:
# webhook.firefrostgaming.com. 300 IN A 63.143.34.217
```
### Task 8: Set Up Nginx Reverse Proxy
**Still on Command Center, configure Nginx:**
```bash
cat > /etc/nginx/sites-available/discord-webhook << 'EOF'
server {
listen 80;
server_name webhook.firefrostgaming.com;
location / {
proxy_pass http://localhost:3100;
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_cache_bypass $http_upgrade;
}
}
EOF
```
**Enable the site:**
```bash
ln -s /etc/nginx/sites-available/discord-webhook /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
```
**Get SSL certificate:**
```bash
certbot --nginx -d webhook.firefrostgaming.com
```
**Test the webhook endpoint:**
```bash
curl https://webhook.firefrostgaming.com/health
```
**Should return:**
```json
{"status":"healthy","bot":"Firefrost Subscription Manager#1234","uptime":123.456}
```
### Task 9: Set Up Discord Bot Admin Panel
**PURPOSE:** Deploy web interface so Holly can manage Discord role mappings herself (no SSH access needed).
**⚠️ IMPORTANT:** Complete admin panel setup is documented in a separate guide.
**See:** `docs/guides/discord-bot-admin-panel.md`
**Quick Overview:**
The admin panel allows Holly to:
- Log in via Discord OAuth (no passwords)
- Update all 10 product → Discord role ID mappings
- Save changes instantly (no bot restart needed)
- View bot status and recent webhooks
**Setup Steps (High-Level):**
1. Create dedicated `firefrost-bot` Linux user (security - don't run as root)
2. Set up Discord OAuth2 application
3. Deploy backend code (provided by Gemini/Google AI)
4. Deploy frontend code (provided by Gemini/Google AI)
5. Configure Nginx reverse proxy + SSL
6. Give Holly admin panel URL and walk through usage
**Time Required:** 2-3 hours (one-time setup)
**Once Complete:**
Holly will access admin panel at:
```
https://discord-bot.firefrostgaming.com/admin
```
**Status:** Full implementation guide available at `docs/guides/discord-bot-admin-panel.md`
**For now, continue with manual method below (Holly gives you role IDs, you update bot.js). We'll migrate to admin panel later.**
---
### Task 9 (ALTERNATIVE - MANUAL METHOD)
**If admin panel isn't set up yet, use this manual approach:**
Create a credentials file for Holly:
```bash
cat > /root/holly-bot-credentials.txt << EOF
Firefrost Discord Bot - Credentials for Holly
Bot Name: Firefrost Subscription Manager
Guild ID: $(grep "const GUILD_ID" /opt/firefrost-discord-bot/bot.js | cut -d"'" -f2)
Webhook URL: https://webhook.firefrostgaming.com/webhook/paymenter
Next Steps:
1. Holly creates Discord roles (Part 2 of guide)
2. Holly gets role IDs and sends them to Michael
3. Michael updates bot.js PRODUCT_ROLE_MAP with role IDs
4. Michael restarts bot: systemctl restart firefrost-discord-bot
5. Test webhook flow
NOTE: Once admin panel is deployed, Holly can update role IDs herself.
See: docs/guides/discord-bot-admin-panel.md
---
Generated: $(date)
EOF
cat /root/holly-bot-credentials.txt
```
**Save this output - you'll give it to Holly.**
---
## ✅ MICHAEL'S PRE-SETUP COMPLETE
**Checklist before handing to Holly:**
- [ ] Discord bot created and invited to server
- [ ] Bot token saved securely
- [ ] Guild ID recorded
- [ ] Node.js installed on Command Center
- [ ] Bot code deployed to /opt/firefrost-discord-bot/
- [ ] Bot service running successfully
- [ ] Nginx reverse proxy configured
- [ ] SSL certificate obtained
- [ ] Webhook endpoint accessible at https://webhook.firefrostgaming.com
- [ ] Credentials file created for Holly
**If all checked, proceed to Part 2 and hand the guide to Holly.**
---
## 👥 HOLLY'S TASKS START HERE
**At this point, Michael has:**
- ✅ Created the Discord bot application
- ✅ Deployed bot code to Command Center
- ✅ Set up Nginx reverse proxy
- ✅ Bot is running and accessible at https://webhook.firefrostgaming.com
**Holly, you now need to:**
1. Create Discord roles (Part 2)
2. **EITHER:**
- **Option A (Recommended):** Use Discord Bot Admin Panel at `discord-bot.firefrostgaming.com/admin` to update role IDs
- **Option B (Manual):** Give role IDs to Michael, he updates bot.js via SSH
3. Configure LuckPerms groups and permissions (Part 3)
4. Set up LuckPerms Discord integration (Part 4)
5. Configure Paymenter webhooks (Part 5)
6. Test the complete flow
**Note:** If admin panel is set up (Option A), you can update role mappings yourself anytime. If not (Option B), you'll need Michael's help each time roles change.
**Admin panel documentation:** `docs/guides/discord-bot-admin-panel.md`
---
## 👥 PART 2: DISCORD ROLES CONFIGURATION
### Step 1: Create Discord Roles (Holly's Task)
**In your Discord server:**
1. Right-click server icon → **Server Settings**
2. Click **Roles**
3. Click **Create Role** for each tier
**Create these roles (in order, top to bottom):**
#### Role 1: Sovereign
- **Name:** `⚡ Sovereign`
- **Color:** `#FFD600` (Amber Gold)
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
- **Mentionable:** ✅ Yes
#### Role 2: Fire Legend
- **Name:** `🔥 Fire Legend`
- **Color:** `#FF3D00` (Deep Orange/Red)
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
#### Role 3: Frost Legend
- **Name:** `❄️ Frost Legend`
- **Color:** `#00E5FF` (Electric Cyan)
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
#### Role 4: Fire Master
- **Name:** `🔥 Fire Master`
- **Color:** `#FF3D00`
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
#### Role 5: Frost Master
- **Name:** `❄️ Frost Master`
- **Color:** `#00E5FF`
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
#### Role 6: Fire Knight
- **Name:** `🔥 Fire Knight`
- **Color:** `#FF3D00`
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
#### Role 7: Frost Knight
- **Name:** `❄️ Frost Knight`
- **Color:** `#00E5FF`
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
#### Role 8: Fire Elemental
- **Name:** `🔥 Fire Elemental`
- **Color:** `#FF3D00`
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
#### Role 9: Frost Elemental
- **Name:** `❄️ Frost Elemental`
- **Color:** `#00E5FF`
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
#### Role 10: The Awakened
- **Name:** `The Awakened`
- **Color:** `#FFFFFF` (White)
- **Permissions:** (default member permissions)
- **Display separately:** ✅ Yes
#### Role 11: Wanderer (Free)
- **Name:** `Wanderer`
- **Color:** `#99AAB5` (Gray)
- **Permissions:** Read messages only (restrict Send Messages in channels)
- **Display separately:** No
### Step 2: Get Role IDs
**For each role you just created:**
1. Right-click the role in Server Settings → Roles
2. Click **Copy ID** (if you don't see this, enable Developer Mode in Discord settings)
3. Paste the ID somewhere - you'll need them
**Create a mapping:**
```
The Awakened: 123456789012345678
Fire Elemental: 234567890123456789
Frost Elemental: 345678901234567890
Fire Knight: 456789012345678901
Frost Knight: 567890123456789012
Fire Master: 678901234567890123
Frost Master: 789012345678901234
Fire Legend: 890123456789012345
Frost Legend: 901234567890123456
Sovereign: 012345678901234567
```
### Step 3: Update Role Mappings in Bot
**After creating all Discord roles (Step 2), you need to tell the bot which role ID corresponds to which subscription tier.**
**You have TWO options:**
---
#### **OPTION A: Use Discord Bot Admin Panel** (RECOMMENDED)
**If admin panel is deployed** (see `docs/guides/discord-bot-admin-panel.md`):
**Holly can do this herself:**
1. Open admin panel: `https://discord-bot.firefrostgaming.com/admin`
2. Click **Login with Discord** (OAuth2 - no password needed)
3. You'll see a form with 10 product tiers
4. For each product, paste the Discord role ID you copied in Step 2
5. Click **Save** for each row (validates and saves instantly)
6. **No bot restart needed** - changes take effect immediately
7. Check `#bot-audit-logs` in Discord to see confirmation embed
**Example workflow:**
```
Product 2 (The Awakened) → Paste role ID → Click Save → ✅ Green confirmation
Product 3 (Fire Elemental) → Paste role ID → Click Save → ✅ Green confirmation
... (repeat for all 10 products)
```
**Status indicator:**
- 🟢 Green dot = Bot connected and working
- 🔴 Red dot = Bot offline (contact Michael)
**Complete guide:** `docs/guides/discord-bot-admin-panel.md`
---
#### **OPTION B: Manual Method** (If admin panel not deployed yet)
**Holly:** Copy all your role IDs and send them to Michael in this format:
```
The Awakened: 123456789012345678
Fire Elemental: 234567890123456789
Frost Elemental: 345678901234567890
Fire Knight: 456789012345678901
Frost Knight: 567890123456789012
Fire Master: 678901234567890123
Frost Master: 789012345678901234
Fire Legend: 890123456789012345
Frost Legend: 901234567890123456
Sovereign: 012345678901234567
```
**Michael:** Holly will give you the list above. SSH to Command Center and update the bot:
```bash
ssh root@63.143.34.217
nano /opt/firefrost-discord-bot/bot.js
```
Find the `PRODUCT_ROLE_MAP` or config.json section and update the role IDs.
Save, then restart:
```bash
systemctl restart firefrost-discord-bot
systemctl status firefrost-discord-bot
```
**Note:** This manual method requires bot restart and Michael's SSH access. **Option A (admin panel) is much better** - Holly can update roles anytime without waiting for Michael.
---
**After updating role mappings (either method), proceed to Step 4.**
### Step 4: Configure Channel Permissions
**Create private channels for Fire/Frost paths:**
#### Fire Path Channels
- `#🔥-fire-general` - Only visible to Fire Elemental+ roles
- `#🔥-fire-builds` - Only visible to Fire Elemental+ roles
- `#🔥-fire-strategy` - Only visible to Fire Elemental+ roles
**Permissions:**
- Deny: `@everyone` - View Channel
- Allow: `@🔥 Fire Elemental`, `@🔥 Fire Knight`, `@🔥 Fire Master`, `@🔥 Fire Legend`, `@⚡ Sovereign`
#### Frost Path Channels
- `#❄️-frost-general` - Only visible to Frost Elemental+ roles
- `#❄️-frost-builds` - Only visible to Frost Elemental+ roles
- `#❄️-frost-strategy` - Only visible to Frost Elemental+ roles
**Permissions:**
- Deny: `@everyone` - View Channel
- Allow: `@❄️ Frost Elemental`, `@❄️ Frost Knight`, `@❄️ Frost Master`, `@❄️ Frost Legend`, `@⚡ Sovereign`
#### The Nexus (Sovereign Only)
- `#⚡-the-nexus` - Only visible to Sovereign
**Permissions:**
- Deny: `@everyone` - View Channel
- Allow: `@⚡ Sovereign` only
---
## ⚙️ PART 3: LUCKPERMS GROUPS & PERMISSIONS
**This is the most important section - you'll configure 13 groups (11 subscriber tiers + 2 staff ranks) that control all in-game permissions.**
**⚠️ IMPORTANT:** Because all 13 servers connect to the SAME MySQL database, you only need to do this ONCE. Changes sync automatically to all servers.
---
## 🎯 CHOOSE YOUR METHOD
You have **two ways** to create LuckPerms groups:
### Method A: Web Editor (RECOMMENDED - Fast & Visual)
-**Time:** 30-45 minutes
-**Difficulty:** Easy (point and click)
-**Visual interface** - see group hierarchy, drag-and-drop permissions
-**Color picker** for chat prefixes
-**Built-in validation** - prevents mistakes
-**Better for learning** - understand the structure visually
- ⚠️ **Requires:** Server running, able to join in-game
**Best for:** Holly (Lead Builder) who might need to adjust permissions later
### Method B: Console Commands (Alternative - Exact & Reproducible)
- ⏱️ **Time:** 2-3 hours
- 📝 **Difficulty:** Moderate (lots of copy/paste)
-**Exact commands** - reproducible script
-**No internet upload** - stays on your servers
-**Good documentation** - can see exactly what was configured
- ⚠️ **Tedious:** ~150+ commands to paste one by one
**Best for:** Documentation purposes, automated deployment, or if you prefer terminal
---
**Choose one method below and follow those instructions:**
---
## 🌐 METHOD A: WEB EDITOR (RECOMMENDED)
### Step 1: Access the Web Editor
1. **Join any Minecraft server** (doesn't matter which - they all share the database)
2. **Run this command in-game:**
```
/lp editor
```
3. **Click the link** that appears in chat (looks like `https://luckperms.net/editor/xxxxxxxx`)
4. **Web editor opens** in your browser
**What you'll see:**
- Left sidebar: List of groups
- Main panel: Selected group's permissions and settings
- Top toolbar: Save, create group, import/export
---
### Step 2: Create Subscriber Groups
**Create these groups in order. For each group:**
1. Click **"Create Group"** button (top left)
2. Fill in the settings as shown below
3. Move to next group
---
#### Group 1: Wanderer (Free)
**Basic Settings:**
- **Name:** `wanderer`
- **Weight:** `10`
- **Display Name:** Wanderer
- **Parents:** None
**Prefix:**
- Click **"Add Prefix"**
- **Priority:** 100
- **Prefix:** `&7[Wanderer] ` (gray color)
- Use color picker or type `&7` for gray
**Permissions:** None needed
**Notes:** Default group for non-subscribers. No server access.
---
#### Group 2: The Awakened ($1 one-time)
**Basic Settings:**
- **Name:** `awakened`
- **Weight:** `20`
- **Parents:** Click "Add Parent" → Select `wanderer`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&f[The Awakened] ` (`&f` = white)
**Permissions:**
- Click **"Add Permission"**
- Add: `ftbessentials.home.set` → Set to `true`
- Add: `ftbessentials.home.teleport` → Set to `true`
**Meta (Data):**
- Click **"Add Meta"**
- **Key:** `max-homes` | **Value:** `1`
**Notes:** Entry tier. Gets server whitelist access and 1 home only.
---
#### Group 3: Fire Elemental ($5/month)
**Basic Settings:**
- **Name:** `fire_elemental`
- **Weight:** `30`
- **Parents:** `awakened`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&c[🔥 Fire Elemental] ` (`&c` = red/fire orange)
- You can paste the 🔥 emoji directly
**Permissions:**
- `ftbchunks.claim` → `true`
- `ftbessentials.rtp` → `true`
**Meta:**
- `max-homes` → `5`
- `max-claimed-chunks` → `25`
- `rtp-cooldown` → `3600` (60 minutes in seconds)
---
#### Group 4: Frost Elemental ($5/month)
**Basic Settings:**
- **Name:** `frost_elemental`
- **Weight:** `30`
- **Parents:** `awakened`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&b[❄️ Frost Elemental] ` (`&b` = cyan/frost blue)
**Permissions:**
- `ftbchunks.claim` → `true`
- `ftbessentials.rtp` → `true`
**Meta:**
- `max-homes` → `5`
- `max-claimed-chunks` → `25`
- `rtp-cooldown` → `3600`
**Notes:** Same perks as Fire Elemental, different path/color.
---
#### Group 5: Fire Knight ($10/month)
**Basic Settings:**
- **Name:** `fire_knight`
- **Weight:** `40`
- **Parents:** `fire_elemental`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&c[🔥 Fire Knight] `
**Meta:**
- `max-homes` → `10`
- `max-claimed-chunks` → `49`
- `max-force-loaded-chunks` → `4`
- `rtp-cooldown` → `1800` (30 minutes)
**Permissions:** Inherits from Fire Elemental (no new permissions needed)
---
#### Group 6: Frost Knight ($10/month)
**Basic Settings:**
- **Name:** `frost_knight`
- **Weight:** `40`
- **Parents:** `frost_elemental`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&b[❄️ Frost Knight] `
**Meta:**
- `max-homes` → `10`
- `max-claimed-chunks` → `49`
- `max-force-loaded-chunks` → `4`
- `rtp-cooldown` → `1800`
---
#### Group 7: Fire Master ($15/month)
**Basic Settings:**
- **Name:** `fire_master`
- **Weight:** `50`
- **Parents:** `fire_knight`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&c[🔥 Fire Master] `
**Meta:**
- `max-homes` → `20`
- `max-claimed-chunks` → `100`
- `max-force-loaded-chunks` → `9`
- `rtp-cooldown` → `900` (15 minutes)
---
#### Group 8: Frost Master ($15/month)
**Basic Settings:**
- **Name:** `frost_master`
- **Weight:** `50`
- **Parents:** `frost_knight`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&b[❄️ Frost Master] `
**Meta:**
- `max-homes` → `20`
- `max-claimed-chunks` → `100`
- `max-force-loaded-chunks` → `9`
- `rtp-cooldown` → `900`
---
#### Group 9: Fire Legend ($20/month)
**Basic Settings:**
- **Name:** `fire_legend`
- **Weight:** `60`
- **Parents:** `fire_master`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&c[🔥 Fire Legend] `
**Meta:**
- `max-homes` → `35`
- `max-claimed-chunks` → `121`
- `max-force-loaded-chunks` → `16`
- `rtp-cooldown` → `600` (10 minutes)
---
#### Group 10: Frost Legend ($20/month)
**Basic Settings:**
- **Name:** `frost_legend`
- **Weight:** `60`
- **Parents:** `frost_master`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&b[❄️ Frost Legend] `
**Meta:**
- `max-homes` → `35`
- `max-claimed-chunks` → `121`
- `max-force-loaded-chunks` → `16`
- `rtp-cooldown` → `600`
---
#### Group 11: Sovereign ($499 lifetime)
**Basic Settings:**
- **Name:** `sovereign`
- **Weight:** `100`
- **Parents:** `awakened` (not Legend - Sovereign is separate from paths)
**Prefix:**
- **Priority:** 100
- **Prefix:** `&6[⚡ Sovereign] ` (`&6` = gold/amber)
**Permissions:**
- `ftbessentials.rtp` → `true`
- `ftbchunks.claim` → `true`
**Meta:**
- `max-homes` → `50`
- `max-claimed-chunks` → `225`
- `max-force-loaded-chunks` → `81`
- **No rtp-cooldown meta** (unlimited /rtp for Sovereign)
**Notes:** Sovereign gets BOTH Fire + Frost path access (configured in Discord, not LuckPerms).
---
### Step 3: Create Staff Groups
**CRITICAL: WorldEdit is powerful. Only staff should have access.**
#### Group 12: Builder (Holly - Lead Builder)
**Basic Settings:**
- **Name:** `builder`
- **Weight:** `1000`
- **Parents:** `default` (or none)
**Prefix:**
- **Priority:** 100
- **Prefix:** `&6[🔨 Builder] `
**Permissions:**
- `worldedit.*` → `true` (gives ALL WorldEdit permissions)
- `minecraft.command.gamemode` → `true`
- `ftbchunks.*` → `true`
**Meta:**
- `max-homes` → `100`
- `max-claimed-chunks` → `1000`
- `max-force-loaded-chunks` → `100`
---
#### Group 13: Owner (Michael/Frostystyle)
**Basic Settings:**
- **Name:** `owner`
- **Weight:** `10000`
- **Parents:** `builder`
**Prefix:**
- **Priority:** 100
- **Prefix:** `&c[👑 Owner] ` (`&c` = red)
**Permissions:**
- `*` → `true` (ALL permissions - full admin)
**Notes:** Owner inherits Builder's WorldEdit access plus everything else.
---
### Step 4: Deny WorldEdit to ALL Subscribers
**CRITICAL SECURITY STEP:**
For **each subscriber group** (wanderer through sovereign), add this permission:
- **Permission:** `worldedit.*`
- **Value:** `false` (red X)
**Groups to set this on:**
- wanderer
- awakened
- fire_elemental
- frost_elemental
- fire_knight
- frost_knight
- fire_master
- frost_master
- fire_legend
- frost_legend
- sovereign
**Why:** Prevents subscribers (even $499 Sovereign) from using WorldEdit to duplicate items, grief, or bypass protections.
---
### Step 5: Save and Apply
1. **Click "Save" button** (top right)
2. **Web editor generates a command** that starts with `/lp applyedits`
3. **Copy the entire command**
4. **Go back to Minecraft**
5. **Paste the command in console** (or in-game chat if you have permission)
6. **Press Enter**
**You'll see:**
```
[LuckPerms] Applied changes from editor session.
```
**Done! All 13 groups are now created and synced across all servers.**
---
### Step 6: Assign Users to Groups
**Still in Minecraft console, assign Holly and yourself:**
```
/lp user unicorn20089 parent set builder
/lp user Frostystyle parent set owner
```
**Replace `Frostystyle` with your actual Minecraft username.**
---
### Step 7: Verify Groups Exist
```
/lp listgroups
```
**You should see all 13 groups listed with their weights.**
---
## 📝 METHOD B: CONSOLE COMMANDS (ALTERNATIVE)
**If you prefer console commands over the web editor, use these commands instead.**
### Step 1: Access Server Console
1. Go to Pterodactyl Panel: https://panel.firefrostgaming.com
2. Click on any server (doesn't matter which)
3. Click **Console** tab
4. Make sure server is **running**
---
### Step 2: Run These Commands (Copy/Paste Each One)
**All commands must be run in the server console. They will sync to all 13 servers automatically via MySQL.**
---
#### Create Wanderer Group (Free Tier)
```
/lp creategroup wanderer
/lp group wanderer setweight 10
/lp group wanderer meta setprefix "&7[Wanderer] "
```
---
#### Create Awakened Group ($1 Tier)
```
/lp creategroup awakened
/lp group awakened parent add wanderer
/lp group awakened setweight 20
/lp group awakened meta setprefix "&f[The Awakened] "
/lp group awakened permission set ftbessentials.home.set true
/lp group awakened permission set ftbessentials.home.teleport true
/lp group awakened meta setmeta max-homes 1
```
---
#### Create Fire Elemental Group ($5/mo)
```
/lp creategroup fire_elemental
/lp group fire_elemental parent add awakened
/lp group fire_elemental setweight 30
/lp group fire_elemental meta setprefix "&c[🔥 Fire Elemental] "
/lp group fire_elemental meta setmeta max-homes 5
/lp group fire_elemental permission set ftbchunks.claim true
/lp group fire_elemental meta setmeta max-claimed-chunks 25
/lp group fire_elemental permission set ftbessentials.rtp true
/lp group fire_elemental meta setmeta rtp-cooldown 3600
```
---
#### Create Frost Elemental Group ($5/mo)
```
/lp creategroup frost_elemental
/lp group frost_elemental parent add awakened
/lp group frost_elemental setweight 30
/lp group frost_elemental meta setprefix "&b[❄️ Frost Elemental] "
/lp group frost_elemental meta setmeta max-homes 5
/lp group frost_elemental permission set ftbchunks.claim true
/lp group frost_elemental meta setmeta max-claimed-chunks 25
/lp group frost_elemental permission set ftbessentials.rtp true
/lp group frost_elemental meta setmeta rtp-cooldown 3600
```
---
#### Create Fire Knight Group ($10/mo)
```
/lp creategroup fire_knight
/lp group fire_knight parent add fire_elemental
/lp group fire_knight setweight 40
/lp group fire_knight meta setprefix "&c[🔥 Fire Knight] "
/lp group fire_knight meta setmeta max-homes 10
/lp group fire_knight meta setmeta max-claimed-chunks 49
/lp group fire_knight meta setmeta max-force-loaded-chunks 4
/lp group fire_knight meta setmeta rtp-cooldown 1800
```
---
#### Create Frost Knight Group ($10/mo)
```
/lp creategroup frost_knight
/lp group frost_knight parent add frost_elemental
/lp group frost_knight setweight 40
/lp group frost_knight meta setprefix "&b[❄️ Frost Knight] "
/lp group frost_knight meta setmeta max-homes 10
/lp group frost_knight meta setmeta max-claimed-chunks 49
/lp group frost_knight meta setmeta max-force-loaded-chunks 4
/lp group frost_knight meta setmeta rtp-cooldown 1800
```
---
#### Create Fire Master Group ($15/mo)
```
/lp creategroup fire_master
/lp group fire_master parent add fire_knight
/lp group fire_master setweight 50
/lp group fire_master meta setprefix "&c[🔥 Fire Master] "
/lp group fire_master meta setmeta max-homes 20
/lp group fire_master meta setmeta max-claimed-chunks 100
/lp group fire_master meta setmeta max-force-loaded-chunks 9
/lp group fire_master meta setmeta rtp-cooldown 900
```
---
#### Create Frost Master Group ($15/mo)
```
/lp creategroup frost_master
/lp group frost_master parent add frost_knight
/lp group frost_master setweight 50
/lp group frost_master meta setprefix "&b[❄️ Frost Master] "
/lp group frost_master meta setmeta max-homes 20
/lp group frost_master meta setmeta max-claimed-chunks 100
/lp group frost_master meta setmeta max-force-loaded-chunks 9
/lp group frost_master meta setmeta rtp-cooldown 900
```
---
#### Create Fire Legend Group ($20/mo)
```
/lp creategroup fire_legend
/lp group fire_legend parent add fire_master
/lp group fire_legend setweight 60
/lp group fire_legend meta setprefix "&c[🔥 Fire Legend] "
/lp group fire_legend meta setmeta max-homes 35
/lp group fire_legend meta setmeta max-claimed-chunks 121
/lp group fire_legend meta setmeta max-force-loaded-chunks 16
/lp group fire_legend meta setmeta rtp-cooldown 600
```
---
#### Create Frost Legend Group ($20/mo)
```
/lp creategroup frost_legend
/lp group frost_legend parent add frost_master
/lp group frost_legend setweight 60
/lp group frost_legend meta setprefix "&b[❄️ Frost Legend] "
/lp group frost_legend meta setmeta max-homes 35
/lp group frost_legend meta setmeta max-claimed-chunks 121
/lp group frost_legend meta setmeta max-force-loaded-chunks 16
/lp group frost_legend meta setmeta rtp-cooldown 600
```
---
#### Create Sovereign Group ($499 Lifetime)
```
/lp creategroup sovereign
/lp group sovereign parent add awakened
/lp group sovereign setweight 100
/lp group sovereign meta setprefix "&6[⚡ Sovereign] "
/lp group sovereign meta setmeta max-homes 50
/lp group sovereign meta setmeta max-claimed-chunks 225
/lp group sovereign meta setmeta max-force-loaded-chunks 81
/lp group sovereign permission set ftbessentials.rtp true
```
---
#### Create Builder Staff Group (Holly)
```
/lp creategroup builder
/lp group builder setweight 1000
/lp group builder meta setprefix "&6[🔨 Builder] "
/lp group builder permission set worldedit.* true
/lp group builder permission set worldedit.navigation.* true
/lp group builder permission set worldedit.selection.* true
/lp group builder permission set worldedit.region.* true
/lp group builder permission set worldedit.clipboard.* true
/lp group builder permission set worldedit.generation.* true
/lp group builder permission set worldedit.history.* true
/lp group builder permission set worldedit.schematic.* true
/lp group builder permission set worldedit.brush.* true
/lp group builder permission set worldedit.tool.* true
/lp group builder permission set minecraft.command.gamemode true
/lp group builder permission set ftbchunks.* true
/lp group builder meta setmeta max-homes 100
/lp group builder meta setmeta max-claimed-chunks 1000
/lp group builder meta setmeta max-force-loaded-chunks 100
```
---
#### Create Owner Group (Michael/Frostystyle)
```
/lp creategroup owner
/lp group owner parent add builder
/lp group owner setweight 10000
/lp group owner meta setprefix "&c[👑 Owner] "
/lp group owner permission set * true
```
---
#### Deny WorldEdit to ALL Subscriber Groups (CRITICAL)
```
/lp group wanderer permission set worldedit.* false
/lp group awakened permission set worldedit.* false
/lp group fire_elemental permission set worldedit.* false
/lp group frost_elemental permission set worldedit.* false
/lp group fire_knight permission set worldedit.* false
/lp group frost_knight permission set worldedit.* false
/lp group fire_master permission set worldedit.* false
/lp group frost_master permission set worldedit.* false
/lp group fire_legend permission set worldedit.* false
/lp group frost_legend permission set worldedit.* false
/lp group sovereign permission set worldedit.* false
```
---
#### Assign Users to Groups
```
/lp user unicorn20089 parent set builder
/lp user Frostystyle parent set owner
```
**Replace `Frostystyle` with your actual Minecraft username.**
---
### Step 3: Verify Groups Created
```
/lp listgroups
```
**You should see all 13 groups listed.**
---
## ✅ NEXT STEP (AFTER EITHER METHOD)
Once groups are created (via web editor OR console commands), proceed to **Part 4: LuckPerms Discord Integration** to connect Discord roles to in-game groups.
---
## 🔗 PART 4: LUCKPERMS DISCORD INTEGRATION
**This connects Discord roles to LuckPerms groups.**
### Step 1: Enable Discord Integration in LuckPerms
**On EVERY server, edit `/config/luckperms/luckperms.conf`:**
**Find the section:**
```conf
# Discord integration
discord-integration {
enabled = false
}
```
**Change to:**
```conf
discord-integration {
enabled = true
# Role to group mappings
role-mappings {
# Format: "discord-role-id" = "luckperms-group"
"123456789012345678" = "awakened" # The Awakened
"234567890123456789" = "fire_elemental" # Fire Elemental
"345678901234567890" = "frost_elemental" # Frost Elemental
"456789012345678901" = "fire_knight" # Fire Knight
"567890123456789012" = "frost_knight" # Frost Knight
"678901234567890123" = "fire_master" # Fire Master
"789012345678901234" = "frost_master" # Frost Master
"890123456789012345" = "fire_legend" # Fire Legend
"901234567890123456" = "frost_legend" # Frost Legend
"012345678901234567" = "sovereign" # Sovereign
}
}
```
**Replace role IDs with the ACTUAL role IDs you copied in Part 2.**
**Save the file.**
### Step 2: Restart All Servers
**Via Pterodactyl Panel:**
1. Open each server's console
2. Click **Restart**
3. Wait for server to come back online
**Repeat for all 13 servers.**
### Step 3: Test Discord → LuckPerms Sync
**Manual test:**
1. Go to Discord
2. Manually assign yourself `The Awakened` role (right-click your name → Roles)
3. Join a Minecraft server
4. Run `/lp user YourUsername info`
5. Should show you're in the `awakened` group
**If it doesn't work:**
- Check LuckPerms config for typos in role IDs
- Check that Discord integration is enabled
- Restart the server
---
## 🪝 PART 5: PAYMENTER WEBHOOK CONFIGURATION
**This connects Paymenter to the Discord bot.**
### Step 1: Set Up Nginx Proxy (Michael's Task)
**On Command Center (where Discord bot runs):**
**Create file: `/etc/nginx/sites-available/discord-bot-webhook`**
```nginx
server {
listen 80;
server_name webhook.firefrostgaming.com;
location / {
proxy_pass http://localhost:3100;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
```
**Enable the site:**
```bash
ln -s /etc/nginx/sites-available/discord-bot-webhook /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
```
**Get SSL certificate:**
```bash
certbot --nginx -d webhook.firefrostgaming.com
```
**Now the webhook endpoint is:**
```
https://webhook.firefrostgaming.com/webhook/paymenter
```
### Step 2: Configure Paymenter Webhooks (Michael + Holly)
**In Paymenter admin panel:**
1. Go to **Settings** → **Webhooks**
2. Click **Add Webhook**
3. Configure:
- **URL:** `https://webhook.firefrostgaming.com/webhook/paymenter`
- **Events:**
- ✅ `subscription.created`
- ✅ `payment.completed`
- ✅ `subscription.cancelled`
- ✅ `subscription.expired`
- **Payload Format:** JSON
4. Click **Save**
### Step 3: Test Webhook
**Create a test purchase in Paymenter (use test mode if available).**
**Watch Discord bot logs:**
```bash
journalctl -u firefrost-discord-bot -f
```
**You should see:**
```
📬 Received webhook from Paymenter
📦 Event: subscription.created, Product: 2, User: 123456789012345678
✅ Added role 123456789012345678 to TestUser#1234
```
**If it works, the user should now have The Awakened role in Discord.**
**If it doesn't work:**
- Check webhook URL is correct
- Check Paymenter is sending the correct payload format
- Check Discord bot logs for errors
---
## ✅ TESTING & VERIFICATION
### End-to-End Test
**Complete flow test:**
1. **Create test user in Discord**
2. **Purchase Awakened tier ($1) in Paymenter**
3. **Verify webhook fires** (check Discord bot logs)
4. **Verify Discord role assigned** (check Discord - user should have "The Awakened" role)
5. **Join Minecraft server**
6. **Run `/lp user TestUser info`** - Should show `awakened` group
7. **Test permissions:**
- `/sethome test` - Should work (1 home allowed)
- `/sethome test2` - Should FAIL (only 1 home for Awakened)
- Try claiming chunks - Should FAIL (Awakened has 0 chunk claims)
- Try `/rtp` - Should FAIL (Awakened has no /rtp access)
**If all these work correctly, the automation is functioning!**
### Upgrade Test
**Test tier upgrade:**
1. Upgrade test user to Fire Elemental ($5/mo) in Paymenter
2. Verify Discord role changes (old role removed, new role added)
3. Join Minecraft server
4. Run `/lp user TestUser info` - Should show `fire_elemental` group
5. Test new permissions:
- `/sethome` - Should work (5 homes allowed)
- Claim chunks - Should work (25 chunks allowed)
- `/rtp` - Should work (60 minute cooldown)
### Cancellation Test
**Test subscription cancellation:**
1. Cancel test user's subscription in Paymenter
2. Verify Discord role removed
3. Join Minecraft server
4. Run `/lp user TestUser info` - Should show `wanderer` or default group
5. Test permissions:
- `/sethome` - Should FAIL (no subscription)
- Try joining server - Should be DENIED (whitelist = Awakened+ only)
---
## 🔧 TROUBLESHOOTING
### Discord Role Not Assigned After Purchase
**Symptoms:** User purchases subscription but doesn't get Discord role.
**Check:**
1. **Webhook logs:** `journalctl -u firefrost-discord-bot -f`
- Are webhooks being received?
2. **Paymenter webhook config:** Is webhook URL correct?
3. **Discord bot permissions:** Does bot have "Manage Roles" permission?
4. **Role position:** Bot's role must be ABOVE subscriber roles in Discord role hierarchy
**Solution:**
- Move bot's role to the top of the role list in Discord Server Settings
- Restart Discord bot: `systemctl restart firefrost-discord-bot`
---
### LuckPerms Not Syncing Discord Roles
**Symptoms:** User has Discord role but no in-game permissions.
**Check:**
1. **LuckPerms config:** Is Discord integration enabled?
2. **Role IDs:** Are Discord role IDs correct in luckperms.conf?
3. **Server restart:** Did you restart server after config change?
**Solution:**
- Double-check role IDs match (right-click role in Discord → Copy ID)
- Ensure luckperms.conf has correct mapping
- Restart all game servers
---
### User Can't Join Server After Subscribing
**Symptoms:** User purchased subscription, has Discord role, but can't join server.
**Check:**
1. **Whitelist status:** Is whitelist enabled on server?
2. **LuckPerms sync:** Run `/whitelist add Username` manually as test
3. **Server online:** Is server actually running?
**Solution:**
- Ensure LuckPerms-based whitelist is configured (see Server-Side Mod Deployment Guide)
- Check server console for "User not whitelisted" messages
- Manually add to whitelist temporarily while debugging
---
### Webhook Endpoint Returns 500 Error
**Symptoms:** Paymenter shows webhook failed with 500 error.
**Check:**
1. **Bot running:** `systemctl status firefrost-discord-bot`
2. **Bot logs:** `journalctl -u firefrost-discord-bot -f` for errors
3. **Nginx proxy:** Is Nginx running and proxying correctly?
**Solution:**
- Restart Discord bot
- Check bot code for syntax errors
- Test webhook manually with curl:
```bash
curl -X POST https://webhook.firefrostgaming.com/webhook/paymenter \
-H "Content-Type: application/json" \
-d '{"event":"subscription.created","product_id":"2","discord_id":"YOUR_DISCORD_ID"}'
```
---
## 📚 REFERENCE
### Quick Command Reference
#### Discord Bot Management
```bash
# Start bot
systemctl start firefrost-discord-bot
# Stop bot
systemctl stop firefrost-discord-bot
# Restart bot
systemctl restart firefrost-discord-bot
# View logs
journalctl -u firefrost-discord-bot -f
# Check status
systemctl status firefrost-discord-bot
```
#### LuckPerms Commands
```bash
# View user's groups
/lp user <username> info
# Manually add user to group
/lp user <username> parent add <groupname>
# Remove user from group
/lp user <username> parent remove <groupname>
# View group permissions
/lp group <groupname> permission info
# List all groups
/lp listgroups
```
---
### Subscriber Tier → Discord Role → LuckPerms Group Mapping
| Tier | Price | Discord Role | LuckPerms Group |
|------|-------|--------------|-----------------|
| Wanderer | Free | `Wanderer` | `wanderer` |
| Awakened | $1 | `The Awakened` | `awakened` |
| Fire Elemental | $5/mo | `🔥 Fire Elemental` | `fire_elemental` |
| Frost Elemental | $5/mo | `❄️ Frost Elemental` | `frost_elemental` |
| Fire Knight | $10/mo | `🔥 Fire Knight` | `fire_knight` |
| Frost Knight | $10/mo | `❄️ Frost Knight` | `frost_knight` |
| Fire Master | $15/mo | `🔥 Fire Master` | `fire_master` |
| Frost Master | $15/mo | `❄️ Frost Master` | `frost_master` |
| Fire Legend | $20/mo | `🔥 Fire Legend` | `fire_legend` |
| Frost Legend | $20/mo | `❄️ Frost Legend` | `frost_legend` |
| Sovereign | $499 | `⚡ Sovereign` | `sovereign` |
---
### File Locations Quick Reference
```
Command Center (63.143.34.217)
└── /opt/firefrost-discord-bot/
├── bot.js
├── package.json
└── node_modules/
Game Servers (TX1/NC1)
└── /config/luckperms/
└── luckperms.conf (Discord integration config)
Nginx
└── /etc/nginx/sites-available/
└── discord-bot-webhook
```
---
**End of Subscription Automation Guide**
**You've now completed the full automation setup! Users can subscribe in Paymenter and automatically get:**
- Discord role assignment
- In-game rank sync
- Correct permissions on all 13 servers
- Channel access based on Fire/Frost path
**Fire + Frost + Foundation = Where Love Builds Legacy** 🔥❄️
---
**Document Version:** 1.0
**Last Updated:** March 23, 2026
**Maintained By:** Firefrost Gaming Infrastructure Team