Overview
Manage licenses from Discord, let buyers claim licenses and get roles, run key drops, alert staff and show live stats in the bot's status.
The Discord module runs a bot in your server. Your team manages licenses, products, and customers with
slash commands, customers see their own licenses with /mylicenses, every license check can be posted to
a channel, and the bot's status can rotate through live numbers like Listening to 1,204 requests.
This module depends on core. The bot only starts once a token is saved.
See Configuration.
Every reply is an embed, and every reply is private to the person who ran the command.
Setting up the bot
- Create an application in the Discord Developer Portal, add a Bot, and copy its token.
- Invite it to your server with the
botandapplications.commandsscopes. Give it Send Messages and Embed Links in your log channel. - On the dashboard Configs page, open Discord, paste the token into Bot, and set the Server ID. Saving starts the bot and registers the commands in that server.
The bot runs in exactly one server, the one set as Server ID. It does not start without one, it leaves any other server it is added to, and it clears any globally registered commands so they never show up twice.
No privileged gateway intents are needed.
Staff commands
/licenses, /products, and /customers check the dashboard permissions of the person running them.
They must be a dashboard member (or the owner), matched by Discord ID, with the permission for that
action: licenses.create for /licenses create, products.delete for /products delete, and so on.
Members are managed under Team.
| Command | What it does |
|---|---|
/licenses create product customer [status] [expires] [key] | Issue a license. The key is generated when empty. |
/licenses edit license [product] [customer] [status] [expires] | Change a license. |
/licenses delete license | Delete a license. |
/licenses view license | Show a license. |
/products create name [version] [description] [price] [currency] [duration] [unit] [active] | Create a product. |
/products edit product [name] [version] [description] [price] [currency] [duration] [unit] [active] | Change a product. |
/products delete product [force] | Delete a product. force also deletes its licenses. |
/products view product | Show a product and its license count. |
/customers create name [email] [user] | Create a customer, optionally linked to a Discord account. |
/customers edit customer [name] [email] [user] | Change a customer. |
/customers delete customer [force] | Delete a customer. force also deletes their licenses. |
/customers view customer | Show a customer and their license count. |
/whitelist group create name type [key] [limit] | Create a whitelist group (type: IP, HEADER, BODY). |
/whitelist group delete group | Delete a whitelist group. |
/whitelist group list | List all whitelist groups. |
/whitelist product attach product group | Attach a whitelist group to a product. |
/whitelist product detach product group | Detach a whitelist group from a product. |
/whitelist add license group value | Add a whitelist entry to a license. |
/whitelist remove license group value | Remove a whitelist entry from a license. |
/whitelist reset license group | Reset all entries for a group on a license. |
/whitelist view license | Show whitelist entries on a license. |
Licenses, products, customers, whitelist groups, statuses, and currencies autocomplete as you type. expires takes a date
such as 2026-12-31, or pick Product default or Never from the suggestions. Every change is
written to the audit log.
/kora holds the other staff tools. Each subcommand has its own permission so you can hand them to support roles: discord.panel, discord.drop and discord.stats.
| Command | What it does |
|---|---|
/kora panel | Post the claim panel in the current channel, with Claim a license and My licenses buttons. |
/kora drop product count [title] | Start a key drop. Each member presses Claim a key, enters their email and gets a fresh license privately. One per member, and the progress bar updates as keys go. |
/kora stats [range] | Checks, valid and rejected answers with the top rejection codes, licenses in use and licenses issued over 24 hours, 7 days or 30 days, with sparklines. |
Staff alert cards carry a Suspend button that gives the license your suspended status, or the first negative status, with the licenses.edit permission.
Member commands
| Command | What it does |
|---|---|
/claim | A form asking for the license key and the purchase email. Both must match, so a leaked key alone cannot be claimed. The Discord account is linked to the license's customer. A customer already linked to that account is merged in. |
/mylicenses [license] | List your licenses with their status, version, addons, and expiry, or show one in detail. Only your own keys autocomplete. A license with seats in use has a Reset seats button. |
/addwhitelist license group value | Add an entry to a whitelist group on your owned license. |
The list shows up to 10 licenses. Pick any of your licenses (up to 25) from the menu under it to open it in detail, and press Back to return.
A member is matched to a customer by the customer's Discord ID.
Buyer roles
Under Configs > Discord > Buyers, pick a Role for every buyer, a role for each product, or both. Members get the roles while they own a valid license and lose them when the license is revoked, suspended, expires or their customer is blocked. Roles follow every license change right away and are checked again every hour. Drag the bot's role above these roles under Server Settings > Roles, and give it Manage Roles.
Seat resets
With Let customers reset their seats on, Reset seats in /mylicenses clears every whitelist entry on that license, so the buyer's product can activate on a new machine. Each license can be reset once per Hours between resets.
Staff alerts
Under Configs > Discord > Staff alerts, pick a channel and the events to post:
| Event | Default |
|---|---|
| License issued | On |
| License status changed | On |
Possible key sharing, when a check fails with leaked or seats_full | On, at most once per license every 15 minutes |
| New device activated | Off |
| Daily digest at 09:00 UTC, the 7 day stats | On |
Alerts show masked keys (AX8P-XXXX-XXXX-XXXX) and masked emails (ja•••@example.com), and have View Details and Suspend buttons that check the pressing member's permissions.
Validation logs
Turn on Post validation logs and pick a channel, and the bot posts an embed for every request to
/api/v1/licenses/validate with the key, product, result code, message, and IP. Choose to post every
result, only valid ones, or only invalid ones. The channel list is read from the bot, so it is empty
until the bot is signed in.
Status
The Status config sets the bot's presence (Online, Idle, Do Not Disturb or Invisible) and a list of activities it rotates through. Each activity has a type (Playing, Listening to, Watching, Competing in, or Custom) and a text with placeholders.
| Placeholder | Value |
|---|---|
%requests_all% | Validation requests logged |
%requests_valid% | Valid validation requests |
%requests_invalid% | Invalid validation requests |
%requests_today% | Validation requests since midnight |
%licenses_all% | Licenses |
%licenses_active% | Licenses in a positive status |
%products_all% | Products |
%customers_all% | Customers |
Request counts come from the core validation logs, so they follow its retention setting. Only the placeholders an activity uses are counted.