# 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,
        },
    },
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.iynxdev.com/configuration-files/tickets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
