Discord has become one of the most popular communication platforms, with over 150 million active users. One of the great things about Discord is the ability to create custom bots that can provide useful functionality to your server. A ticket bot allows users to open support tickets within a Discord server to easily get help from staff members. In this comprehensive guide, we’ll walk through how to create a custom ticket bot from scratch using Discord.js and Node.js.
Prerequisites
Before we start coding our Discord ticket bot, let’s go over some prerequisites:
- Basic knowledge of JavaScript
- Node.js installed on your computer
- A Discord bot token
- Discord.js module installed
- A code editor like Visual Studio Code
- Access to a hosting platform like Glitch or Heroku (optional)
If you don’t already have a Discord bot created, you’ll need to create one in the Discord Developer Portal first. This will generate a token that will allow your bot to connect to Discord’s API. The Discord.js module will also need to be installed via npm which allows you to interact with Discord’s API.
Setting Up the Bot Project
Let’s start by creating a new project folder on your computer called “discord-ticket-bot”. Open up a terminal or command prompt and navigate into this folder.
Run the command:
npm init
This will initialize a new Node.js project. You can press enter a few times to accept the defaults. After this completes, you’ll have a package.json file in your project folder.
Next, we’ll want to install Discord.js and dotenv:
npm install discord.js dotenv
dotenv allows us to load our Discord bot token from an environment variable for security.
Now create a .env file in your project folder and add your Discord bot token:
TOKEN=YOUR_BOT_TOKEN
Replace YOUR_BOT_TOKEN with your actual bot token from the Discord Developer Portal. This will be loaded by dotenv.
Coding the Bot
With the project setup complete, we can start coding our Discord ticket bot.
Create a index.js file and add the following code:
// Load Discord.js and .env const Discord = require('discord.js'); require('dotenv').config(); // Create Discord client const client = new Discord.Client(); // Ready event client.on('ready', () => { console.log(`Logged in as ${client.user.tag}!`); }); // Login with token client.login(process.env.TOKEN);
This basic code loads Discord.js, configures the bot client, and logs in using your token.
Run the bot with:
node index.js
You should see it log “Logged in as” in the terminal if successful. This verifies our basic bot structure is working before we continue adding more code.
Adding Ticket Creation
Now we can start adding the ticket creation logic. This will involve:
- Creating a new channel category to store tickets
- Reacting to a message to open a ticket
- Creating and formatting the new ticket channel
In your index.js file, add the following:
// Create ticket category const categoryId = 'PUT_CATEGORY_ID_HERE'; // Ticket open reaction const openTicketEmoji = '🎫'; // Create ticket channel async function createTicketChannel(member) { // Get guild and category channels const guild = member.guild; const categoryChannel = guild.channels.cache.get(categoryId); // Create channel const createdChannel = await guild.channels.create(`${member.user.username}'s Ticket`, { permissionOverwrites: [ { id: guild.id, deny: ['VIEW_CHANNEL'] }, { id: member.id, allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES'] } ], type: 'text', parent: categoryChannel }); // Send starting message createdChannel.send(`Welcome <@${member.id}>! Please explain your issue.`); }
This code does a few things:
- Defines the ticket category channel ID (set this to your server’s ticket category)
- Sets the reaction emoji that will trigger ticket creation
- Creates the new text channel under the defined category
- Applies permission overwrites so only the user can view the channel
- Sends a starting message in the new channel
Next, we need to call this function when a reaction is added:
// Ticket reaction listener client.on('messageReactionAdd', async (reaction, user) => { // Check for ticket emoji if (reaction.emoji.name === openTicketEmoji) { // Create ticket channel createTicketChannel(user); } });
This listens for reactions being added and checks if it is the defined emoji. If so, it calls our createTicketChannel function, passing the reacted user object.
To test this, add a message in a server channel asking users to react to open a ticket. Once reacted to, it should create a new channel category and channel for that user!
Closing Tickets
We also want to allow staff members to close ticket channels once the issue is resolved.
Add this code:
// Close ticket command client.on('message', message => { // Check for staff role if (!message.member.roles.cache.find(r => r.name === 'Staff')) { return; } // Close ticket if (message.content.toLowerCase() === '!closet') { message.channel.delete(); } });
This listens for messages and checks if the sender has the “Staff” role. If so, it checks for the !closet command and deletes the channel if present.
To use this, have a staff member type !closet to close the ticket channel.
Sending Transcripts
To finish our bot, let’s add the ability to send a transcript of the full ticket conversation to a log channel when closed.
Add this code:
// Send transcript async function sendTranscript(channel) { // Fetch messages const messages = await channel.messages.fetch(); // Send messages client.channels.cache.get('LOG_CHANNEL_ID') .send(messages.map(m => `${m.author.tag}: ${m.content}`).join('\n')); }
This fetches all the ticket messages and sends them to the defined log channel in plain text format.
Call this in the close ticket command:
if (message.content.toLowerCase() === '!closet') { // Send transcript sendTranscript(message.channel); // Close channel message.channel.delete(); }
Now when a staff member closes a ticket, the full conversation will be logged!
Hosting the Bot
Your Discord ticket bot is complete! You can continue hosting it locally, but for persistent uptime you may want to deploy it to a hosting platform.
Here are some good options:
- Glitch – Free hosting for Node.js apps
- Heroku – Free tier available for hosting bots
- DigitalOcean – Pay-as-you-go VPS for hosting bots 24/7
All of these have options to automatically restart your bot process if it crashes or the server restarts.
For Glitch and Heroku, you can connect your GitHub repository and it will auto-deploy your code each time you push changes.
Final Bot Features
Your basic Discord ticket bot is complete! Here are some additional features you may want to add:
- More ticket management commands like renaming, adding members, etc
- Allow users to self-close tickets by reacting
- Send ticket opening notifications to staff channels
- Add ticket timers that automatically close after x hours/days
- Allow creation of ticket transcripts as text files
- Integrate with external systems like Zendesk, Freshdesk, etc
The possibilities are endless for enhancing your ticket bot and streamlining your support workflows inside Discord. Reference the Discord.js guide for examples of other types of commands you can build.
Conclusion
Building a custom Discord ticket bot provides a sleek way for your community members to get support right within your server. With this guide, you have all the fundamentals to get started and create your own feature-packed ticketing system that caters to your unique needs.
The key takeaways from building a Discord ticket bot are:
- Use Discord.js and Node.js to interact with Discord’s API
- Listen for reactions to trigger ticket creation events
- Create dedicated ticket channels under a category
- Add commands for staff members to manage tickets
- Transcript and log conversations for record keeping
- Host your bot on a platform for continuous uptime
With a properly configured ticket bot, both your users and staff can benefit from streamlined support requests and conversations. Set one up for your Discord server today!