> For the complete documentation index, see [llms.txt](https://docs.iynxdev.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.iynxdev.com/configuration-files/tickets.md).

# Tickets

## <mark style="color:blue;">Introduction</mark>

The Tickets configuration file (`tickets.json`) manages your support ticket system including categories, permissions, questions, transcripts, and automation.

***

## <mark style="color:blue;">General Settings</mark>

### <mark style="color:yellow;">send\_transcript\_to\_ticket\_creator</mark>

**Type:** Boolean

Send transcript copy to ticket creator.

```json
send_transcript_to_ticket_creator: true
```

**When `true`:** User receives transcript when ticket closes\
**When `false`:** No transcript is sent to user

***

### <mark style="color:yellow;">save\_ticket\_transcript\_on\_disk</mark>

**Type:** Boolean

Save transcripts to disk locally.

```json
save_ticket_transcript_on_disk: true
```

**When `true`:** Transcripts saved to `\logs\transcripts\`\
**When `false`:** No local save

***

### <mark style="color:yellow;">update\_permissions\_on\_move</mark>

**Type:** Boolean

Sync permissions when moving tickets.

```json
update_permissions_on_move: true
```

**When `true`:** Permissions update to match new category when using `/tmove`\
**When `false`:** Permissions stay the same

***

### <mark style="color:yellow;">ticket\_channel\_name</mark>

**Type:** String

Channel name format for tickets.

```json
ticket_channel_name: "ticket-%random%"
```

**Placeholders:**

* `%random%` - Random number
* `%creator%` - Username
* `%created_total%` - Total tickets created
* `%category%` - Category name

Categories can override this with custom names.

***

### <mark style="color:yellow;">ticket\_transcript\_message\_limit</mark>

**Type:** Number

Maximum messages included in transcripts.

```json
ticket_transcript_message_limit: 200
```

***

### <mark style="color:yellow;">close\_ticket\_after\_creator\_left</mark>

**Type:** Boolean

Auto-close tickets when creator leaves server.

```json
close_ticket_after_creator_left: true
```

***

### <mark style="color:yellow;">ping\_role\_at\_permission\_update</mark>

**Type:** Boolean

Ping role when ticket is elevated/lowered.

```json
ping_role_at_permission_update: false
```

**When `true`:** New permission level role is mentioned\
**When `false`:** No ping

***

### <mark style="color:yellow;">ticket\_creation\_limit</mark>

**Type:** String

How many tickets users can create.

```json
ticket_creation_limit: "CATEGORY"
```

**Options:**

* `"CATEGORY"` - One ticket per category
* `"GLOBAL"` - One ticket total across all categories
* `"NONE"` - Unlimited tickets

Does not apply to applications.

***

### <mark style="color:yellow;">enable\_web\_server</mark>

**Type:** Boolean

Upload transcripts to web server.

```json
enable_web_server: true
```

**When `true`:** Transcripts uploaded and replaced with link\
**When `false`:** Transcripts sent as files

***

### <mark style="color:yellow;">send\_transcript\_to\_claimed\_user</mark>

**Type:** Boolean

Send transcript to staff who claimed ticket.

```json
send_transcript_to_claimed_user: false
```

***

### <mark style="color:yellow;">send\_plain\_ticket\_create\_message</mark>

**Type:** Boolean

Use plain text instead of embed for ticket creation message.

```json
send_plain_ticket_create_message: false
```

***

### <mark style="color:yellow;">use\_discord\_category\_permissions</mark>

**Type:** Boolean

Inherit Discord category permissions.

```json
use_discord_category_permissions: false
```

**When `true`:** Uses Discord category permissions, ignores `permission_level` settings\
**When `false`:** Uses configured permission levels

***

### <mark style="color:yellow;">generate\_new\_category\_if\_full</mark>

**Type:** Boolean

Auto-create new categories when full (50 channel limit).

```json
generate_new_category_if_full: false
```

***

### <mark style="color:yellow;">maximum\_generated\_categories</mark>

**Type:** Number

Maximum auto-generated categories.

```json
maximum_generated_categories: 10
```

Only applies when `generate_new_category_if_full` is enabled.

***

### <mark style="color:yellow;">all\_roles\_required\_to\_open</mark>

**Type:** Boolean

Whether all roles in `required_role_to_open` are needed.

```json
all_roles_required_to_open: false
```

**When `true`:** User needs ALL configured roles\
**When `false`:** User needs only ONE of the configured roles

***

### <mark style="color:yellow;">enable\_ticket\_rating\_system</mark>

**Type:** Boolean

Enable rating system after ticket closure.

```json
enable_ticket_rating_system: true
```

***

## <mark style="color:blue;">Ticket Categories</mark>

**Type:** Array of Objects

Define ticket types and their settings. Each category represents a different ticket type (e.g., General Support, Bug Reports, Appeals, etc.).

```json
ticket_categories: [
    {
        category: "General Support",
        description: "Select to create a General ticket.",
        emoji: "❓",
        category_id: "833732233021751306",
        permission_level: 0,
        ticket_create_questions: "first_question_set",
        required_role_to_open: [],
        mention_roles: ["804354029076348959"],
        ticket_create_msg: "default",
    },
    {
        category: "Bug Report",
        description: "Report bugs or issues with the server.",
        emoji: "🐛",
        category_id: "833732304366338128",
        permission_level: 1,
        ticket_create_questions: "bug_questions",
        required_role_to_open: [],
        mention_roles: ["804354022612926515"],
        ticket_create_msg: "bug_template",
    },
    {
        category: "VIP Support",
        description: "Priority support for VIP members.",
        emoji: "⭐",
        category_id: "833732400000000000",
        permission_level: 0,
        ticket_create_questions: null,
        required_role_to_open: ["123456789012345678"], // VIP Role ID
        mention_roles: ["804354019455139900"],
        ticket_create_msg: "vip_template",
    },
]
```

**category** - Category name displayed in the ticket panel and channel\
**description** - Category description shown in panel dropdown/buttons\
**emoji** - Emoji for category button (use Discord emoji picker or custom emoji ID)\
**category\_id** - Discord category ID where ticket channels will be created\
**permission\_level** - Starting permission level (0 = lowest, higher numbers = more restricted)\
**ticket\_create\_questions** - Question set ID from `question_list` or `null` to skip questions\
**required\_role\_to\_open** - Array of role IDs required to open this ticket type (empty array = anyone can open)\
**mention\_roles** - Array of role IDs to ping when ticket is created (e.g., support team roles)\
**ticket\_create\_msg** - Message template ID from `ticket_create_message` section

{% hint style="success" %}
**Example Use Cases:**

* **General Support**: Open to everyone, low permission level, asks basic questions
* **Bug Report**: Open to everyone, higher permission for developers, asks detailed bug info
* **VIP Support**: Restricted to VIP role, pings senior staff, no questions needed
* **Appeals**: Open to everyone, highest permission for admins, asks for appeal details
  {% endhint %}

***

## <mark style="color:blue;">Permission Levels</mark>

**Type:** Array of Strings

Define ticket access hierarchy using Discord role IDs. This creates a tiered support system where higher-level staff can access lower-level tickets.

```json
permission_levels: [
    "804354029076348959", // Level 0 - Helper/Support (lowest)
    "804354022612926515", // Level 1 - Moderator
    "804354019455139900", // Level 2 - Senior Moderator
    "804354017580810260", // Level 3 - Admin (highest)
]
```

**How Permission Levels Work:**

1. **Position in Array**: Index 0 is the lowest level, higher indexes = higher permission levels
2. **Ticket Access**: Staff with a role can see tickets at their level AND all levels below them
3. **Starting Level**: Tickets start at the `permission_level` set in their category
4. **Escalation**: Use `/televate` to increase level, `/tlower` to decrease level

**Detailed Example:**

Let's say you have these permission levels:

* Level 0: Helper role (ID: `111111111111111111`)
* Level 1: Moderator role (ID: `222222222222222222`)
* Level 2: Admin role (ID: `333333333333333333`)

**Scenario 1 - General Support Ticket (permission\_level: 0)**

* ✅ Helpers can see it (they are level 0)
* ✅ Moderators can see it (level 1 can access level 0)
* ✅ Admins can see it (level 2 can access levels 0 and 1)

**Scenario 2 - Bug Report Ticket (permission\_level: 1)**

* ❌ Helpers CANNOT see it (level 0 cannot access level 1)
* ✅ Moderators can see it (they are level 1)
* ✅ Admins can see it (level 2 can access level 1)

**Scenario 3 - Ticket Elevated to Level 2**

* ❌ Helpers CANNOT see it
* ❌ Moderators CANNOT see it
* ✅ Only Admins can see it (level 2)

{% hint style="info" %}
**Common Setup:**

* Level 0: Junior Support / Helpers
* Level 1: Moderators / Regular Support
* Level 2: Senior Moderators / Team Leads
* Level 3: Administrators / Management

This allows tickets to start with helpers, then be escalated to mods, then admins if needed.
{% endhint %}

***

## <mark style="color:blue;">Ticket Create Questions</mark>

Pre-ticket questions to gather information before the ticket is created. This helps support staff have context immediately.

### <mark style="color:yellow;">enabled</mark>

**Type:** Boolean

Whether to enable question system.

```json
ticket_create_questions: {
    enabled: true,
}
```

***

### <mark style="color:yellow;">question\_list</mark>

**Type:** Object

Question sets for different categories. Each set has a unique ID that you reference in `ticket_categories`.

```json
question_list: {
    "first_question_set": [
        {
            question: "What is your ingame name?",
            max_length: 20,
            min_length: 2,
            placeholder: "Enter your username...",
            select_options: [],
            required: true,
        },
        {
            question: "On which realm are you playing?",
            max_length: 1,
            min_length: 1,
            placeholder: "Select your realm...",
            select_options: ['Orbit', 'Skyblock', 'Survival', 'Creative'],
            required: true,
        },
        {
            question: "What's your issue?",
            max_length: 500,
            min_length: 30,
            placeholder: "Describe your issue in detail...",
            select_options: [],
            required: true,
        },
    ],
    "bug_questions": [
        {
            question: "What type of bug is this?",
            max_length: 2,
            min_length: 1,
            placeholder: "Select bug type(s)...",
            select_options: ['Gameplay Bug', 'Visual Bug', 'Crash', 'Performance Issue', 'Other'],
            required: true,
        },
        {
            question: "Describe the bug in detail",
            max_length: 1000,
            min_length: 50,
            placeholder: "What happened? What did you expect to happen?",
            select_options: [],
            required: true,
        },
        {
            question: "Steps to reproduce",
            max_length: 500,
            min_length: 20,
            placeholder: "1. First I did...\n2. Then I...\n3. Bug occurred when...",
            select_options: [],
            required: true,
        },
    ],
    "appeal_questions": [
        {
            question: "What were you punished for?",
            max_length: 1,
            min_length: 1,
            placeholder: "Select punishment type...",
            select_options: ['Ban', 'Mute', 'Kick', 'Warning'],
            required: true,
        },
        {
            question: "When were you punished?",
            max_length: 100,
            min_length: 5,
            placeholder: "e.g., Yesterday, Last week, 3 days ago...",
            select_options: [],
            required: true,
        },
        {
            question: "Why should we remove your punishment?",
            max_length: 1000,
            min_length: 50,
            placeholder: "Explain why you believe the punishment should be removed...",
            select_options: [],
            required: false,
        },
    ],
}
```

**question** - Question text displayed to the user\
**max\_length** - For text: max characters allowed. For dropdowns: max number of options user can select\
**min\_length** - For text: min characters required. For dropdowns: min number of options user must select\
**placeholder** - Placeholder text shown in the input field\
**select\_options** - Empty array `[]` = text input. Array with values = dropdown menu\
**required** - `true` = must be answered, `false` = optional

{% hint style="warning" %}
**Important:** For select menus (dropdowns), `max_length` and `min_length` control how many options can be selected, NOT the character length of each option.

**Example:**

* `max_length: 1, min_length: 1` = User must select exactly 1 option
* `max_length: 3, min_length: 1` = User can select 1 to 3 options
* `max_length: 5, min_length: 2` = User must select between 2 and 5 options
  {% endhint %}

**Question Type Examples:**

**Text Input (Short Answer):**

```json
{
    question: "What is your Minecraft username?",
    max_length: 16,
    min_length: 3,
    placeholder: "Enter your username...",
    select_options: [],
    required: true,
}
```

**Text Input (Long Answer):**

```json
{
    question: "Describe what happened",
    max_length: 1000,
    min_length: 30,
    placeholder: "Provide as much detail as possible...",
    select_options: [],
    required: true,
}
```

**Single Selection Dropdown:**

```json
{
    question: "Which server are you on?",
    max_length: 1,
    min_length: 1,
    placeholder: "Select a server...",
    select_options: ['Survival', 'Creative', 'Skyblock', 'Prison'],
    required: true,
}
```

**Multiple Selection Dropdown:**

```json
{
    question: "What features are affected? (Select all that apply)",
    max_length: 5,
    min_length: 1,
    placeholder: "Select affected features...",
    select_options: ['Chat', 'Commands', 'Economy', 'PvP', 'Building'],
    required: true,
}
```

**Optional Question:**

```json
{
    question: "Additional information (optional)",
    max_length: 500,
    min_length: 0,
    placeholder: "Any other details...",
    select_options: [],
    required: false,
}
```

***

## <mark style="color:blue;">Ticket Create Message</mark>

**Type:** Object

First message sent in new tickets. Each template has a unique ID that you reference in ticket categories.

```json
ticket_create_message: {
    "default": {
        author: {
            name: '%guild%',
            icon_url: '%guild_icon%',
        },
        title: "``🎫 Ticket Created``",
        description: "Hey %creator%,\nThank you for creating %ticket_channel%. A staff member will assist you shortly.\n\nWhile you wait, please provide:\n• Your in-game name\n• What you need help with\n• Any relevant screenshots",
        color: "#3498db",
        defaultFooter: true,
        defaultTimestamp: true,
        userIcon: true,
    },
    "bug_template": {
        author: {
            name: 'Bug Report',
            icon_url: '%guild_icon%',
        },
        title: "``🐛 Bug Report Ticket``",
        description: "Thanks for reporting a bug, %creator%!\n\nA developer will review your report soon. Please make sure you've provided:\n✅ Detailed description\n✅ Steps to reproduce\n✅ Screenshots/videos if possible",
        color: "#e74c3c",
        defaultFooter: true,
        defaultTimestamp: true,
    },
    "vip_template": {
        author: {
            name: 'VIP Support',
            icon_url: '%guild_icon%',
        },
        title: "``⭐ VIP Priority Support``",
        description: "Welcome %creator%!\n\nThank you for being a VIP member. A senior staff member has been notified and will assist you as soon as possible.\n\nPriority response time: **Under 15 minutes**",
        color: "#f1c40f",
        thumbnail: {
            url: '%guild_icon%',
        },
        defaultFooter: true,
        defaultTimestamp: true,
    },
    "appeal_template": {
        title: "``⚖️ Punishment Appeal``",
        description: "%creator%, your appeal has been submitted.\n\nAn administrator will review your case within 24-48 hours.\n\n**Important:**\n• Be honest and respectful\n• Additional rule violations will result in appeal denial\n• Spamming messages will delay your appeal",
        color: "#95a5a6",
        defaultFooter: true,
        defaultTimestamp: true,
    },
}
```

Uses same embed format as `lang.json` configuration file.

**Available Placeholders:**

* `%creator%` - Mentions the ticket creator
* `%ticket_channel%` - Mentions the ticket channel
* `%guild%` - Server name
* `%guild_icon%` - Server icon URL

**Embed Properties:**

* `author` - Author section with name and icon
* `title` - Embed title
* `description` - Main embed content (supports newlines with `\n`)
* `color` - Hex color code (e.g., `"#3498db"`)
* `thumbnail` - Small image in top-right corner
* `image` - Large image at bottom
* `fields` - Array of field objects with `name` and `value`
* `footer` - Footer text and icon
* `defaultFooter` - Use default footer (true/false)
* `defaultTimestamp` - Add timestamp (true/false)
* `userIcon` - Use ticket creator's avatar (true/false)

{% hint style="success" %}
**Pro Tip:** Create different templates for different ticket types to set the right expectations:

* **General Support**: Welcoming message with basic instructions
* **Bug Reports**: Technical format asking for reproduction steps
* **VIP Support**: Priority messaging with faster response times
* **Appeals**: Formal tone with appeal process information
  {% endhint %}

***

## <mark style="color:blue;">Ticket Priority</mark>

The Tickets plugin now includes a full priority system for tickets.

### <mark style="color:yellow;">enabled</mark>

**Type:** Boolean

Enable the ticket priority system.

```json
priority_settings: {
    enabled: true,
}
```

***

### <mark style="color:yellow;">default\_level</mark>

**Type:** String

The default priority level assigned to tickets when no role-based priority applies.

```json
default_level: "Default"
```

***

### <mark style="color:yellow;">levels</mark>

**Type:** Array of Objects

Defines the available priority levels and how they behave.

Each level can include:

* `priority_name` - The displayed priority name.
* `mention_roles` - Roles to ping when a ticket is created at this priority.
* `move_to_top` - Whether the ticket channel is moved to the top of the category.
* `priority_placeholder` - Text added before the ticket channel name.

```json
levels: [
    {
        priority_name: "High",
        mention_roles: ["884573835205148692"],
        move_to_top: true,
        priority_placeholder: "🔴-",
    },
    {
        priority_name: "Medium",
        mention_roles: ["878410148874448928"],
        move_to_top: false,
        priority_placeholder: "🟡-",
    },
    {
        priority_name: "Low",
        mention_roles: ["804354030662713344"],
        move_to_top: false,
        priority_placeholder: "🟢-",
    },
    {
        priority_name: "Default",
        mention_roles: [],
        move_to_top: false,
        priority_placeholder: "",
    }
]
```

***

### <mark style="color:yellow;">role\_priority</mark>

**Type:** Object

Automatically assign priority levels based on user roles.

```json
role_priority: {
    enabled: false,
    roles: [
        {
            role_id: "804354030662713344",
            priority_level: "High",
        },
        {
            role_id: "804354036001407037",
            priority_level: "Low",
        },
    ],
}
```

If a user has one of the listed roles, their ticket will receive the mapped priority level. If not, the default priority level is used.

***

## <mark style="color:blue;">Out of Service</mark>

Notify users during off-hours.

### <mark style="color:yellow;">enabled</mark>

**Type:** Boolean

Enable out-of-service notifications.

```json
out_of_service: {
    enabled: false,
}
```

***

### <mark style="color:yellow;">time</mark>

**Type:** Object

Off-hours time range in UTC.

```json
time: {
    start: "23:00",
    finished: "07:00",
}
```

Format: `"hh:mm"` in 24-hour UTC time.

***

## <mark style="color:blue;">Inactivity Closure</mark>

Auto-close inactive tickets.

### <mark style="color:yellow;">enabled</mark>

**Type:** Boolean

Enable inactivity closure.

```json
inactivity_closure: {
    enabled: true,
}
```

***

### <mark style="color:yellow;">send\_warning</mark>

**Type:** Boolean

Send warning before closing.

```json
send_warning: true
```

***

### <mark style="color:yellow;">send\_warning\_before</mark>

**Type:** Number

Hours before closure to send warning.

```json
send_warning_before: 24
```

***

### <mark style="color:yellow;">inactive\_for</mark>

**Type:** Number

Hours of inactivity before closing.

```json
inactive_for: 72
```

***

## <mark style="color:blue;">Ticket Buttons</mark>

**Type:** Object

Control which buttons appear on ticket creation message.

```json
ticket_buttons: {
    close: false,
    close_request: true,
    elevate: true,
    lower: true,
    claim: true,
    unclaim: true,
}
```

**close** - Direct close button\
**close\_request** - Request closure button\
**elevate** - Increase permission level\
**lower** - Decrease permission level\
**claim** - Claim ticket\
**unclaim** - Unclaim ticket

***

## <mark style="color:blue;">Complete Configuration Example</mark>

Here's a production-ready tickets configuration:

```json
{
    config: {
        send_transcript_to_ticket_creator: true,
        save_ticket_transcript_on_disk: true,
        update_permissions_on_move: true,
        ticket_channel_name: "ticket-%random%",
        ticket_transcript_message_limit: 200,
        close_ticket_after_creator_left: true,
        ping_role_at_permission_update: false,
        ticket_creation_limit: "CATEGORY",
        enable_web_server: true,
        send_transcript_to_claimed_user: false,
        send_plain_ticket_create_message: false,
        use_discord_category_permissions: false,
        generate_new_category_if_full: false,
        maximum_generated_categories: 10,
        all_roles_required_to_open: false,
        enable_ticket_rating_system: true,

        ticket_categories: [
            {
                category: "General Support",
                description: "Select to create a General ticket.",
                emoji: "❓",
                category_id: "833732233021751306",
                permission_level: 0,
                ticket_create_questions: "first_question_set",
                required_role_to_open: [],
                mention_roles: ["804354029076348959"],
                ticket_create_msg: "default",
            },
        ],

        permission_levels: [
            "804354029076348959", // Level 0
            "804354022612926515", // Level 1
            "804354019455139900", // Level 2
        ],

        ticket_create_questions: {
            enabled: true,
            question_list: {
                "first_question_set": [
                    {
                        question: "What is your issue?",
                        max_length: 200,
                        min_length: 30,
                        placeholder: "Describe your issue...",
                        select_options: [],
                        required: true,
                    },
                ],
            }
        },

        ticket_create_message: {
            "default": {
                title: "``🎫 Ticket Created``",
                description: "Thank you for creating %ticket_channel%!",
                defaultFooter: true,
            },
        },

        priority_settings: {
            enabled: true,
            default_level: "Default",
            levels: [
                {
                    priority_name: "High",
                    mention_roles: ["884573835205148692"],
                    move_to_top: true,
                    priority_placeholder: "🔴-",
                },
                {
                    priority_name: "Medium",
                    mention_roles: ["878410148874448928"],
                    move_to_top: false,
                    priority_placeholder: "🟡-",
                },
                {
                    priority_name: "Low",
                    mention_roles: ["804354030662713344"],
                    move_to_top: false,
                    priority_placeholder: "🟢-",
                },
                {
                    priority_name: "Default",
                    mention_roles: [],
                    move_to_top: false,
                    priority_placeholder: "",
                },
            ],
            role_priority: {
                enabled: false,
                roles: [
                    {
                        role_id: "804354030662713344",
                        priority_level: "High",
                    },
                ],
            },
        },

        out_of_service: {
            enabled: false,
            time: {
                start: "23:00",
                finished: "07:00",
            }
        },

        inactivity_closure: {
            enabled: true,
            send_warning: true,
            send_warning_before: 24,
            inactive_for: 72,
        },

        ticket_buttons: {
            close: false,
            close_request: true,
            elevate: true,
            lower: true,
            claim: true,
            priority: true,
            unclaim: true,
        },
    },
}
```
