Files
MineGeo/docs/discord-integration.md
pavel444-byte 1f254b29a2
All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 5m57s
Update MineGeo domain and harden process supervision
2026-10-15 20:35:39 +05:00

8.3 KiB

Discord announcements

MineGeo uses your Discord bot to send messages through Discord's REST API. It runs on Vercel and does not need a continuously running bot process, Gateway, Message Content intent, slash commands, an interactions URL, or a Discord webhook. The bot can appear offline while announcements work.

New maps are announced when a Moderator or Admin approves their first public version. Drafts, imported ZIP copies, player contributions, subsequent map updates, and re-publication do not create new-map announcements. Existing maps from before this integration are not backfilled.

In an open multiplayer lobby, the host can select Publish party to Discord. Hosting requires a signed-in account and always uses its stored Display Name. Signed-in players join with account names; guests can join with nicknames. If the host leaves, another signed-in player takes over; the party closes if only guests remain. All published parties go to the single server-wide DISCORD_PARTIES_CHANNEL_ID. Players cannot choose a destination. Discord readers can open the invite and join without a MineGeo account while the lobby is open and has space. Messages show the map, host, difficulty, player count, and link. Publishing is optional: ordinary private invite links still work. Parties on private or imported maps cannot be announced publicly. A room gets one announcement, including repeated clicks or a transfer of lobby ownership. The counts are a snapshot when posted.

Create and invite your bot

  1. Open the Discord Developer Portal and select New Application. Name it MineGeo, or your preferred bot name.
  2. Open Bot. Create the bot if prompted, then use Reset Token to obtain its bot token. Keep it private; save it directly into Vercel as described below.
  3. Under Installation, enable Guild Install. For the guild's install settings, choose the bot scope and these permissions: View Channels, Send Messages, Embed Links. You do not need Administrator permission. Use the installation link to add the bot to your Discord server. Alternatively, OAuth2 → URL Generator with the bot scope generates an invite link.
  4. Create or choose a text channel for map announcements and another for parties. You can use the same channel for both. Ensure the bot has the three permissions above in each channel, including any category or channel permission overrides. Ensure community members can view the party channel.
  5. In Discord's User Settings → Advanced, enable Developer Mode. Right-click each channel and choose Copy Channel ID. On mobile, long-press the channel or open its channel menu, then choose Copy Channel ID. Copy the numeric channel IDs; an invite link or server ID is not a channel ID.

Discord setup references: application setup, bot permissions.

Add the Vercel environment variables

Open MineGeo's environment settings. Add these for Production:

Name Value Sensitive?
DISCORD_BOT_TOKEN Bot token from the Developer Portal, without Bot in front Yes
DISCORD_MAPS_CHANNEL_ID Numeric channel ID for new approved maps No
DISCORD_PARTIES_CHANNEL_ID Numeric channel ID where all published parties appear No
MINEGEO_URL https://minegeo.site (already configured) No

Use Sensitive for the token, and never prefix these names with NEXT_PUBLIC_. Leave a channel variable blank to disable that announcement type. A Discord invite such as MINEGEO_DISCORD_URL controls the footer button only; it cannot send announcements.

After saving, open Deployments, choose the newest Production deployment, select Redeploy, and use the current environment variables. Vercel applies environment changes to new deployments. See Vercel's environment-variable guide.

For local use, put the same variables in ignored .env.local (ordinary .env also works) and restart the server. Use a publicly reachable HTTPS MINEGEO_URL for links that Discord members can open. Do not paste bot tokens into chat, source control, Linear issues, or public map metadata.

Check it

Sign in as PerfectPython500, open Moderation → Discord integration, and select Check Discord setup. This reads the bot and channels without sending a test message. It confirms the bot token, channel visibility, and channel type; the bot must also have Send Messages and Embed Links.

Approve a genuinely new map to test a map announcement. Create a multiplayer room on a published map, choose Publish party to Discord, and open the resulting link from Discord. The lobby shows queued, sent, expired, or failed delivery.

Saved delivery and retries

Announcements are stored in a private Supabase queue. Delivery runs after map approval or party publication, leaving gameplay and approval independent of Discord availability. Active workers hold leases, repeated clicks share one event, and Discord receives a stable nonce with enforce_nonce. Rate limits and temporary errors retry with a delay, up to eight attempts. Invalid tokens and missing channel permissions require fixing the settings and selecting Retry saved announcements as an Admin. Delivery resumes while the host polls their lobby or an Admin opens the integration panel; other announcements also wake pending jobs.

Started, closed, full, removed, private, or stale parties are skipped. Pending party announcements expire one hour after sharing; lobbies themselves last up to 24 hours. A map removed before delivery is skipped. Messages already posted are kept when the match starts; the linked lobby shows its live state. When a party closes (including its last player leaving), its posted announcement turns red, says Party closed, and removes the join prompt. Five minutes after Discord acknowledges that notice, the bot deletes the message. Vercel Workflow stores the timer and resumes deletion even if every player closes the page. Retries preserve the original deadline and tolerate messages already removed by a moderator. Previously posted announcements for closed or deleted rooms receive the same cleanup when the queue next runs. The original message's channel is used even if DISCORD_PARTIES_CHANNEL_ID has since changed. Cleanup failures appear in the Admin integration panel and can be retried after fixing bot access. Discord only deduplicates nonces for a few minutes. A long outage after an unconfirmed send can therefore result in a duplicate; inspect the channel before manually retrying uncertain deliveries.

For optional scheduled retries, configure a private CRON_SECRET and call GET /api/integrations/discord/dispatch with Authorization: Bearer <CRON_SECRET>. This endpoint claims at most five due announcements. A Vercel Cron entry can use that path; scheduling limits depend on your plan. No schedule is installed by default, and the secret must never be placed in a URL.

Database and verification

Apply 20261009133431_discord_announcements.sql and 20261009153708_discord_party_cleanup.sql after existing migrations. The queue and functions are service-role-only, use RLS and invoker permissions, and verify the host from the room's server-verified access hash. No Discord credentials are stored in Supabase or sent to a browser.

Vercel Workflow uses the project's managed backend automatically. Keep Settings → Environment Variables → Enable access to System Environment Variables enabled and redeploy after changing it. No additional secret or scheduled cron is needed for the five-minute timer. The bot edits and deletes its own announcements, so Manage Messages is not required.

Run npm test, npm run typecheck -- --incremental false, npm run build, and node scripts/test-discord-sql.mjs. node scripts/test-discord-http.mjs verifies the live role gates, destination restrictions, optional configuration, and host-only room action with temporary accounts and a room, which it removes. Discord transport tests use a mocked API; real delivery requires your bot token and channel permissions.