Create a Discord Bot that Automates Secret Messages with Node.js

Before Starting

  • Courier Hacks 1st Place: Top submission for use for notifications and demonstration of proper app-to-user notifications with the Courier API will receive $1000 via Zelle or PayPal.
  • Courier Hacks 2nd Place: 2nd Place submission for use for notifications and demonstration of proper app-to-user notifications with the Courier API will receive the Apple AirPods Pro.
  • Public Favorite: Public favorite winner will receive a Keychron Keyboard.
  • Runners-Up: Runners-up submissions will receive a Hydro Flask.

What is Going On?

Recap

What’s Next:

Let’s Build

Pre-reqs:

  • Admin access to a Discord server
  • A cool undercover Agent name for our Discord bot
  • Optional: a cool undercover Agent profile picture for our Discord bot

Part 1: Set Up Node.js Project

  • Create a new project folder.
  • Create three new files: “index.js”, “.env”, and “.gitignore”.
  • Install dotenv npm package to store variables: npm install dotenv --save
  • Import and configure dotenv by adding to top of index.js: require("dotenv").config();
  • Similarly, install node-fetch npm package to make API calls: npm install node-fetch@2
  • Import and configure node-fetch by adding to top of index.js: const fetch = require("node-fetch");

Part 2: Create a Discord Bot

  • Sign up for (or log into) Courier >
  • Open Discord provider in Channels. Here we will need our Discord bot token to continue.
  • In order to access a Discord bot token, we’ll create a Discord application and add a Discord bot.
  • Click on “New Application” within the Discord Developer Dashboard.
  • Type the app’s name and click “Create”.
  • In the left menu, open the “Bot” page and click “Add Bot”. We can update the icon and username (bot icon file can be found in the GitHub linked above).
  • Once the bot has been created, copy the bot token provided and paste it in Courier (make sure to keep this token private).
  • We will need to give this application permission to post as the bot within our server. Check out the Bot permissions documentation.
  • Within the application, head over to OAuth2 and click on URL generator
  • Select the bot scope
  • Select the following permissions: View Channels, Send Messages, and Read Message History
  • Go to the generated URL below. This URL will invite the bot to the server and authorize it with the permissions chosen.
  • On Discord, click on User Settings (next to username on the bottom left). Access the Advanced settings page and enable Developer Mode âś….
  • Back in the Discord server, right click on the channel and copy the channel ID (bottom of list). Add this as the value of channelID in the .env file within the project and save it as a variable within the index.js file:
1const channelID = process.env.channelID

Part 3: Send Messages

  • Create a new notification within the Notification Designer
  • Add the Chat notification channel with Discord as the provider
  • Select on the Chat channel on the right to edit the message
  • Write and publish the message. We need to create a clear message that will indicate to our civilians how to escape. Our message will be: Run while you can. You can find shelter here: https://discord.com/invite/courier.
  • Copy the notification template ID from the notification’s settings and add it as the value of templateID in the .env file within the project and save it as a variable within the index.js file:
const templateID = process.env.templateID
  • Create a test event and replace the channel_id in the JSON with the channel_id we received from Discord earlier.
{     "courier": {},
"data": {},
"profile": {
"discord": {
"channel_id": "768866348853383208"
}
},
"override": {}
}
  • Test a message to ensure that the Discord provider integration is working correctly.
  • Replace the message with a variable {secretMessage} so that, later, we can edit the message from our code directly.

Part 4: Encrypt Message with the Morse API

  • Create an asynchronous function called encryptMessage(), which takes originalMessage as a parameter. This function will call the Morse API, which will allow us to translate any message from English to Morse code. The enemy will have to spend more time and resources into decrypting our messages, which will give our civilians time to escape from the server.
async function encryptMessage(originalMessage) {
}
  • Let’s define the GET API call options:
const morseOptions = {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
};
  • We need to attach the originalMessage function parameter to the Morse API endpoint:
const morseEndpoint = "https://api.funtranslations.com/translate/morse.json?text="+originalMessage
  • We need to be able to access the translation from this API call in the body of the Courier API call. To call the API, we can use node-fetch as we did before.
  • Create a variable called morseResponse, which will hold the entire response from this call.
  • Convert the JSON object into a JavaScript object morseResponseJSON so that we can read it within our code.
  • Get the translated message out of that object and save it in a new variable called encryptedMessage.
  • Return encryptedMessage so that we can call this function to access it elsewhere.
const morseResponse = await fetch(morseEndpoint, morseOptions);
const morseResponseJSON = await morseResponse.json();
const encryptedMessage = morseResponseJSON.contents.translated;
console.log(encryptedMessage);
return encryptedMessage;

Part 5: Automate Messages

  • Create a new asynchronous function called runDiscordAutomation(), which will call the encryptMessage() function to translate a message and use the Courier API to automatically send messages to the enemy Discord server everyday.
async function runDiscordAutomation() {}
  • Before we can run our message through the Morse translation API, we need to ensure that it is in the correct format, with all spaces converted into their URL encoding, %20 as shown below. We can call encryptMessage() with originalMessage as a parameter to translate it. encryptedMessage will evaluate as the translated message.
const originalMessage = "run%20while%20you%20can%20you%20can%20find%20shelter%20here";
const encryptedMessage = await encryptMessage(originalMessage);
  • Add the link to the safe server in the notification template within the designer: “https://discord.com/invite/courier”
  • Let’s define the Courier Automation endpoint and options. Here we will need access to our Courier API Key, which can be found within the Courier Settings page. Save the first value in the .env file as apiKey and access it in this file as process.env.apiKey.
const automationsEndpoint = "https://api.courier.com/automations/invoke"  const courierOptions = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: 'Bearer ' + process.env.apiKey
},
body: JSON.stringify({
//next steps
}),
};
  • The body object within the options will encompass two objects: automation and data
body: JSON.stringify({
"automation": {
},
"data": {
}
}),
"automation": {
"steps": [],
},
  • Each step will need to be defined with two objects: the type of action (send, delay, cancel, etc.) and message. The message consists of the notification template ID (we saved this in the .env file earlier) and information about where this message is being sent. A Discord message requires either a user_id or a channel_id. In order to reach as many innocent civilians as possible, as quickly as possible, we will directly send messages in a channel.
  • This is what the send and delay steps would look like:
{
"action": "send",
"message": {
"template": templateID,
"to": {
"discord": {
"channel_id": process.env.channelID
}
}
}
},
{
"action": "send",
"duration":"1 day"
},
  • The data object would need to contain the encryptedMessage:
"data": {
"secretMessage": encryptedMessage
}
  • Learn more about sending to a channel via Courier >
  • For testing purposes, it’s easier to either remove 1 delay step or keep it at a short period like 1 minute
  • Finally, we can use node-fetch again to call the Automations API and trigger this automation
fetch(automationsEndpoint, courierOptions)    .then((response) => response.json())    .then((response) => console.log(response))    .catch((err) => console.error(err));

Conclusion

Quick Links

--

--

Courier is the fastest way for developers to build notifications for their apps. With one API and easy-to-use UI trigger multi-channel notifications at scale.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Courier.com

Courier is the fastest way for developers to build notifications for their apps. With one API and easy-to-use UI trigger multi-channel notifications at scale.