Commands¶
MediaWatch has five slash commands, one slash command group, and one prefix command.
Every one of them is restricted to DISCORD_AUTHORIZED_USERS. There are no roles
and no per-command permissions. An unauthorized call is answered, not silently ignored.
/load, /unload, /reload, /reload_config, /cogs and !sync reply:
/mapping replies with a ❌ Not Authorized embed instead: You are not authorized to
manage user mappings. (/mapping list: You are not authorized to view user mappings.)
All slash commands are published into DISCORD_GUILD_ID only. They do not appear in any
other server the bot is in. If none of them show up at all, see
Troubleshooting.
Day-to-day¶
/mapping¶
Maps a media server username to the name shown on the dashboard, without a restart and
without editing data/user_mapping.json by hand. Mappings are stored per platform, so a
deployment that switches between Plex and Jellyfin keeps both sets.
| Subcommand | Parameters | What it does |
|---|---|---|
/mapping add |
platform, username, display_name |
Adds a mapping. Refuses if one already exists for that username and points you at /mapping edit. |
/mapping edit |
platform, username, new_display_name |
Changes the display name of an existing mapping. |
/mapping remove |
platform, username |
Deletes a mapping. |
/mapping list |
platform (optional: plex, jellyfin, all) |
Lists the mappings. Without the parameter it lists the currently active platform. |
username is the exact, case-sensitive name on the media server. For remove and
edit the field autocompletes from the mappings you already have. That autocomplete
runs the same authorization check as the command itself, so it does not leak the list to
anyone else.
Changes take effect on the next dashboard update; no /reload_config needed.
/reload_config¶
Re-reads data/config.yaml and reloads the cogs that are driven by it: the active media
core extension and, if loaded, SABnzbd. Use it after editing library sections, presence
texts, the privacy options or SABnzbd settings.
It also handles a change of media_server.type: the running platform is unloaded and the
newly configured one loaded. If the new one fails to load, the previous one is restored
rather than leaving you with no media cog at all. The reply lists what happened:
✅ Applied config reload.
- reloaded `cogs.media_core.plex`
- reloaded `cogs.sabnzbd`
If this changes slash commands, publish them with `!sync guild`.
If config.yaml is invalid, nothing is reloaded and the reply reads ❌ Config not reloaded,
the running configuration is unchanged. Fix the file and run /reload_config again.,
followed by the parse error.
Not everything is config
Environment variables are read at process start. Changing .env (a token, a URL,
DISCORD_AUTHORIZED_USERS) needs a restart, not /reload_config.
Extension management¶
/cogs, /load, /unload and /reload operate on the bot's extensions. You need them
rarely: to turn an integration off without editing the deployment, or to recover a cog
that failed to load at startup.
| Command | Parameter | What it does |
|---|---|---|
/cogs |
none | Lists every extension with 🟢 loaded / 🔴 not loaded and its description. The media core entry names the active platform, e.g. Media Core (Plex). |
/load |
cog |
Loads an extension that is not running. |
/unload |
cog |
Unloads a running extension. |
/reload |
cog |
Reloads an extension; loads it if it was not running. |
Valid cog values are the file and package names under cogs/: sabnzbd, uptime,
user_mapping, and media_core for the media server itself. media_core resolves to
whichever platform media_server.type selects, so you never type media_core.plex.
media-core and mediacore are accepted as spellings.
Loading or unloading an extension changes which slash commands exist, and Discord does not learn that by itself. The replies say so:
If this changes slash commands, publish them with
!sync guild.
!sync: the prefix command¶
!sync pushes the bot's current command tree to Discord. You need it after /load or
/unload added or removed commands, or when Discord's copy of the command list is out of
step with what the bot has.
Type it as a normal message in a channel the bot can read:
| Scope | Alias | What it does |
|---|---|---|
global |
g |
Publishes the tree globally. Global commands can take up to an hour to propagate, and MediaWatch publishes guild-scoped on every start, so you rarely want this one: with the guild scope already populated, a global sync makes each command appear twice in this server. Undo it with !sync clearglobal. |
guild |
~ |
Clears the guild scope, copies the current tree into it and syncs. This is the default when you write a bare !sync, and the one you want: it takes effect immediately and mirrors exactly what the bot has loaded. |
copy |
* |
Identical to guild in effect; only the confirmation message differs. |
clear |
^ |
Empties the guild scope. Every slash command disappears from this server until you sync again. |
clearglobal |
clear-global, ^^ |
Drops the global registration without touching the guild scope. This is what removes leftover globally registered commands from PlexWatch 1.x, but 2.0 already does it once automatically on first start. |
guild, copy and clear have to be used inside a server; in a DM they answer
❌ `<scope>` sync requires running this command inside a server., for example
❌ `guild` sync requires running this command inside a server.. An unknown scope lists
the valid ones back to you.
!sync is the only reason the bot needs a privileged intent
!sync is a prefix command: to see it, the bot has to read the text of your
message, which requires the Message Content Intent in the Discord developer
portal. Nothing else in MediaWatch reads message content: the dashboard, the buttons
and every slash command work without it, and the Server Members and Presence intents
stay off entirely.
The intent is requested unconditionally, so it is not optional in practice: with the box unticked in the portal, Discord closes the connection and the bot never comes online. See Discord bot setup.