Discord bot Server - nicho92/MtgDesktopCompanion GitHub Wiki
DiscordBotServer is the MTG Companion server plugin that exposes card lookup and price-movement features through a Discord bot. It uses JDA (Java Discord API) to connect to Discord, registers slash commands, answers interactions with Discord embeds, and records query metadata in the technical service manager for monitoring.
Create your discord bot
Where it fits
- Plugin type: server plugin, declared as
org.magic.servers.impl.DiscordBotServerin the default server list. - Runtime name:
Discord. - Primary class:
src/main/java/org/magic/servers/impl/DiscordBotServer.java. - Admin endpoint:
/admin/discordonJSONHttpServer, which combines live Discord connection details with recorded bot queries. - Admin UI: the admin Discord page calls
/admin/discordand renders guild and message tables.
Startup flow
- MTG Companion loads enabled server plugins from the application configuration.
- If the Discord server plugin is enabled and
AUTOSTARTistrue, the server manager can start it automatically. start()builds a JDA client with the Discord bot token stored in the plugin authenticator underTOKEN.- The JDA client installs a listener for:
ReadyEvent, used to log that the bot is connected.SlashCommandInteractionEvent, routed to command handling.CommandAutoCompleteInteractionEvent, routed to autocomplete handling.
- If
ACTIVITY_TYPEandACTIVITYare configured, the bot presence is updated. initCommands()registers the bot slash commands with Discord.- Pagination support is activated through the JDA paginator helper used for multi-card search results.
Registered slash commands
| Command | Required options | Optional options | Purpose |
|---|---|---|---|
/card |
cardname |
setname, price |
Searches cards by name, optionally filters by set, and returns card details. If price is true, the response includes the best available regular and foil prices from enabled price providers. |
/format |
formatname |
none | Shows the largest upward and downward daily price movements for a Magic format. |
/set |
setname |
none | Shows the largest upward and downward daily price movements for a set. |
/help |
none | none | Sends a short usage summary for the supported commands. |
All commands are registered as Discord slash commands in initCommands().
Autocomplete behavior
Discord autocomplete is handled before command execution:
cardnameautocomplete starts only after the typed value reachesAUTOCOMPLETE_STARTcharacters. It searches the enabledMTGCardsProvider, keeps distinct names, and returns up to 25 choices.setnameautocomplete filters set codes/names. When a card name is already provided, it narrows suggestions to editions of that card; otherwise it uses all editions from the enabled card provider.formatnameautocomplete filters values fromMTGFormat.FORMATS.
Discord limits autocomplete replies, so the implementation caps choices at 25.
Command handling details
/card
The /card command:
- Stores a human-readable query string in a
MessageInfoaudit object. - Defers the Discord reply, because card provider and price provider calls can take time.
- Resolves the optional set filter through the enabled
MTGCardsProvider. - Searches matching cards by name.
- Builds one embed per matching card with:
- card name and mana cost,
- color-derived embed color,
- type line,
- oracle text,
- set,
- reserved-list status,
- extra card metadata when present,
- collection names when
SHOW_COLLECTIONSis enabled, - image or thumbnail from the enabled
MTGPictureProvider, - optional prices from all enabled
MTGPricesProviderimplementations, - optional external link built from
EXTERNAL_LINKplus the card Scryfall ID.
- Sends the first embed and enables pagination when multiple cards match.
/format
The /format command asks the enabled dashboard plugin for price shakers in the selected format. It sorts the result twice: once for the biggest upward daily percentage changes and once for the biggest downward daily percentage changes. Each side is limited by CARD_SHAKE_LIMIT, and the combined result is returned in an embed.
/set
The /set command resolves the selected set through the enabled card provider, then asks the enabled dashboard plugin for that edition's price shakers. It uses the same upward/downward daily movement display and CARD_SHAKE_LIMIT behavior as /format.
/help
The /help command sends a plain text explanation of /card, /format, and /set.
Configuration
DiscordBotServer defines these plugin properties:
See Discord plugin documentation
Monitoring and admin data
Every slash command creates a MessageInfo audit record with the Discord user, channel, guild, query text, timing, and any accumulated price-provider errors. The record is stored through AbstractTechnicalServiceManager after command handling.
The JSON admin server exposes /admin/discord, returning:
server: live bot details fromDiscordBotServer.toJsonDetails(), including guilds, bot user, and presence data when connected.queries: recorded DiscordMessageInfoentries from the technical service manager.
The admin UI's Discord page consumes that endpoint to display bot status, guild information, and message/query history.
Dependencies on other MTG Companion plugins
DiscordBotServer is an integration layer. It delegates most MTG-specific work to enabled plugins:
MTGCardsProviderfor card search, set lookup, and edition listing.MTGPictureProviderfor card image URLs.MTGPricesProviderimplementations for optional price fields on/card.MTGDaofor optional collection lookup whenSHOW_COLLECTIONSis enabled.MTGDashBoardfor card-shaker data used by/formatand/set.
Because of those dependencies, command quality depends on the configured providers and whether they are enabled, reachable, and indexed.
Stopping and health
stop()shuts down the JDA client, sets the Discord presence offline, and logs the stop.isAlive()returnstrueonly when the JDA status isCONNECTED.getVersion()reports the JDA library version used by the plugin.
Troubleshooting checklist
- Verify the Discord server plugin is enabled in the server configuration.
- Add a valid Discord bot token to the plugin authenticator under
TOKEN. - Ensure the bot has been invited to the target Discord guild with permissions to use slash commands and send embeds.
- Check that card, picture, dashboard, DAO, and price providers are enabled as needed for the commands you want to use.
- Use the admin Discord page or
/admin/discordendpoint to confirm connection status, guild visibility, and recorded query errors. - If autocomplete seems inactive, check
AUTOCOMPLETE_STARTand remember that Discord will not request card-name suggestions until the configured character threshold is reached.