Skip to content

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

  1. User visits your event request form at your configured website
  2. User logs in with Discord (OAuth authentication)
  3. 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
  4. 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.
  5. System revalidates membership at submission (prevents edge case of leaving server after login)
  6. Request appears in your moderation channel with Approve/Deny buttons
  7. Moderator clicks a button to approve or deny
  8. 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.

  1. Go to Discord Developer Portal
  2. Select your bot application
  3. Navigate to OAuth2 section
  4. 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_URI environment variable exactly
  5. Click Save Changes (don't forget this!)
  6. Copy your Client Secret from the OAuth2 page (keep it secure!)

Step 2: Environment Variables

Add these to your .env file:

env
# 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.com

Local Testing

For local testing, use:

env
OAUTH_REDIRECT_URI=http://localhost:3000/api/auth/discord/callback
FORM_URL=http://localhost:PORT
ALLOWED_ORIGINS=http://localhost:PORT

Step 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 form
  • public/app.js - Form logic
  • public/style.css - Styling

Required Configuration:

  1. Open public/app.js
  2. Find the GUILD_ID constant (around line 11)
  3. Replace the placeholder with your Discord server's Guild ID:
javascript
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_ID in public/app.js
  • Upload /public contents to https://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:true

2. 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.com

3. Optional settings:

/eggshen-config event-requests invite-url url:https://discord.gg/yourserver
/eggshen-config event-requests get-link

This 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 view

Shows your current configuration including the event request link.

Enable/Disable

/eggshen-config event-requests toggle enabled:true
/eggshen-config event-requests toggle enabled:false

Turn 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-requests

Choose 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.com

The website where your event request form is hosted.

/eggshen-config event-requests invite-url url:https://discord.gg/yourserver

Discord 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:false

Control 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-link

Shows 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:false

Users 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:true

Users 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:

  1. Enable Developer Mode in Discord Settings → Advanced
  2. Right-click any channel → Copy Channel ID
  3. 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

  1. Visit the link provided by server admins
  2. Click "Login with Discord" to authenticate
  3. 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)
  4. Click "Submit Request"
  5. 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:

  1. Request appears in moderation channel with all details
  2. Shows location (text channel) and voice channel (if requested)
  3. Approval buttons vary based on request:
    • Text-only request: ✅ Approve, ✏️ Edit, or ❌ Deny
    • Request with voice: ✅ Approve Both, 💬 Text Only, ✏️ Edit, or ❌ Deny
  4. 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:false

Moderator 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:

  1. Update GUILD_ID in public/app.js - Point to your Discord server
  2. Configure server name and invite - Use /eggshen-config event-requests commands
  3. Customize styling - Edit public/style.css to match your branding
  4. 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:

  1. Instructions to deploy the web form files
  2. Their specific GUILD_ID to configure
  3. Discord OAuth setup guide

Local Testing

Want to test before deploying?

1. Start the Bot

The API server starts automatically:

bash
npm start

You should see: ✓ API server listening on port 3000

2. Serve the Web Form

bash
# Using Python
cd public && python3 -m http.server 8080

# OR using Node.js http-server
npx http-server public -p 8080

3. Configure for Testing

env
# .env
OAUTH_REDIRECT_URI=http://localhost:3000/api/auth/discord/callback
FORM_URL=http://localhost:PORT
ALLOWED_ORIGINS=http://localhost:PORT

Don't forget to add http://localhost:3000/api/auth/discord/callback to Discord Developer Portal!

4. Test the Flow

  1. Update GUILD_ID in public/app.js to your test server's ID
  2. 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
  1. Open http://localhost:PORT in 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_PORT in .env (default: 3000)
  • ✅ Check firewall rules if deployed to production
  • ✅ Ensure the bot process is running with pm2 status or 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:

  1. Go to Discord Developer Portal
  2. Select your application → OAuth2 → Redirects
  3. Add the exact URL from your OAUTH_REDIRECT_URI environment variable
  4. Click Save Changes (required!)
  5. Wait 1-2 minutes for changes to propagate
  6. 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 /callback vs /callbacks matters)
  • ❌ Port number mismatch

Validate your configuration:

bash
npm run validate-oauth

OAuth Redirect Mismatch

  • OAUTH_REDIRECT_URI in .env must 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-oauth to 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_ORIGINS in .env
  • ✅ Restart the bot after changing environment variables
  • ✅ Check browser console for specific CORS errors

Login Not Working

  • ✅ Verify DISCORD_CLIENT_SECRET is 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:

EndpointMethodDescription
/api/healthGETHealth check
/api/guild-config/:guildIdGETGet server configuration
/api/auth/discordGETStart OAuth flow
/api/auth/discord/callbackGETOAuth callback handler
/api/auth/sessionGETCheck current session
/api/auth/logoutPOSTLogout user
/api/channels/:guildIdGETList voice/stage channels
/api/event-requestPOSTSubmit 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 Club

Server 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.
:::

Egg Shen — A Discord bot for movie, TV, video and board gaming, and book communities.