Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion 01-discordjs/.env-example
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
SERVERID=1234
CLIENTID=1234
TOKEN=abcd1234
TENORKEY=abcd2345
141 changes: 141 additions & 0 deletions 01-discordjs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Episode 1

In this episode, we make a new Discord bot from scratch and create a simple slash command!

## Steps to Create Your Bot!

### 1. Set Up Your Project

Create a new Node.js project and install necessary dependencies.

```sh
$ npm init
$ npm install discord.js dotenv
```

Add a property `"type": "module"` in your `package.json` file in order to use ES6 module import syntax.

### 2. Create a Discord Application

- Navigate to the [Discord Developer Portal](https://discord.com/developers/applications/) and create a new application.
- Optionally, set the application name, description, and avatar.
- Note down the "Application ID" (also known as "Client ID").

### 3. Create and Configure Your Bot

- In the Discord Developer Portal, select "Bot" from the left navigation.
- Set a name and icon for your bot.
- Note down the "Bot Token" (keep this secret).

### 4. Add Bot to a Server

- Go to your application page in the Discord developer portal.
- Navigate to "OAuth" -> "URL Generator".
- Check "application.commands" and "bot".
- Open the URL that populates at the bottom and authorize the bot to access your server.

### 5. Enable Developer Mode in Discord

- Enable "Developer Mode" under the "Advanced" settings tab on your Discord client.
- Right-click on the server icon, and select "Copy ID" to get the server ID.

### 6. Configure Environment Variables

Create a `.env` file in your project root and add your client ID, server ID, and bot token:

```plaintext
CLIENTID=1234
SERVERID=1234
TOKEN=1234
```

These environment variables are used to keep sensitive data, like your bot token, out of your code. This is especially important if you're sharing your code with others or storing your code publicly on GitHub. (Notice how `.env` is included in `.gitignore`.)

### 7. Create the bot code!

Create `bot.js` (or `index.js`) and paste this code:

```javascript
import { Client, Events, GatewayIntentBits } from 'discord.js';
import { config } from 'dotenv';

config();

// Create a new client instance
const client = new Client({
intents: [GatewayIntentBits.Guilds],
});

// When the client is ready, run this code (only once)
client.once(Events.ClientReady, readyDiscord);

// Login to Discord with your client's token
client.login(process.env.TOKEN);

function readyDiscord() {
console.log('💖');
}
```

Run to see if it works! (If you see the 💖 it's working!)

```sh
$ node bot.js
```

## 8. Create a Command

Each command should be handled in a separate JS file, there are many ways you can manage this, but I suggest putting them in a folder called commands:

```javascript
import { SlashCommandBuilder } from 'discord.js';

// Command Builder export
export const data = new SlashCommandBuilder()
.setName('choochoo')
.setDescription('Replies choo choo!');

// Execute function export
export async function execute(interaction) {
await interaction.reply('Choo choo!');
}
```

## 9. Deploy the commands

Create `deploy-commands.js` and copy the [example code](/01-discordjs/deploy-commands.js). Then run it!

```sh
node deploy-commands.js
```

You only have to do this once. If you change the command (altering descriptions, changing options, etc.), then you do need to re-run `deploy-commands.js`.

## 10. Add the code to handle the command

You also need to handle the command in bot.js, add the equivalent code:

```javascript
import * as choochoo from './commands/choochoo.js';

client.on(Events.InteractionCreate, handleInteraction);

async function handleInteraction(interaction) {
if (!interaction.isCommand()) return;
if (interaction.commandName === 'choochoo') {
await choochoo.execute(interaction);
}
}
```

Then run the bot again!

```sh
node bot.js
```

## Recap of the code elements

- `commands/choochoo.js`: Defines a simple slash command.
- `bot.js`: Handles interactions with Discord and executes commands.
- `deploy-commands.js`: Script to register slash commands with Discord API.
66 changes: 10 additions & 56 deletions 01-discordjs/bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
import { Client, Events, GatewayIntentBits } from 'discord.js';
import { config } from 'dotenv';

// Import everything the commands/choochoo.js file exports and store it inside the choochoo variable.
import * as choochoo from './commands/choochoo.js';
import * as gif from './commands/gif.js';
import * as randomwalk from './commands/randomwalk.js';
import * as roshambo from './commands/roshambo.js';

// Call the config() function on dotenv to load the environmental variables from the .env file
config();
Expand All @@ -15,75 +13,31 @@ config();
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
],
});

