Configuration
๐ ๏ธ Configuration Referenceโ
Startup Log Visibilityโ
"showLog": true // Show INFO log messages on startup (commands, events, components)
// Set to false for a cleaner output in production
Panel Interaction Typeโ
"panel": {
"interactionType": "BUTTON" // "BUTTON" (default) or "SELECT_MENU"
}
| Mode | Behaviour |
|---|---|
"BUTTON" | A green button is shown. Clicking it opens an ephemeral select menu โ always fresh, no Discord caching issue. |
"SELECT_MENU" | The select menu is shown directly in the panel. After every use it automatically resets, so users never need to restart Discord to open a second ticket of the same type. |
Panel Logo & Bannerโ
"panel": {
"logo": { "enabled": true, "file": "logo.png" },
"banner": { "enabled": true, "file": "banner.png" }
}
Supported formats: PNG, JPG, GIF, WEBP. Run /setup again after adding or changing images.
Channel State Overviewโ
| State | Channel Name | Channel Topic | Opening Embed |
|---|---|---|---|
| Ticket opened | ticket-username | ๐ก Medium | Priority: ๐ก Medium |
/priority urgent | ticket-username | ๐ด Urgent | Priority: ๐ด Urgent |
/claim | ticket-username | ๐ก Medium | ๐ Claimed by @Staff | + Claimed by field |
/unclaim | ticket-username | ๐ก Medium | field removed |
/lock lock | ticket-username | unchanged | lock notice posted |
| Ticket closed | closed-ticket-username | unchanged | all buttons removed |
| Reopen | ticket-username | restored | reopen embed + ticket buttons restored |
Note on rate-limits: Discord limits channel topic changes to 2 per 10 minutes. A warning is shown in the ticket and the update appears automatically once the limit resets.
Ticket Typesโ
{
"codeName": "support",
"name": "Support",
"description": "...",
"emoji": "๐ก",
"color": "#ff0000", // Hex color or "" to use mainColor
"categoryId": "123456789",
"priority": "medium", // Predefined start priority: "low", "medium", "high" or "urgent" (defaults to "medium")
"ticketNameOption": "", // USERNAME, USERID, TICKETCOUNT or ""
"customDescription": "...", // Variables: REASON1, REASON2, USERNAME, USERID
"cantAccess": ["roleId"],
"staffRoles": [], // Type-specific staff roles
"askQuestions": true,
"questions": [
{ "label": "Question", "placeholder": "...", "style": "SHORT", "maxLength": 500 }
]
}
Bot Statusโ
"status": {
"enabled": true,
"dynamic": false, // true = live ticket count in status
"dynamicText": "๐ซ {open} open tickets", // placeholders: {open}, {total}, {closed}
"dynamicInterval": 5, // update interval in minutes
"text": "Support Tickets", // used when dynamic: false
"type": "WATCHING", // PLAYING, WATCHING, LISTENING, STREAMING, COMPETING
"status": "online"
}
User Notificationsโ
"userNotifications": {
"enabled": true // Show a ๐ "Notify me" button in new tickets.
// User opts in โ receives a DM when staff first replies.
// Rate-limited to 1 DM per 30 minutes per ticket.
}
Canned Responses (Snippets)โ
Snippets are defined in a separate file โ not in config.jsonc:
cp config/snippets.example.jsonc config/snippets.jsonc
{
"snippets": [
{
"name": "welcome",
"description": "Welcome message at the start of a ticket",
"content": "Hey {user}! ๐ Thanks for opening a ticket. We'll be with you shortly.",
"embed": {
"title": "๐ Welcome",
"color": "#5865F2"
}
},
{
"name": "docs",
"description": "Link to the MSK-Scripts documentation",
"content": "Hey {user}, check out our docs: https://docu.msk-scripts.de",
"embed": null
}
]
}
Available placeholders: {user} ยท {staff} ยท {type} ยท {priority}
Commands: /snippet send <name> ยท /snippet list
Snippets support autocomplete โ start typing the name or description to filter.
Staff Reminderโ
"staffReminder": {
"enabled": true,
"afterHours": 4,
"pingRoles": true
}
The bot checks all open tickets every 15 minutes. Each ticket is only reminded once.
Rating Systemโ
"ratingSystem": {
"enabled": true,
"dmUser": true,
"ratingsChannelId": "CHANNEL_ID_HERE"
}
Auto-Closeโ
"autoClose": {
"enabled": true,
"inactiveHours": 48,
"warnBeforeHours": 6,
"excludeClaimed": true
}
Reopenโ
Closed tickets can be reopened via a โป๏ธ Reopen button on the closed-ticket message and the /reopen command.
"reopenOption": {
"enabled": true, // Master switch for the reopen feature (button + /reopen)
"button": true, // Show the โป๏ธ Reopen button on the closed-ticket message
"whoCanReopen": "STAFFONLY" // "EVERYONE" or "STAFFONLY"
}
| Field | Description |
|---|---|
enabled | Master switch. When false, the button is hidden and /reopen replies that it is disabled. |
button | Whether the โป๏ธ Reopen button is shown on the closed-ticket message. |
whoCanReopen | "STAFFONLY" (default) requires staff. "EVERYONE" allows anyone who can see the channel. |
Reopening restores the creator's channel access, moves the channel back to its ticket type's category and drops the closed- name prefix.
Note: Closed channels are usually only visible to staff (the creator's view is removed on close), so
"EVERYONE"mainly matters if you keep closed channels visible to users.
Transcript Designโ
The generated HTML transcript can be rendered in two styles:
"transcriptDesign": "modern" // "modern" (default) or "classic"
| Value | Look |
|---|---|
"modern" | Minimal, MSK-branded layout (default โ also used if the key is absent). |
"classic" | The original Discord-style dark layout. |
Both styles are fully self-contained / offline-safe (no external requests):
- Avatars and custom emojis are embedded as Base64 (custom emojis fall back to
:name:text if the image can't be fetched at generation time). - User mentions and the header fields Created by / Claimed by / Closed by are shown as display names instead of raw user IDs (unresolvable IDs fall back to the ID).
- The header also shows Closed by and the close reason โ the reason only when one was provided.
- Fenced code blocks show their language as a small label (e.g.
LUA); no syntax colouring (kept dependency-free).
Statisticsโ
/stats shows server-wide numbers. /stats @user shows a detailed profile split into ๐ค As a User and ๐ก๏ธ As Staff.