Files
electric-cherry/docs/guides/discord.md
T
2026-10-18 16:55:49 -04:00

157 lines
9.2 KiB
Markdown

# Discord companion
Electric Cherry can publish live Black Ops I and Black Ops II server boards in
Discord, answer commands privately, and send requested map availability alerts by
DM. Configure it under **Admin → Discord**. Administrators can make changes;
Super Viewers can inspect configuration, the saved preview, and delivery health.
The integration is disabled by default and publishes no servers until selected.
## Install the application
1. Create an application in the [Discord Developer Portal](https://discord.com/developers/applications).
Copy its Application ID and Public Key, and create a bot token.
2. Set the controller environment variables below. Keep the token private; the
settings page reports whether it is configured without displaying its value.
With Docker Compose, put the values in the deployment's `.env` file and recreate
the controller to apply them. Do not commit that file.
```dotenv
EC_DISCORD_APPLICATION_ID=
EC_DISCORD_PUBLIC_KEY=
EC_DISCORD_BOT_TOKEN=
```
3. Install the application into your Discord server using the `bot` and
`applications.commands` scopes. Grant **View Channel**, **Send Messages**, and
**Read Message History** in each board channel. No Administrator permission or
privileged Gateway intents are needed. Channel overrides must also permit the
bot to read and write those channels.
4. In the Developer Portal, set **Interactions Endpoint URL** to
`https://your-controller.example/api/discord/interactions`. Use your actual
public controller origin with a trusted HTTPS certificate. Discord verifies
the endpoint before accepting it. The controller checks Discord's request
signatures; this endpoint does not use the Electric Cherry login session.
5. In Discord, enable Developer Mode, then copy the Discord server ID and the
board channel IDs. Open **Admin → Discord**, enter those IDs, and select the
game servers to publish. Either game may omit its board channel.
6. Review the information-sharing switches, enable the companion, and save.
Select **Register commands** to install the commands in the saved Discord
server. Saving configuration and registering commands are separate actions.
The deployment's reverse proxy must route the interaction endpoint to the
controller and preserve Discord's signature headers and request body. No Gateway
connection is required. Installation scopes and channel permissions follow
Discord's [OAuth2 documentation](https://docs.discord.com/developers/topics/oauth2)
and [permissions reference](https://docs.discord.com/developers/topics/permissions).
See [HTTP interactions](https://docs.discord.com/developers/interactions/receiving-and-responding)
for Discord's endpoint verification and response requirements.
Use a dedicated Discord application for this controller. The command registration
action updates that application's command set in the configured Discord server.
## Choose what is published
The published-server selection is an explicit allowlist. Newly created game
servers stay private until an administrator selects them. The selection controls
boards, private server browsing, server details, and availability watches.
Player names in server details and public connection addresses are separate,
disabled-by-default options. Connection instructions use an explicitly configured
native host public endpoint; internal host addresses and RCON credentials are not
published. Capacity, player counts, map, round, and observation state can appear
without either switch enabled.
**Publish fleet leaderboards** is a separate decision. It exposes recorded player
names and statistics from the whole fleet, including historical matches on
servers outside the published-server selection. Leave it disabled if those
statistics should remain available only to Electric Cherry users.
The settings page's preview uses the **saved settings**. Pending form edits do
not change the preview or Discord. The preview remains available while the
integration is disabled.
## Boards and browsing
Each configured game channel receives a persistent server board, split into
additional messages when needed. The controller revisits delivery about every
30 seconds and edits changed content. Stored message IDs survive controller
restarts. Periodic existence checks recreate messages that were removed.
Boards show observed occupancy, capacity and current round where available,
with separate empty, in-progress, full, starting, offline, not-responding, and
unknown states. Freshness is part of the observation. **Empty slots do not prove
that a match accepts new players**; this release does not label games joinable.
Members can use the board controls or slash commands. Browsing, filters, details,
leaderboards, and command confirmations are visible only to the member who
requested them. They do not rearrange the shared board.
| Command | Purpose |
| ------------------------------- | ------------------------------------------------------------------------------------------ |
| `/servers` | Browse published servers; filter by game, map and state, and page through results. |
| `/server name` | Inspect one published server, including optional roster names and connection instructions. |
| `/leaderboard` | Browse recorded fleet rankings by game, map, metric, squad size and page, when enabled. |
| `/watch add game map condition` | Request a one-shot DM when a map has an empty lobby or observed space. |
| `/watch list` | See your active watches and their IDs. |
| `/watch cancel id` | Cancel one of your own watches. |
| `/help` | Explain the commands and their limits. |
Commands are limited to the configured Discord server. Map options preserve the
game's map variants. Leaderboard results reflect recorded gameplay, not a new
claim that a match was won or that a player survived continuously.
## Availability alerts
A watch lasts up to 24 hours and sends one DM when its condition is satisfied.
Each member may have up to ten active watches. Requesting the same map and
condition again reuses the existing watch. Members can cancel only their own
watches.
An **empty** watch needs an observed empty lobby. A **space** watch needs a known
capacity and fewer players than that capacity. Neither condition promises that
joining is allowed. Unknown, stale, and offline observations never satisfy a
watch. The worker requires two qualifying observations at least 15 seconds apart
before queueing a notification.
Watches and pending notifications persist across controller restarts. Delivery
handles transient failures and Discord rate limits. A permanent DM failure, such
as a member blocking messages from the bot, ends that watch. Members should allow
DMs from the bot before creating a watch and can inspect active watches with
`/watch list`.
## Delivery and troubleshooting
The settings page shows the last attempt, last success, current error, active
watches, pending notifications, and links to recorded board channels. Refreshing
that page preserves pending edits. A failure keeps the last loaded information
visible.
- **Credentials need attention:** check all three environment variables and
restart the controller after changing them. A readiness indicator checks local
configuration; it does not establish that Discord has accepted the token.
- **Discord rejects the interaction endpoint:** verify HTTPS routing, the
application's Public Key, and that the reverse proxy preserves signed
requests. Discord must reach the endpoint without an interactive login.
- **Commands are missing:** save the correct Discord server ID, install the bot
with `applications.commands`, then select **Register commands**. Register again
after upgrading to a release that changes the command schema.
- **Board delivery is denied:** check the bot's permissions and channel overrides.
Authorization failures pause retries. After correcting access, select **Save
and retry** in Electric Cherry.
- **A board was deleted:** the controller's periodic check recreates it. Keep
Read Message History enabled so those checks can verify existing messages.
- **Discord rate limits or temporary outages:** delivery honors retry delays and
retries transient failures with increasing delays. Fleet operations continue
independently.
- **Old board messages remain after a channel change or disable:** the controller
attempts to remove old messages. If permissions were removed first, an
administrator may need to delete those messages in Discord.
Disabling the companion stops new publication and notifications. Cleanup may
still remove previously recorded board messages. Data already seen or copied by
members cannot be recalled by changing publication settings.
This release does not link Discord accounts to game identities, expose personal
bank or AFK accounts, mutate servers or moderation state, or announce
achievements. Those workflows require separate authorization and implementation.