Private ticket channels
Build a ticket panel that opens a private room for a member and the support team.
Examples use the bot client from Your first bot.
Set up the panel
- Create a visible #tickets channel and a regular support role.
- Use SDK 0.5.0 or newer. Install the bot with all server channels selected and approve View Channel, Send Messages, Manage Channels and Manage Roles. Add Message Content if you want to save transcripts.
- Put the bot’s managed role above the support role. In the Python source archive, examples/tickets.py includes a runnable bot. Configure the IDs in the README, then run /ticket-setup in #tickets.
Open a private ticket
Send an Open a ticket button in your panel. Reply privately with a reason menu. When someone selects a reason, use their ID from the interaction and the configured support role ID. The channel and its access are saved together.
const { items } = await bot.categories(serverId);
const category = items.find(item => item.name === 'Tickets')
?? await bot.createCategory(serverId, 'Tickets');
const access = { allow: ['VIEW_CHANNEL', 'SEND_MESSAGES'] };
const channel = await bot.createChannel(serverId, {
name: 'ticket-' + interaction.id, categoryId: category.id, private: true,
overwrites: {
members: { [interaction.userId]: access },
roles: { [supportRoleId]: access },
},
});Close, reopen, save or delete
Keep the ticket’s channel ID, requester ID and staff role in your own store. When someone uses a control, look up their current roles and verify they can act in that ticket before changing it.
To close a ticket, use setChannelOverwrite / set_channel_overwrite with target member. Allow VIEW_CHANNEL and deny SEND_MESSAGES for the requester. The bot can deny permissions only to eligible members below its managed role. To reopen, allow both again. Owners and Administrators keep their normal bypass.
Save with paginated history and keep the export in restricted storage. Ask staff to confirm before calling deleteChannel / delete_channel. Deleting the channel removes its messages.