-
-
Notifications
You must be signed in to change notification settings - Fork 280
Custom Messages
Ticket-Bot message templates live in the messages/ directory. Config values reference them without the messages/ prefix or file extension.
Example:
message: "tickets/open-panel"This resolves to:
messages/tickets/open-panel.ts
Templates export a Discord message payload object or a function that returns one.
Simple object:
export default {
content: "Hello from Ticket-Bot"
};Function:
export default ({ LL }) => ({
content: LL.tickets.templates.open_panel.description()
});Templates can use:
contentembedscomponentsflagsallowed_mentionsuseComponentsV2
Classic messages can use content and embeds.
Components V2 messages use component types such as containers and text displays. When Components V2 is enabled:
- Do not use
content. - Do not use
embeds. - Put visible text inside components.
Ticket-Bot automatically adds the Components V2 flag when V2 components are detected or useComponentsV2 is true.
Use classic embeds when you want the old Discord embed layout instead of Components V2 containers:
- Remove
useComponentsV2: true. - Do not use Components V2 component types such as
Container,TextDisplay,Section,Separator,Thumbnail,MediaGallery, orFile. - Put the visible message body in
contentand/orembeds. - Keep interactive controls as regular action-row components. Ticket-Bot can still inject panel openers and ticket action buttons through slots.
Discord references:
This creates a panel with a normal Discord embed. The select menu or buttons configured in panels are inserted into the panel-opener slot.
import { createPanelOpenerSlot } from "@/features/tickets/messages";
import type { LoadedMessageTemplate } from "@/features/tickets/types";
const openPanelMessage = (): LoadedMessageTemplate => ({
content: "Choose the ticket type that fits your issue best.",
embeds: [
{
title: "Support Tickets",
description: "Open a ticket and the team will help you as soon as possible.",
color: 0xf5c26b,
footer: {
text: "Powered by Ticket-Bot"
}
}
],
components: [createPanelOpenerSlot()]
});
export default openPanelMessage;This creates a ticket welcome message with a classic embed. Ticket-Bot inserts claim, unclaim, close, and delete buttons into the actions slot.
import { createMessageSlot } from "@/features/tickets/messages";
import type { LoadedMessageTemplate } from "@/features/tickets/types";
const ticketOpenedMessage = (): LoadedMessageTemplate => ({
content: "{createdByMention}{staffMentions}",
embeds: [
{
title: "{ticketTypeName} Ticket #{ticketNumber}",
description: "Thanks for opening a ticket. A staff member will reply here.",
color: 0xf5c26b,
fields: [
{
name: "Reason",
value: "{reason}"
},
{
name: "Claim status",
value: "{claimStatus}"
}
],
footer: {
text: "Powered by Ticket-Bot"
}
}
],
components: [createMessageSlot("actions")]
});
export default ticketOpenedMessage;Use Components V2 when you want container layouts, text display blocks, separators, thumbnails, media galleries, or other V2-only components. Do not include content or embeds in this format.
import { ComponentType } from "discord-api-types/v10";
import { createPanelOpenerSlot } from "@/features/tickets/messages";
import type { LoadedMessageTemplate } from "@/features/tickets/types";
const openPanelMessage = (): LoadedMessageTemplate => ({
useComponentsV2: true,
components: [
{
type: ComponentType.Container,
accent_color: 0xf5c26b,
components: [
{
type: ComponentType.TextDisplay,
content: "## Support Tickets"
},
{
type: ComponentType.TextDisplay,
content: "Open a ticket and the team will help you as soon as possible."
},
{
type: ComponentType.Separator
},
createPanelOpenerSlot()
]
}
]
});
export default openPanelMessage;Slots let Ticket-Bot inject runtime controls into your template.
Panel opener slot:
createPanelOpenerSlot()Ticket runtime text slot:
createRuntimeTextSlot()Generic action slot:
createMessageSlot("actions")Common behavior:
- Panel opener controls are inserted into the
panel-openerslot. - Claim, unclaim, close, and delete buttons are inserted into the
actionsslot. - Runtime welcome content can be inserted into the
runtime-textslot.
If a slot is missing, Ticket-Bot appends the controls in a safe fallback location.
Ticket open and welcome templates can use:
{channelId}{claimStatus}{claimerId}{claimerMention}{createdByMention}{reason}-
{reason1},{reason2}, etc. {staffMentions}{ticketNumber}{ticketTypeKey}{ticketTypeName}{userId}{username}{closeButtonCustomId}
Close channel and DM templates can use:
{channelId}{claimStatus}{claimerId}{claimerMention}{closerId}{closerMention}{closerName}{reason}{transcriptStatus}{transcriptUrl}{userId}{deleteButtonCustomId}
- Keep custom IDs provided by tokens when creating buttons used by the bot.
- Do not hardcode private tokens or secrets in message templates.
- Keep template references inside the
messages/directory. - Use TypeScript files when you want typed imports and helpers.
- Restart the bot after changing templates so panels and future ticket messages use the new content.
Create:
messages/tickets/ticket-opened-billing-custom.ts
Then configure:
ticketTypes: {
billing: {
message: "tickets/ticket-opened-billing-custom"
}
}Restart the bot. Existing ticket welcome messages are not automatically rewritten unless a workflow such as claim sync edits them.