Tickets
People ask for help, staff pick it up, and a transcript is kept.
Module: tickets — off until a bot owner runs /moduleadmin enable module: Tickets. See Modules.
Setting up a full ticket system, start to finish
This is everything, in order. Skipping a step just means the next one tells you what's missing.
1. Turn the module on
Bot owner only:
/moduleadmin enable module: Tickets guild_id: <your server ID>
2. Pick the category tickets open into
Ticket channels are created inside a Discord category. Make one (e.g. Tickets), then point the bot at it:
/config set key: ticket_category value: #your-category
Without this, opening a ticket fails with "Ticket category not configured."
3. Set the log channel
Every open, close, claim, and transcript gets posted here:
/ticketadmin logs channel: #ticket-logs
4. Decide your ticket types
Out of the box, before you configure anything, four built-in types exist: Support, Appeal, Application, Miscellaneous. If that's enough, skip to step 6. Otherwise, create your own — the moment you create even one custom type, the built-ins stop being offered and only your types are used.
/ticketadmin type create
Opens a form: type key (lowercase, no spaces — e.g. report), display label,
short description (shown in the dropdown), an emoji, and an intro message
shown when the ticket opens.
Manage types with:
| Command | What it does |
|---|---|
/ticketadmin type create | New type (opens a form) |
/ticketadmin type edit <type_key> | Edit an existing type (same form, pre-filled) |
/ticketadmin type delete <type_key> | Delete a type |
/ticketadmin type toggle <type_key> <enabled> | Hide a type from panels without deleting it |
/ticketadmin type reorder <type_key> <position> | Change dropdown order (1 = first) |
/ticketadmin type list | See every configured type |
/ticketadmin type setcategory <type_key> <category> | Send this one type's tickets to a different category than the server default |
/ticketadmin type clearcategory <type_key> | Undo that override |
5. Add a form, if you want one (optional)
Up to 5 fields per type. When a type has fields, opening that ticket pops a form instead of creating the channel immediately, and the answers get posted into the ticket.
/ticketadmin form add type_key: report
Opens a form for the form field itself: label, placeholder text, style
(short or paragraph), whether it's required, and max length (up to 1000).
| Command | What it does |
|---|---|
/ticketadmin form add <type_key> | Add a field (max 5) |
/ticketadmin form list <type_key> | See the fields, in order |
/ticketadmin form remove <type_key> <field_number> | Remove by number, from form list |
6. Assign who handles each type (optional but recommended)
Without this, tickets fall back to your server's global staff_role /
admin_role (set with /config set). To be specific per type:
/ticketadmin staffrole set type_key: report role: @Moderators level: handler
Three levels:
| Level | Can do |
|---|---|
| Viewer | Read only. No sending, no reactions. |
| Handler | Read and send. |
| Senior | Read, send, and manage (this is what the claimer gets automatically). |
| Command | What it does |
|---|---|
/ticketadmin staffrole set <type_key> <role> <level> | Assign a role |
/ticketadmin staffrole remove <type_key> <role> | Unassign |
/ticketadmin staffrole list <type_key> | See assignments for one type |
7. Post the panel
The panel is the dropdown people actually click to open a ticket.
/ticket panel post
Opens a form: title, description (markdown works — bold, bullets), which ticket types to include (comma-separated keys, blank = all enabled), accent colour (hex, blank = blue), and an optional image URL. Posts immediately in whatever channel you ran the command in.
Use save instead of post if this is a panel you'll want to bring back
later:
/ticket panel save name: general
Same form, but it also remembers the panel under that name. If the panel message ever gets deleted — someone fat-fingers it, the channel gets purged — you don't rebuild it from scratch:
/ticket panel load name: general
| Command | What it does |
|---|---|
/ticket panel post | Post a panel, don't save it |
/ticket panel save <name> | Post a panel and remember it |
/ticket panel load <name> | Repost a saved panel |
/ticket panel list | See saved presets |
/ticket panel delete <name> | Forget a saved preset |
That's a full system: module on, category set, log channel set, types defined, forms attached where you want them, roles assigned, panel live.
Optional: unclaim appeals
If a claimer goes quiet and someone else wants to take the ticket over, other staff can vote to force an unclaim. This needs its own channel:
/config set key: ticket_vote_channel value: #staff-votes
Optionally set who's allowed to vote (falls back to your admin role if unset):
/config set key: ticket_inner_circle_role value: @Inner Circle
The button that starts a vote (⚠️ Appeal) only appears on claimed tickets, to anyone with staff perms other than the current claimer.
Using it, day to day
Opening a ticket
Members click the dropdown on the panel. If the type has a form, it pops up first; otherwise the ticket opens immediately.
Staff can open one on someone's behalf:
/ticket open member: @someone ticket_type: report
Claiming
The 🤝 Claim button on the ticket's control message. Whoever claims gets full control (send, manage messages, manage the channel). Claiming is what tells everyone else it's being handled — there's no other signal.
Only one claimer at a time. 🔓 Unclaim on the control message gives it up (only the claimer can do this themself; anyone else has to go through the appeal vote above).
Working the ticket
| Command | Who | What it does |
|---|---|---|
/ticket add <member> | Staff | Bring someone in (handler perms) |
/ticket remove <member> | Staff | Take someone out |
/ticket coclaim <member> <add|remove> | Claimer only | A second handler, max 2 |
/ticket note <content> [attachment] | Staff | A note saved in the transcript and posted to the private staff thread |
/ticket rename <name> | Claimer (or staff, if unclaimed) | Rename the channel |
/ticket perms <target> <level> | Claimer (or admin) | Set a specific user or role to viewer / handler / co-claimer / none |
/ticket transcript | Anyone in the ticket | Generate the HTML transcript right now, without closing |
/ticket list [status] | Staff | Every ticket in the server — open, closed, or all |
Every ticket also gets a private staff thread, invisible to the ticket
opener, for coordinating without cluttering the ticket itself. Staff in the
handling role(s) are added automatically. /ticket note posts there too.
Closing
🔒 Close on the control message. This:
- Revokes the opener's access to the channel (they can no longer see it)
- Posts a transcript to the log channel automatically
- DMs the opener a star rating request (1–5 stars, plus an optional comment, or they can skip it)
- Leaves 🔓 Reopen, 📄 Transcript, and 🗑️ Delete buttons behind
If the opener never responds to the rating DM within 48 hours, that's logged too, as "no feedback" rather than silently dropped.
It's not working
When you are stuck
"Ticket category not configured."
Run /config set key: ticket_category value: #your-category. See step 2 above.
The panel button does nothing
The panel is older than the last time ticket types changed — its dropdown
still references types that no longer exist. Repost it with /ticket panel load
if it was saved, or /ticket panel post for a fresh one.
"You can't claim this."
You're not in the handler/senior role for that ticket type (/ticketadmin staffrole list),
and you don't hold the server's global staff or admin role either.
The ticket channel didn't open
Usually the bot can't create channels in the configured category — check its permissions there. Second most common: you already have an open ticket of that same type; the bot won't open a second one.
The transcript is empty
Transcripts capture messages the bot could see in that channel. If it was
added to the channel late (e.g. via /ticket add), it only has messages from
that point on.
"No vote channel configured."
The unclaim appeal needs ticket_vote_channel set — see the optional section
above. Without it, there is no way to force an unclaim; the claimer has to do
it themselves.