Event Requests
Allow your community to submit watch party event requests through a web form! Server moderators can approve or deny submissions, and approved events are automatically created as Discord Scheduled Events.
Overview
The Event Request System provides:
- 🔐 Discord OAuth Login - Secure authentication with Discord
- 📝 Web-based Form - User-friendly event submission interface
- ✅ Moderation Queue - Review and approve/deny requests
- 🎉 Auto-create Events - Approved events become Discord Scheduled Events
- ⏱️ Rate Limiting - Prevents spam (1 request per 5 minutes per user)
- 🌐 Dedicated Deployment - Each website serves one specific Discord server
How It Works
- User visits your event request form at your configured website
- User logs in with Discord (OAuth authentication)
- System validates guild membership:
- Checks if user is a member of the target server
- Non-members see error with invite link (if configured)
- Only server members can proceed
- User submits event details:
- Simple Mode (default): Title, description, time only. Moderators assign channels during approval.
- Advanced Mode (opt-in): Full control including channel selection from admin-configured whitelists.
- System revalidates membership at submission (prevents edge case of leaving server after login)
- Request appears in your moderation channel with Approve/Deny buttons
- Moderator clicks a button to approve or deny
- If approved, Discord Scheduled Event is created automatically
Security: Guild Membership Required
The bot validates that users are actual members of your Discord server both when they log in and when they submit the form. Non-members see a friendly error message with an invite link to join. This prevents spam from users outside your community.
Default Behavior
By default, event requests use Simple Mode: users submit event ideas and moderators handle channel logistics. This reduces decision fatigue and simplifies the user experience. Enable Advanced Mode with /eggshen-config event-requests allow-user-channel-selection allow:true to let users select channels.
Deployment Model
One Website = One Discord Server
Each event request form deployment is dedicated to one specific Discord server. If you host the bot for multiple servers, each server should deploy its own instance of the web form on their own domain.
Example:
- moviefans.example.com → Movie Fans Discord Server
- yourdomain.com → Your Discord Server
Setup Requirements
Prerequisites
This feature requires:
- A web server to host the event request form (e.g., yourdomain.com)
- Discord Client Secret from the Developer Portal
- Web server configuration (e.g., nginx)
- Additional environment variables
Step 1: Discord Developer Portal Setup
CRITICAL: OAuth Redirect URI
You MUST add the redirect URI to Discord Developer Portal BEFORE testing! Without this, users will get "Invalid OAuth2 redirect_uri" errors when trying to login.
- Go to Discord Developer Portal
- Select your bot application
- Navigate to OAuth2 section
- Click Add Redirect and enter:
- For local testing:
http://localhost:3000/api/auth/discord/callback - For production:
https://yourdomain.com/api/auth/discord/callback - The URL MUST match your
OAUTH_REDIRECT_URIenvironment variable exactly
- For local testing:
- Click Save Changes (don't forget this!)
- Copy your Client Secret from the OAuth2 page (keep it secure!)
Step 2: Environment Variables
Add these to your .env file:
# Required for event requests
DISCORD_CLIENT_SECRET=your_client_secret_here
# API Configuration
API_PORT=3000
OAUTH_REDIRECT_URI=https://yourdomain.com/api/auth/discord/callback
FORM_URL=https://yourdomain.com
ALLOWED_ORIGINS=https://yourdomain.comLocal Testing
For local testing, use:
OAUTH_REDIRECT_URI=http://localhost:3000/api/auth/discord/callback
FORM_URL=http://localhost:PORT
ALLOWED_ORIGINS=http://localhost:PORTStep 3: Deploy Web Form
The bot includes a web form in the /public folder. Deploy these files to your web server:
public/index.html- Event request formpublic/app.js- Form logicpublic/style.css- Styling
Required Configuration:
- Open
public/app.js - Find the
GUILD_IDconstant (around line 11) - Replace the placeholder with your Discord server's Guild ID:
const GUILD_ID = 'YOUR_GUILD_ID_HERE'; // Change this!Finding Your Guild ID
Run /eggshen-config event-requests get-link in your Discord server to see your Guild ID.
Example deployment:
- Update
GUILD_IDinpublic/app.js - Upload
/publiccontents tohttps://yourdomain.com - Ensure the domain matches your environment variables
Step 4: Configure Your Server
Event Requests Disabled by Default
Event requests are disabled by default for all servers. You must enable them using the toggle command below. Until enabled, the event request form will show a "disabled" message to users.
Use /eggshen-config event-requests commands in your Discord server:
1. Enable event requests (required first step):
/eggshen-config event-requests toggle enabled:true2. Configure required settings:
/eggshen-config event-requests moderation-channel channel:#event-requests
/eggshen-config event-requests server-name name:"Your Server Name"
/eggshen-config event-requests website-url url:https://yourdomain.com3. Optional settings:
/eggshen-config event-requests invite-url url:https://discord.gg/yourserverStep 5: Get Your Link
/eggshen-config event-requests get-linkThis gives you a unique link like: https://yourdomain.com?guild=YOUR_GUILD_ID
Share this link with your community!
Configuration Commands
All configuration is done via /eggshen-config event-requests subcommands:
View Current Settings
/eggshen-config event-requests viewShows your current configuration including the event request link.
Enable/Disable
/eggshen-config event-requests toggle enabled:true
/eggshen-config event-requests toggle enabled:falseTurn event requests on or off for your server.
Default State
Event requests are disabled by default. You must explicitly enable them with enabled:true before users can submit requests. When disabled, the event request form shows a message telling users the feature is not available.
Set Moderation Channel
/eggshen-config event-requests moderation-channel channel:#event-requestsChoose where event requests will be sent for approval. Must be a text channel.
Set Server Display Name
/eggshen-config event-requests server-name name:"My Awesome Server"This name appears on the event request form.
Set Website URL
/eggshen-config event-requests website-url url:https://yourdomain.comThe website where your event request form is hosted.
Set Invite Link (Optional)
/eggshen-config event-requests invite-url url:https://discord.gg/yourserverDiscord invite link shown on the form. Leave empty to hide.
Allow/Disallow Voice Requests
/eggshen-config event-requests allow-voice-requests allow:true
/eggshen-config event-requests allow-voice-requests allow:falseControl whether users can request voice/stage channels for events. When disabled, all events will be text-channel only.
Use cases for disabling:
- Server primarily uses text chat for watch parties
- Voice channels are reserved for specific purposes
- Simplify the event request form
Get Configuration Summary
/eggshen-config event-requests get-linkShows your form URL and reminds you to configure the GUILD_ID in your web form deployment.
Optional: Choose Simple or Advanced Mode
Simple Mode (default):
/eggshen-config event-requests allow-user-channel-selection allow:falseUsers submit basic event details only (title, description, time). The form hides channel selectors and shows: "Moderators will select the channels when approving your event." Moderators assign channels during approval.
Best for:
- New communities still establishing channel structure
- Servers with dedicated event coordinators
- Reducing decision fatigue for casual users
- Simplifying the submission process
Advanced Mode (opt-in):
/eggshen-config event-requests allow-user-channel-selection allow:trueUsers select specific text/voice channels from admin-configured whitelists (see below). Form shows Location field (required) and optional Voice Channel checkbox.
Best for:
- Experienced communities with established channels
- Power users who understand channel structure
- Community-driven events where users know best location
- Servers where moderators prefer not to assign channels
Recommended Default
Keep Simple Mode enabled by default. It provides the best experience for most users by removing the complexity of channel selection. Only switch to Advanced Mode if your community specifically requests more control.
Optional: Whitelist Allowed Channels
Advanced Mode Only
Channel whitelisting only applies when Advanced Mode is enabled. In Simple Mode, moderators assign channels during approval, so whitelisting is not needed.
By default (in Advanced Mode), users can select from all text channels and all voice/stage channels in your server. You can restrict this to specific channels:
Whitelist text channels:
/eggshen-config event-requests set-allowed-text-channels channel-ids:"123456,789012,345678"Whitelist voice channels:
/eggshen-config event-requests set-allowed-voice-channels channel-ids:"111222,333444"Allow all channels (reset to default):
/eggshen-config event-requests set-allowed-text-channels channel-ids:"all"
/eggshen-config event-requests set-allowed-voice-channels channel-ids:"all"When to Use Channel Whitelisting
Good use cases:
- Limit events to dedicated watch party channels (#movie-night, #tv-night)
- Exclude announcement or admin-only channels
- Simplify dropdown for servers with 50+ channels
- Prevent accidental selection of inappropriate channels
How to get Channel IDs:
- Enable Developer Mode in Discord Settings → Advanced
- Right-click any channel → Copy Channel ID
- Paste IDs comma-separated (no spaces)
Independent Controls
Text and voice whitelists are independent:
- You can limit text channels while allowing all voice channels
- Or vice versa
- Or limit both
- Empty list (default) = all channels of that type allowed
User Experience
Submitting a Request
- Visit the link provided by server admins
- Click "Login with Discord" to authenticate
- Fill out the form:
- Event title (required)
- Description (optional)
- Location (required) - Text channel for the watch party
- Voice channel (optional) - Check the box to add voice/stage channel
- Start date and time (required)
- End date and time (optional)
- Frequency (optional: Once, Weekly, Biweekly, Monthly)
- Click "Submit Request"
- Wait for moderator approval
Channel Selection
Location is where the watch party chat happens (text channel, always required).
Voice channel is optional and only shown if enabled by server admins. Check the box if you want to include a voice/stage channel for the event.
For Moderators
When a request is submitted:
- Request appears in moderation channel with all details
- Shows location (text channel) and voice channel (if requested)
- Approval buttons vary based on request:
- Text-only request: ✅ Approve, ✏️ Edit, or ❌ Deny
- Request with voice: ✅ Approve Both, 💬 Text Only, ✏️ Edit, or ❌ Deny
- Choose approval type:
- Approve Both → Creates voice channel event with text channel coordination
- Text Only → Creates text-only event (removes voice channel from request)
- Edit → Opens a form to correct the title or description — saving it immediately approves the request too (see below)
- Deny → Opens a form for an optional reason, then removes the request without creating an event
Editing a Request (Immediately Approves It)
If a submitter's title is wrong or the description needs more detail, click ✏️ Edit. This opens a form pre-filled with the current title and description — update either field and submit.
Saving the edit both updates the request and approves it in the same step — there's no separate Approve click needed afterward:
- If the request already has a text channel (the submitter picked one, or advanced mode isn't in use), saving creates the event right away, using a voice channel too if one was requested.
- If no channel is set yet, saving shows the same channel-selection step Approve normally shows — pick a channel there and the event is created from your edited title/description.
If you want to review the edit before it goes live, or need to change something Edit doesn't cover, deny the request instead and ask the submitter to resubmit — editing is meant for quick corrections a moderator is comfortable approving outright, not a staging step.
Editing does not touch the requested start/end time. If the time also needs correcting, edit and approve first, then use the Event URL included in the confirmation to open Discord's own event editor and adjust the schedule there — Discord's editor handles timezones correctly for every viewer, which a text-only edit form cannot.
Denying with a Reason
Clicking ❌ Deny opens a form with an optional reason field. Whatever you enter (or leave blank) is:
- Shown on the moderation-channel embed, so other moderators can see why without asking
- Sent as a direct message to the person who submitted the request, so they're not left wondering what happened
If the bot can't DM the submitter (for example, they have server DMs disabled), the denial still completes — you'll just see a note that the notification couldn't be delivered.
Everyone Sees What Happened
Approving or denying a request updates the original request's message in place (title, color, and buttons change to reflect the outcome) — but a silent edit to an old message is easy to miss if you weren't already looking right at it. On top of that, the bot posts a new message to the moderation channel announcing the outcome:
- Approved: who approved it and a link to the newly created event
- Denied: who denied it, and the reason if one was given
This applies to every way a request gets approved — the Approve buttons, picking a channel after Approve, and saving an edit — so the whole moderation team can see what happened and why without having to notice an old message changed.
This is on by default. To turn it off (only the original request message updates, no separate announcement):
/eggshen-config event-requests announce-decisions enabled:falseModerator Permissions
Only members with Manage Events permission or Administrator/Moderator roles can approve/deny/edit requests.
Rate Limiting
Built-in protection against spam:
- 1 request per 5 minutes per user (by IP address)
- 10 channel lookups per minute per user
- Sessions expire after 24 hours
Security Features
- ✅ Discord OAuth authentication (no passwords stored)
- ✅ Session-based login (24-hour expiration)
- ✅ HTTP-only secure cookies
- ✅ CORS protection
- ✅ Rate limiting
- ✅ Request expiration (7 days)
Customizing for Your Server
Making It Your Own
The event request system is designed to be easily customized:
- Update
GUILD_IDinpublic/app.js- Point to your Discord server - Configure server name and invite - Use
/eggshen-config event-requestscommands - Customize styling - Edit
public/style.cssto match your branding - Deploy to your domain - Host on any web server (Apache, nginx, Netlify, Vercel, etc.)
Multiple Servers (Advanced)
If you host the bot for multiple communities, each should deploy their own instance:
Server 1: Deploy to movienight.com with GUILD_ID = 'SERVER_1_ID'
Server 2: Deploy to gamenight.com with GUILD_ID = 'SERVER_2_ID'
Server 3: Deploy to bookclub.com with GUILD_ID = 'SERVER_3_ID'Each deployment is independent with its own:
- Domain/subdomain
- GUILD_ID configuration
- Custom branding and styling
- Separate Discord OAuth configuration
For Bot Hosts
If you're running the bot for multiple servers and want to offer event requests as a feature, provide each server with:
- Instructions to deploy the web form files
- Their specific GUILD_ID to configure
- Discord OAuth setup guide
Local Testing
Want to test before deploying?
1. Start the Bot
The API server starts automatically:
npm startYou should see: ✓ API server listening on port 3000
2. Serve the Web Form
# Using Python
cd public && python3 -m http.server 8080
# OR using Node.js http-server
npx http-server public -p 80803. Configure for Testing
# .env
OAUTH_REDIRECT_URI=http://localhost:3000/api/auth/discord/callback
FORM_URL=http://localhost:PORT
ALLOWED_ORIGINS=http://localhost:PORTDon't forget to add http://localhost:3000/api/auth/discord/callback to Discord Developer Portal!
4. Test the Flow
- Update
GUILD_IDinpublic/app.jsto your test server's ID - Configure your test server:
# In Discord
/eggshen-config event-requests toggle enabled:true
/eggshen-config event-requests moderation-channel channel:#test-events
/eggshen-config event-requests server-name name:"Test Server"
/eggshen-config event-requests website-url url:http://localhost:PORT
# Check configuration
/eggshen-config event-requests view- Open
http://localhost:PORTin browser and test the full flow!
Troubleshooting
"Site can't be reached" Error
- ✅ Check if the bot is running (API server starts with bot)
- ✅ Verify
API_PORTin.env(default: 3000) - ✅ Check firewall rules if deployed to production
- ✅ Ensure the bot process is running with
pm2 statusor similar
"Guild not found" Error
- ✅ Verify the guild ID in the URL is correct
- ✅ Ensure the bot is a member of that server
- ✅ Check event requests are enabled:
/eggshen-config event-requests view
"Invalid OAuth2 redirect_uri" Error
Common Issue
This is the most common error when setting up event requests. It means Discord doesn't recognize your callback URL.
Solution:
- Go to Discord Developer Portal
- Select your application → OAuth2 → Redirects
- Add the exact URL from your
OAUTH_REDIRECT_URIenvironment variable - Click Save Changes (required!)
- Wait 1-2 minutes for changes to propagate
- Try logging in again
Common mistakes:
- ❌ Forgetting to click "Save Changes" in Discord portal
- ❌ Using HTTP instead of HTTPS in production
- ❌ Typo in the URL (even
/callbackvs/callbacksmatters) - ❌ Port number mismatch
Validate your configuration:
npm run validate-oauthOAuth Redirect Mismatch
- ✅
OAUTH_REDIRECT_URIin.envmust exactly match Discord Developer Portal - ✅ Check for HTTP vs HTTPS mismatches
- ✅ Verify port numbers match
- ✅ Restart the bot after changing
.env - ✅ Run
npm run validate-oauthto check configuration
Requests Not Appearing
- ✅ Check moderation channel is set:
/eggshen-config event-requests view - ✅ Verify bot has permissions to send messages in that channel
- ✅ Check bot logs for errors
CORS Errors
- ✅ Add your website URL to
ALLOWED_ORIGINSin.env - ✅ Restart the bot after changing environment variables
- ✅ Check browser console for specific CORS errors
Login Not Working
- ✅ Verify
DISCORD_CLIENT_SECRETis set correctly in.env - ✅ Check redirect URI matches in Discord Developer Portal
- ✅ Clear browser cookies and try again
- ✅ Check bot logs for OAuth errors
API Endpoints
The bot exposes these endpoints for the event request system:
| Endpoint | Method | Description |
|---|---|---|
/api/health | GET | Health check |
/api/guild-config/:guildId | GET | Get server configuration |
/api/auth/discord | GET | Start OAuth flow |
/api/auth/discord/callback | GET | OAuth callback handler |
/api/auth/session | GET | Check current session |
/api/auth/logout | POST | Logout user |
/api/channels/:guildId | GET | List voice/stage channels |
/api/event-request | POST | Submit event request |
Best Practices
For Server Admins
- 📝 Test locally first before going live
- 🔒 Keep your client secret secure - never share it
- 📢 Share the link in an announcement channel
- 👀 Monitor the moderation queue regularly
- ⚙️ Set clear guidelines for acceptable events
For Web Hosting
- 🔐 Use HTTPS in production for security
- 🌐 Use a memorable domain that matches your community brand
- 📊 Monitor traffic and adjust rate limits if needed
- 💾 Back up your configuration regularly
- 🎨 Customize the styling to match your server's theme
Example Use Cases
Movie Watch Party Server
Server Name: "Friday Horror Nights"
Invite URL: https://discord.gg/horrorlovers
Website: https://horrornights.com
GUILD_ID: '1234567890123456789'Users submit horror movie requests for Friday watch parties.
Gaming Community
Server Name: "Speedrun Central"
Invite URL: https://discord.gg/speedruns
Website: https://speedrungaming.com
GUILD_ID: '9876543210987654321'Coordinate speedrun events and tournaments. Website: https://speedruncalendar.com
Users can request streaming/racing events in the server.
### Anime ClubServer Name: "Anime Watch Party" Invite URL: https://discord.gg/animewp Website: https://animewatchparty.com
Members submit anime screening requests for weekly viewings.
## Support
Need help setting this up? Check:
- [Technical Setup Guide](https://github.com/r3volution11/Egg-Shen-Bot/blob/main/EVENT_REQUEST_SETUP.md)
- [Bot Installation](./installation.md)
- [Configuration Guide](./configuration.md)
- [GitHub Issues](https://github.com/r3volution11/Egg-Shen-Bot/issues)
::: info Note
The Event Request System is an optional feature. Your bot works perfectly without it! This is for communities that want to formalize their event submission process.
:::