// Event listener that executes once when the client successfully connects to Discord
client.once(Events.ClientReady, readyDiscord);

// Login to Discord with your bot's token (stored in the .env file)
client.login(process.env.TOKEN);

// A function executed when the Discord client is ready and connected
function readyDiscord() {
console.log('💖 Logged in as', client.user.tag);
startTalking();
console.log('🚂 ', client.user.tag);
}

// Event listener for when a slash command is executed
client.on(Events.InteractionCreate, async (interaction) => {
// A function executed when the Discord client receives an interaction
async function handleInteraction(interaction) {
// Ensure interaction is a command before proceeding
if (!interaction.isCommand()) return;

// Command execution mapping
if (interaction.commandName === 'choochoo') {
await choochoo.execute(interaction);
} else if (interaction.commandName === 'gif') {
await gif.execute(interaction);
} else if (interaction.commandName === 'randomwalk') {
await randomwalk.execute(interaction);
} else if (interaction.commandName === 'roshambo') {
await roshambo.execute(interaction);
}
});

// Function that sends a message to a specific channel every 60 minutes
function startTalking() {
// Retrieve the desired channel using its ID
const channel = client.channels.cache.get('1139569830761070651');

// Send a message to the channel every 60*60*1000 milliseconds (1 hour)
setInterval(() => {
channel.send('Hello, this is your bot speaking!');
}, 60 * 60 * 1000);
}

// Event listener for when a reaction is added to a message
client.on(Events.MessageReactionAdd, (reaction, user) => {
// Retrieve the emoji used for the reaction
let emoji = reaction.emoji.name;

// If the emoji is custom, format it accordingly
if (reaction.emoji.id) {
emoji = `<:${reaction.emoji.name}:${reaction.emoji.id}>`;
}
// Event listener that executes once when the client successfully connects to Discord
client.once(Events.ClientReady, readyDiscord);

// Retrieve the channel using its ID and send a message indicating the user and emoji
const channel = client.channels.cache.get('1139569830761070651');
channel.send(`${user.username} reacted with ${emoji}`);
});
// Event listener for when a slash command is executed
client.on(Events.InteractionCreate, handleInteraction);

// Event listener for handling any received message
client.on(Events.MessageCreate, (message) => {
// If the message author is not a bot and the bot is mentioned in the message
if (!message.author.bot && message.mentions.has(client.user)) {
// Remove the bot mention from the message content
const mention = /<@.*?\s/;
const content = message.content.replace(mention, '').trim();
// Login to Discord with your bot's token (stored in the .env file)
client.login(process.env.TOKEN);

// Respond to the message
message.reply(`How does ${content} make you feel?`);
}
});
8 changes: 2 additions & 6 deletions 01-discordjs/commands/choochoo.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
// Importing modules using ES6 syntax
import { SlashCommandBuilder } from 'discord.js';

// Replies array
const replies = ['🚂🌈💖', 'Choo choo!', 'Ding! 🛎', 'Never forget this dot!'];

// Command Builder export
export const data = new SlashCommandBuilder()
.setName('choochoo')
.setDescription('Replies with a random phrase!');
.setDescription('This is a demo choo choo!');

// Execute function export
export async function execute(interaction) {
const index = Math.floor(Math.random() * replies.length);
await interaction.reply(replies[index]);
await interaction.reply('choo choo!');
}
48 changes: 0 additions & 48 deletions 01-discordjs/commands/gif.js

This file was deleted.

52 changes: 0 additions & 52 deletions 01-discordjs/commands/randomwalk.js

This file was deleted.

Loading