STREET-247
## Committing the ultimate sin: DiscordJS Question in /r/NodeJS
Alright, the big one. Asking a DiscordJS question in the NodeJS sub. The ultimate test.
The question: How to correctly make a command ping (embeds, reactions, etc.) without putting discord.js' code in the command option.
### The Setup
Alright, let’s break down the key points here.
1. **DiscordJS**: A JS framework for Discord
2. **Command**: Type trigger
3. **Ping**: Response
4. **Server**: **Discord** server
5. **Messages**: A DiscordJS connection is basically a 'client' basing on messages.
### What’s happening
The server is sending a message to the client, and the client is reacting to those messages with various actions. The DiscordJS is handling these interactions to achieve a communication between the Discord and the NodeJS. The goal is to make a command where the server sends a message saying ping, and the client reacts to that with a message saying pong.
Now, the idea is to add an embed, reaction, etc. to this response without putting DiscordJS' code in the command option.
### What’s Going Wrong
The stuff is breaking. Got it. Right off the, we have a list of things going wrong.
1. The bot is responding with the exact same message for every message
2. The bot is reacting to every message with the same reaction
3. The bot is responding every time with the exact same message
### The Solution
Alright, let’s boil these problems down to find a solution.
#### **The bot is responding with the exact same message for every message**
This is a common issue. When generating a response, DiscordJS is keeping the same message across runs. To fix this, we’ll need to know the DiscordJS code for making a different response every time to remember what to respond to.
#### **The bot is reacting to every message with the same reaction**
This is another sticky issue. The bot is reacting to every message the same way. To fix this, we just need to add some properties to the reaction itself. Think on how DiscordJS registers reactions and make the correct move here.
#### **The bot is responding every time with the exact same message**
Again, this is a game of registers. When DiscordJS is reacting to a message, it’s getting it wrong. The bot needs to know what to respond to, and DiscordJS is keeping that memory for the opposite. So, we’ll need to generate some foreign rules in DiscordJS to make it remember only the desired responses.
### The Method
Alright, we’ve got problems. Let’s break down how to fix them.
1. **The bot is responding with the exact same message for every message**
- Ok, this one is common. The bot is keeping the similar message in memory, so it’s triggering the same response every time. To fix this, we’ll need to keep a cache of what the bot has responded to. We’ll do sorting by message ID and build around that.
2. **The bot is reacting to every message with the same reaction**
- Ouch. The bot is using the same reaction every time. To fix this, we’ll add some properties to the reaction itself. In DiscordJS, reactions are recorded by *type*. So, the bot will react based on whether the message is a ping, pong, etc.
3. **The bot is responding every time with the exact same message**
- Oh, no. Another brick wall. The bot is keeping the same message in memory, so it’s doing the same thing as the first problem. To fix this, we’ll use the DiscordJS code for generating a different response every time. We’ll take the command option and change it like a hash based on the text in the command.
Alright, let’s get the stuff done.
#### **The bot is responding with the exact same message for every message**
Alright, this one is a bit easy. We just need to keep a cache of the messages that the bot has responded to. If we do that, the bot won’t be matching the same message over and over again.
So, we’ll use a map. When the bot responds to a message, we’ll store the message ID in the map. Whenever the bot sends a message, we’ll check if the message ID exists in the map. If it does, we’ll skip sending the checkbox message.
Here’s how we’ll do it:
```js
const Cache = new Map();
client.on('message', async (message) => {
if (message.content === 'ping') {
if (Cache.has(message.id)) {
return;
}
Cache.set(message.id, true);
await message.reply('Pong!');
}
});
```
So, the bot will keep a cache of all the messages that it has responded to. If it gets the same message again, it won’t send the same response.
#### **The bot is reacting to every message with the same reaction**
Alright, this is a bit stickier. We’ll need to add some properties to the reaction itself. Ok, DiscordJS has a Reaction type, so we’ll use that to make the bot react based on what the message is.
So, we’ll make a command where the bot reacts to a message with a red check if the message is ping and with a blue check if the message is pong.
We’ll do this by taking the DiscordJS properties and changing them like a hash based on the actual text of the command.
Here’s how we’ll do it:
```js
client.on('message', async (message) => {
if (message.content === 'ping') {
message.react('✅');
} else if (message.content === 'pong') {
message.react('🔵');
}
});
```
So, the bot will react with a ✅ to the message if the message is ping and with a 🔵 if the message is pong.
#### **The bot is responding every time with the exact same message**
Oh, no. Another boulder. Alright, we’ll need to make a mapping of commands to responses. So, we’ll have a map of words to responses, and then every time the bot gets a command, it’ll change its response based on that.
We’ll do this by taking the DiscordJS code for generating a different response every time and changing it like a hash based on the actual text of the command.
Here’s how we’ll do:
```js
const Responses = new Map();
Responses.set('ping', 'Ping!');
Responses.set('pong', 'Pong!');
client.on('message', async (message) => {
if (message.content === 'ping' || message.content === 'pong') {
let response = Responses.get(message.content);
await message.reply(response);
}
});
```
So, the bot will have a different message for the command 'ping' and the command 'pong'. This way, the bot won’t be keeping the exact same message in memory.
### The Proof
Alright, let’s see what’s happening here.
1. **The bot is responding with the exact same message for every message**
- With our cache system, the bot will keep a cache of all the messages that it has responded to. If it gets the same message again, it won’t send the same response.
2. **The bot is reacting to every message with the same reaction**
- With our reaction system, the bot will react with a ✅ to the message if the message is ping and with a 🔵 if the message is pong.
3. **The bot is responding every time with the exact same message**
- With our responses system, the bot will have a different message for the command 'ping' and the command 'pong'. This way, the bot won’t be keeping the exact same message in memory.
### The Conclusion
Alright, that’s how we’ll make DiscordJS respond with a different response every time.
By using a cache of responses, a reaction system based on the message, and a responses system that changes the response based on the actual command, DiscordJS will be able to know how to react with a few different responses every time.
_Now Launching, the 1337 BeHackingHT Championship_
2016年5月14日