157 lines
9.2 KiB
Markdown
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.
|