Discord Bot Boilerplate BETA
This boilerplate is for single-tenant Discord bots (ie. installing on a single server). It also ships with a CLI tool to help you start writing your bot quickly!
This is currently in beta, and features may change quickly before the stable release. Please check back here regularly for updates. Contributions are also welcome!
Requirements
- Node.js version 16.x+
- Solid understanding of JavaScript
- A Discord account, and the Discord application installed on your computer
- Basic understanding of how Discord.js works
Introduction and Folder Structure
This boilerplate was created to help you start writing Discord bots quickly! After you run the setup below, you can either use the CLI tool to help you generate slash commands and event listeners, or you can manually create them on your own. This boilerplate uses Discord.js to help you write slash commands and event listeners. You can learn more about how it works here.
The folder structure in this boilerplate is opinionated and will help you automatically deploy your slash commands, and mount your event listeners:
/src/slashCommands
This is where your slash commands will live. You can either create files directly in this folder, or you can create folders in here to organize your code. When you run your project in dev or production mode, it will look for all JavaScript files under this directory, and it will deploy them to Discord so that they are available to your bot. You can either manually create files in here, OR you can use the CLI tool to help generate files and boilerplate code that will be saved to this directory. To learn more about how Slash commands work with Discord.js, you can read about it here.
src/events
This is where all of your event handlers will live. In this directory, you will see a list of folders that correspond to all of the events supported in Discord.js version 14. You can either manually create JavaScript files in these directories, OR you can use the CLI tool to help generate files and boilerplate code that will be saved into the event listener that you choose. JavaScript files that live in each of the event folders will receive the corresponding event from Discord. If you have multiple files in these directories, they will all receive the event. For example, all .js files that live under the src/events/messages
folder will trigger whenever a message is created, deleted, or updated in Discord. You can learn more about these events and the data your .js files will receive here.
Setting Up Your Environment
- Click the "Use This Template" button to clone this repo.
Github Use this template button
- Run
yarn
to install dependencies. - Run
npx discord-bot
to start the Discord bot CLI tool.- Using the arrow keys, select the "Set up your bot" option, and press enter. Proceed through the wizard to set up your bot's environment variables. If you have any difficulty finding keys and secrets, please check out the environment variable reference section. If you'd like to set this up without using the CLI tool, you can reference the manual setup section.
Discord Bot CLI tool
- If you didn't install your bot in the previous step, run
npx discord-bot
and select the "Install the bot on your Discord Server" option. Open the link in your browser, and follow the steps, and your bot will be added to your server! - Reference the CLI Commands section below to start writing commands and event handlers.
Environment Variable Reference
DISCORD_API_VERSION
Currently defaulted to 10. If you wish to override this, please update this in your .env
file. For more information about supported API versions, you can check the Discord API docs here.
DISCORD_APP_ID
After you create an application in the Discord Developer Portal, you can find your App ID in the "General Information" tab:
Discord Developer Portal App ID
DISCORD_BOT_TOKEN
Navigate to the "Bot" tab. If you haven't set up your application as a bot yet, click the "Add Bot" button:
Discord Add Bot
Click the "Reset Token" button, to generate a new bot token. This is what you will use for the environment variable. Also, make sure that "Presence Intent" is toggled on at the bottom of the page:
Discord Bot Token
DISCORD_GUILD_ID
In the Discord app, make sure that "Developer Mode" is turned on in your settings:
Discord Developer Mode
Next, right click on the server that you want to deploy your bot to. Click on the "Copy ID" button. Use this as your environment variable.
Discord Guild ID
The Client
When you create slash commands and event listeners with the CLI, you'll notice that a client
is imported into your file. You can use this to handle everything from fetching guild details, fetching a list of users and channels, responding to the user's input, sending a user a private direct message, and much more. For common usecases, see the common patterns section.
CLI Commands
Set up your bot
This is the wizard that will set up your project's .env files. The environment variables are used to help your bot communicate with your Discord server, listen for commands, and receive events!
Install the bot on your Discord server
If you need to run the install step again, you can use this to add your bot to your Discord server.
Run the bot in dev mode
You can use this to start your bot. This will deploy your commands, and listen for events. As long as your bot is installed on your server and your bot is running, you will receive events from your Discord server! You can also run dev mode without the CLI tool by running yarn dev
.
Create a slash command
Slash commands let you define "actions" that users can interact with. An example of a slash command might be something like:
- A user types
/hello
- The bot responds with
World!
In the CLI tool, the "Create a slash command" option will walk you through a series of steps to create your own. It will ask you to name your command, give it a description, and optionally, add some arguments such as a string, a user, a channel, a role, etc. Once you have followed the steps in the wizard, the CLI will generate a skeleton command in src/slashCommands/[commandName].js
. You will then be able to modify this file to add the functionality you want! To learn more about what you can do in slash commands, check out the common patterns section.
Create an event handler
Event handlers let you execute code when a specific event happens. For example, when a user sends a message, adds an emoji reaction, changes their name, etc. You can reference the full list below, and when you can expect them to trigger.
In the CLI tool, the "Create an event handler" option will let you select from a list of supported events. You will be asked to give it a name, and a file will be automatically created with some boilerplate code inside of src/events/[eventName]
. You can now modify this code to add the functionality that you want! For a full list of supported methods and data structures, you can reference the events in the official Discord.js documentation.
Supported Event Handlers
Common
Messages
Triggers when a message is created, deleted, deleted in bulk, or updated.
Receives:
message: Message
action: (created
, deleted
, deleteBulk
, updated
)
Example:
1const { client } = require('../../configuration/bot');
2
3// Sample: If user sends 'ping' in a channel, the bot will respond with 'Pong'
4module.exports = async (message, action) => {
5 try {
6 if (message.author.bot) return;
7
8 if (message.content.toUpperCase() === 'PING') {
9 const channel = await client.channels.fetch(message.channel.id);
10
11 channel.send({
12 content: 'Pong'
13 });
14 }
15
16 } catch(e) {
17 console.error(`Ping pong error: ${e}`);
18 }
19};
Roles
Triggers when a role is created, deleted, or updated.
Receives:
role: Role
action: (created
, deleted
, updated
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (event, action) => {
4 try {
5 const roleId = event?.id;
6 console.log(`Role ${action} event for role ID: ${roleId}`);
7 } catch(e) {
8 console.error(`Role event error: ${e}`);
9 }
10};
Channels
Triggers when a channel is created, deleted, or updated.
Receives:
guildChannel: GuildChannel
action: (created
, deleted
, updated
)
Example:
1const { ChannelType } = require('discord.js');
2const { client } = require('../../configuration/bot');
3
4module.exports = async (guildChannel, action) => {
5 try {
6 const channelType = ChannelType[guildChannel.type];
7
8 switch(channelType) {
9 case 'GUILD_TEXT':
10 console.log('New text channel event.');
11 break;
12 case 'GUILD_VOICE':
13 console.log('New voice channel event.');
14 break;
15 case 'GUILD_CATEGORY':
16 console.log('New organizational category event.');
17 break;
18 case 'GUILD_NEWS':
19 console.log('New news channel event.');
20 break;
21 case 'GUILD_NEWS_THREAD':
22 console.log('New news channel thread event.');
23 break;
24 case 'GUILD_PUBLIC_THREAD':
25 console.log('New text channel thread event.');
26 break;
27 case 'GUILD_PRIVATE_THREAD':
28 console.log('New text channel private thread event.');
29 break;
30 case 'GUILD_STAGE_VOICE':
31 console.log('New stage channel event.');
32 break;
33 case 'GUILD_DIRECTORY':
34 console.log('New guild directory event.');
35 break;
36 case 'GUILD_FORUM':
37 console.log('New guild forum event.');
38 break;
39 default:
40 console.log(`Unknown channel event for type: ${channelType}`);
41 }
42 } catch(e) {
43 console.error(`Channel event error: ${e}`);
44 }
45};
Message Reactions
Triggers when an emoji reaction(s) is added or removed from a message.
Receives:
messageReaction: MessageReaction
action: (add
, remove
, removeAll
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (messageReaction, action) => {
4 try {
5 const messageId = messageReaction?.message?.id;
6 console.log(`Message reaction ${action} for message ID: ${messageId}`);
7 } catch(e) {
8 console.error(`Message reaction event error: ${e}`);
9 }
10};
User Join / Leave
Triggers when a user joins or leaves your server.
Receives:
guildMember: GuildMember
action: (join
, leave
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (guildMember, action) => {
4 try {
5 const userId = guildMember?.user?.id;
6 console.log(`Guild ${action} event for user ID: ${userId}`);
7 } catch(e) {
8 console.error(`User join / leave event error: ${e}`);
9 }
10};
Threads
Triggers when a thread is created, deleted, or updated.
Receives:
threadChannel: ThreadChannel
action: (create
, delete
, update
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (threadChannel, action) => {
4 try {
5 const threadId = threadChannel?.id;
6 console.log(`Thread ${action} event for thread ID: ${threadId}`);
7 } catch(e) {
8 console.error(`Thread event error: ${e}`);
9 }
10};
User Updates
Triggers when a guild member updates. This can happen for a number of different reasons such as:
- A role added / removed from the guild member
- Guild member's nickname updated
- Guild member's server avatar updated
Receives:
guildMember: GuildMember
action: (update
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (guildMember, action) => {
4 try {
5 const userId = guildMember?.user?.id;
6 console.log(`User ${action} event for user ID: ${userId}`);
7 } catch(e) {
8 console.error(`User update event error: ${e}`);
9 }
10};
Other Events
Bans
Triggers when a guild member receives a ban, or if a ban is removed.
Receives:
guildBan: GuildBan
action: (add
, remove
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (guildBan, action) => {
4 try {
5 const userId = guildBan?.user?.id;
6 console.log(`${action} event for user ID: ${userId}`);
7 } catch(e) {
8 console.error(`Ban event error: ${e}`);
9 }
10};
Bot Ready
Triggers when the bot is ready to receive commands.
Receives:
client: Client
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (event) => {
4 try {
5 console.log(`Bot ready event ID ${event?.readyAt}`);
6 } catch(e) {
7 console.error(`Bot read event error: ${e}`);
8 }
9};
Emojis
Triggers when an emoji is created, deleted, or updated.
Receives:
guildEmoji: GuildEmoji
action: (create
, delete
, update
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (guildEmoji, action) => {
4 try {
5 const emojiName = guildEmoji?.name;
6 console.log(`Emoji :${emojiName}:, ${action}`);
7 } catch(e) {
8 console.error(`Emoji event error: ${e}`);
9 }
10};
Guild Join / Leave
Triggers when the bot is installed or removed from a guild.
Receives:
guild: Guild
action: (create
, delete
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (event, action) => {
4 try {
5 const guildId = event?.guild?.id;
6 console.log(`Guild ${action} event for guild ID: ${guildId}`);
7 } catch(e) {
8 console.error(`Guild join / leave event error: ${e}`);
9 }
10};
Guild Scheduled Events
Triggers when a guild scheduled event is created, deleted, or updated.
Receives:
guildScheduledEvent: GuildScheduledEvent
action: (create
, delete
, update
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (guildScheduledEvent, action) => {
4 try {
5 const eventId = guildScheduledEvent?.id;
6 console.log(`Guild Scheduled Event ${action} for guild ID: ${eventId}`);
7 } catch(e) {
8 console.error(`Guild scheduled event error: ${e}`);
9 }
10};
Guild Scheduled Event Members
Triggers when a user subscribes or unsubscribes from a guild scheduled event
Receives:
guildScheduledEvent: GuildScheduledEvent
action: (subscribe
, unsubscribe
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (guildScheduledEvent, action) => {
4 try {
5 const userId = guildScheduledEvent?.user?.id;
6 console.log(`Guild Scheduled Event Members ${action} for guild ID: ${userId}`);
7 } catch(e) {
8 console.error(`Guild scheduled event members error: ${e}`);
9 }
10};
Guild Update
Triggers when a guild is updated (such as a name change)
Receives:
guild: Guild
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (event) => {
4 try {
5 const guildId = event?.guild?.id;
6 console.log(`Guild Update Event for Guild ID: ${guildId}`);
7 } catch(e) {
8 console.error(`Guild update event error: ${e}`);
9 }
10};
Invites
Triggers when a guild invite is created or deleted
Receives:
invite: Invite
action: (create
, delete
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (invite, action) => {
4 try {
5 const guildId = invite?.guild?.id;
6 console.log(`Invite Event ${action} for Guild ID: ${guildId}`);
7 } catch(e) {
8 console.error(`Invite event error: ${e}`);
9 }
10};
Ping
Triggers when a ping event is emitted. More information here.
Receives:
Event:
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (event) => {
4 try {
5 console.log(`Ping event received`);
6 } catch(e) {
7 console.error(`Ping event error: ${e}`);
8 }
9};
Shards
Triggers when a shard's websocket is ready, disconnected, errors, is reconnecting, and resumed.
Receives:
shardDetails:
1{
2 shardId?: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number),
3 unavailableGuilds?: [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set),
4 event?: [CloseEvent](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent),
5 error?: [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error),
6 replayedEvents?: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number),
7}
action: (ready
, disconnect
, error
, reconnecting
, resume
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (
4 {
5 shardId,
6 unavailableGuilds,
7 event,
8 error,
9 replayedEvents
10 },
11action) => {
12 try {
13 console.log(`Shard ${action} event for role ID: ${shardId}`);
14 } catch(e) {
15 console.error(`Shard event error: ${e}`);
16 }
17};
Stages
Triggers when stage is created, deleted, or updated
Receives:
stageInstance: StageInstance
action: (create
, delete
, update
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (stageInstance, action) => {
4 try {
5 const stageId = stageInstance?.id;
6 console.log(`Stage ${action} event for stage ID: ${stageId}`);
7 } catch(e) {
8 console.error(`Stage event error: ${e}`);
9 }
10};
Stickers
Triggers when sticker is created, deleted, or updated
Receives:
sticker: Sticker
action: (create
, delete
, update
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (sticker, action) => {
4 try {
5 const stickerId = sticker?.id;
6 console.log(`Sticker ${action} event for sticker ID: ${stickerId}`);
7 } catch(e) {
8 console.error(`Sticker event error: ${e}`);
9 }
10};
Thread Members
Triggers when a guild member(s) is added or removed from a thread
Receives:
sticker: Sticker
action: (create
, delete
, update
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (oldMembers, newMembers, action) => {
4 try {
5 if (Array.isArray(newMembers)) {
6 const threadMemberIds = newMembers?.map(user => user?.id);
7 console.log(`Thread member ${action} event for user IDs: ${threadMemberIds}`);
8
9 } else {
10 const threadMemberId = newMembers?.user?.id;
11 console.log(`Thread member ${action} event for user ID: ${threadMemberId}`);
12 }
13 } catch(e) {
14 console.error(`Thread member event error: ${e}`);
15 }
16};
Typing Start
Triggers when a user starts typing in a channel
Receives:
typing: Typing
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (typing) => {
4 try {
5 const userId = typing?.user?.id;
6 console.log(`Typing start event for user ID: ${userId}`);
7 } catch(e) {
8 console.error(`Typing start event error: ${e}`);
9 }
10};
User Presence
Triggers when a guild member's presence (e.g. status, activity) has changed
Receives:
oldPresence: Presence
newPresence: Presence
action: (create
, delete
, update
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (presence) => {
4 try {
5 const userId = presence?.user?.id;
6 console.log(`User presence update for user ID: ${userId}`);
7 } catch(e) {
8 console.error(`User presence event error: ${e}`);
9 }
10};
Voice
Triggers when a guild member changes voice state - e.g. joins/leaves a channel, mutes/unmutes.
Receives:
oldState: VoiceState
newState: VoiceState
action: (create
, delete
, update
)
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (oldState, newState) => {
4 try {
5 const userId = newState?.member?.id;
6 console.log(`Voice state event for User ID: ${userId}`);
7 } catch(e) {
8 console.error(`Voice state event error: ${e}`);
9 }
10};
Webhooks
Triggers when a channel has its webhooks changed
Receives:
channel: TextChannel || NewsChannel || VoiceChannel
Example:
1const { client } = require('../../configuration/bot');
2
3module.exports = async (channel) => {
4 try {
5 const channelId = channel?.id;
6 console.log(`Webhook update event for Channel ID: ${channelId}`);
7 } catch(e) {
8 console.error(`Webhook update event error: ${e}`);
9 }
10};
Common Patterns
Responding to a user's interaction in a slash command
1const { SlashCommandBuilder } = require('@discordjs/builders');
2
3module.exports = {
4 data: new SlashCommandBuilder()
5 .setName('hello')
6 .setDescription(
7 'Will respond with "world"'
8 ),
9
10 async execute(interaction) {
11 try {
12 const { user } = interaction;
13 // Send a direct message to the user
14 await user.send({ content: `World!` });
15
16 // Respond in the channel the user sent the message in
17 await interaction.reply(`World!`);
18 } catch (e) {
19 console.log(`There was an error with the 'hello' command: ${e}`);
20 }
21 },
22};
In the example above, you can see we are deconstructing the user from the interaction object. We then send the user a direct message with the reply()
method, and then we send a response to the channel that the slash command was used in with the reply()
method.
This interaction object is what our bot receives when a user uses a slash command. There are many other methods and parameters available. For a full list, you can check out the Discord documentation.
Editing a bot's response in a slash command
1const { SlashCommandBuilder } = require('@discordjs/builders');
2const wait = require('node:timers/promises').setTimeout;
3
4module.exports = {
5 data: new SlashCommandBuilder()
6 .setName('hello')
7 .setDescription(
8 'Will respond with "world"'
9 ),
10
11 async execute(interaction) {
12 try {
13 const { user } = interaction;
14
15 // Respond in the channel the user sent the message in
16 await interaction.reply(`World!`);
17 // Wait four seconds
18 await wait(4000);
19 // Edit the reply
20 await interaction.editReply('World (edited)!');
21 } catch (e) {
22 console.log(`There was an error with the 'hello' command: ${e}`);
23 }
24 },
25};
Sending a message to a channel after an interaction event
1const { client } = require('../../configuration/bot');
2
3// Sample: If user sends 'ping' in a channel, the bot will respond with 'Pong'
4module.exports = async (message, action) => {
5 try {
6 if (message.author.bot) return;
7
8 if (message.content.toUpperCase() === 'PING') {
9 const channel = await client.channels.fetch(message.channel.id);
10
11 channel.send({
12 content: 'Pong'
13 });
14 }
15
16 } catch(e) {
17 console.error(`Ping pong error: ${e}`);
18 }
19};
Responding to a message with some text and an action button from an interaction event
1const { client } = require('../../configuration/bot');
2const { ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
3
4// Sample: If user sends 'ping' in a channel, the bot will respond with 'Pong'
5module.exports = async (message, action) => {
6 try {
7 if (message.author.bot) return;
8
9 if (message.content.toUpperCase() === 'PING') {
10 const channel = await client.channels.fetch(message.channel.id);
11
12 const button = new ActionRowBuilder()
13 .addComponents(
14 new ButtonBuilder()
15 .setLabel('Click Me!')
16 .setURL('https://stackfive.io')
17 .setStyle(ButtonStyle.Link),
18 );
19
20 channel.send({
21 content: 'Pong',
22 components: [button]
23 });
24 }
25
26 } catch(e) {
27 console.error(`Ping pong error: ${e}`);
28 }
29};
Discord Bot Button Example
Changing a user's server nickname from a slash command
1const { client } = require('../configuration/bot');
2const { SlashCommandBuilder } = require('@discordjs/builders');
3
4module.exports = {
5 data: new SlashCommandBuilder()
6 .setName('rename')
7 .setDescription(
8 'Will rename you'
9 )
10 .addStringOption((option) =>
11 option
12 .setName('new-name')
13 .setDescription('What you would like to change your nickname to')
14 .setRequired(true)),
15
16 async execute(interaction) {
17 try {
18 const newName = interaction.options.getString('new-name');
19 const guild = await client.guilds.fetch(process.env.DISCORD_GUILD_ID);
20 const user = await guild.members.fetch(interaction?.user?.id);
21
22 await user.setNickname(newName);
23
24 // Respond in the channel the user sent the message in
25 await interaction.reply({ content: `Your username has been updated!`, ephemeral: true });
26 } catch (e) {
27 console.log(`There was an error with the 'hello' command: ${e}`);
28 }
29 },
30};
NOTE: This command will fail on server administrators (DiscordAPIError[50013]: Missing Permissions
). Bots can not change nicknames of server admins.
Discord Bot Command Example
Other Examples
There are many other patterns and responses you can use. For more examples, you can check out the following Discord.js samples:
Manual Setup (NOT RECOMMENDED)
- Run
yarn
to install dependencies. - Create a blank
.env
file in the root of this project, and copy the contents from the.env.example
file into it. These are the environment variables we will be using. - Navigate to the Discord developer portal and sign in.
- Click on the
New Application
button, and add a name for your Discord bot. - Click on the
Bot
button in the navigation on the lefthand side of the page. - Click on the
Add Bot
button, and thenYes, do it!
in the pop up modal. Note: If you application name is not unique, you will receive an error in this step. You can change your application name in theGeneral Information
tab to something unique, and then try this step again. - If you want your bot to be only privately accessible, make sure you turn off the
Public Bot
toggle. This can be changed later. - Make sure that the
Presence Intent
,Server Members Intent
, andMessage Content Intent
toggles are all turned on, andRequires OAauth2 Code Grant
is turned off. - Click the
Save Changes
button at the bottom of the page. - Scroll to the top of the page, and click on the
Reset Token
button underneath the bot icon, and then clickYes, do it
in the pop up modal. This will generate a secret token that will only be displayed once. Copy and paste this into the.env
file you created in the root of your project for theDISCORD_BOT_TOKEN
variable. - In the lefthand navigation, click on the
OAuth2
button. - Copy the
Client ID
value, and paste it as theDISCORD_APP_ID
value in your.env
file. - In your Discord application, click the
+
icon in your server list (theAdd a Server
button). Click onCreate My Own
,For me and my friends
, add a name, and then clickCreate
. - You should now see your newly created Discord server in your server list. Right click on it, and click
Copy ID
(at the bottom of the list). If you don't see this option, you may need to enable Developer Mode. See instructions below. - In your
.env
file, paste your Discord server ID into theDISCORD_GUILD_ID
parameter. Note: The discord.js docs will refer to "Servers" as "Guilds". - Follow the bot installation steps below to add your newly created bot to your new Discord server!
Installing Your Bot
Run npx discord-bot
and select the "Install the bot on your Discord Server" option. Open the link in your browser, and follow the steps, and your bot will be added to your server!
Important Notes
Your boilerplate server MUST be running in order for your commands to register. Your bot will not be able to receive interactions, or send responses if your server is not running. Also note, your bot configuration can only run on one server at a time. If you are doing active development and you have deployed your bot somewhere, it is recommended that you create a separate bot application for production and development to avoid collisions.
Deployment
You can deploy your bot anywhere you'd like. For the sake of simplicity, you can easily deploy to Heroku. Just make sure you set up all of your environment variables on your Heroku server when you deploy your bot, and everything else should work as expected.
Enable Discord Developer Mode
If you need to enable Discord developer mode, follow these steps:
- Open up the Discord app
- Click on the settings cog in the bottom left corner
- Go to Advanced (near the bottom)
- Toggle
Developer Mode
on
Contributing
PRs are welcome. A contributing guide will be released soon.
In Progress
- Testing
- Additional CLI utilities to add more helpers to commands and events such as button builders, modal builders, etc.
- More examples
- Typescript boilerplate
Contact
We'd love to hear from you! Please feel free to email us at hello@stackfive.io, or reach out to us on Twitter.