TL;DR
In this tutorial, you'll learn how to build an automated Discord bot with Novu. The bot will send memes from a subreddit to your Discord channel every hour β°
Novu: Open-source notification infrastructure π
Just a quick background about us. Novu is an open-source notification infrastructure. We basically help to manage all the product notifications. It can be In-App (the bell icon like you have in the Dev Community), Emails, SMSs and so on.
Let's set it up π₯
Create your project folder and run npm init -y
to add a package.json
file.
mkdir discord-bot
cd discord-bot
npm init -y
InstallΒ Novu SDK,Β Nodemon,Β Node Cron, andΒ Fast XML Parser.
npm install @novu/node fast-xml-parser node-cron nodemon
Novu enables us to send Discord messages in Node.js, Node Cron helps with scheduling tasks, Fast XML Parser for converting XML files to JSON, and Nodemon is a Node.js tool that automatically restarts the server after detecting file changes.
Create an index.js
file - the entry point to the web server.
touch index.js
Configure Nodemon by adding the start command to the list of scripts in the package.json
file. The code snippet below starts the server using Nodemon.
//ππ» In server/package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js"
},
Congratulations!π You can now start the server by using the command below.
npm start
Getting memes from Reddit π€
Copy the code below into the index.js
file.
const { XMLParser } = require("fast-xml-parser");
const parser = new XMLParser();
//ππ» Regex for retrieving memes image URL
const urlPattern = /https:\/\/i\.redd\.it[^"]*/g;
const getMemes = async () => {
const matchedUrls = [];
try {
//ππ» fetch XML data
const fetchMeme = await fetch(
"https://www.reddit.com/r/ProgrammerHumor/.rss"
);
const XMLdata = await fetchMeme.text();
//ππ» convert XML data to JSON format
const jsonObj = parser.parse(XMLdata);
const content = jsonObj.feed.entry;
//ππ» map through the memes data
const contentArray = content.map((obj) => obj.content);
contentArray.forEach((htmlString) => {
const matches = htmlString.match(urlPattern);
if (matches) {
// Add memes into an array
matchedUrls.push(...matches);
}
});
return matchedUrls;
} catch (err) {
console.error(err);
}
};
//ππ» log memes array to the console (for testing purposes)
const logMemes = async () => {
const memes = await getMemes();
console.log(memes);
};
logMemes();
The code snippet above fetches the XML data (RSS feed) from the ProgrammerHumor subreddit, converts it to JSON format using the XMLParser, and retrieves only the memes from the large amount of data returned.
Reddit to Discord using Novu πͺ β¨
Here, you'll learn how to send messages to your Discord channels withΒ NovuΒ - an open-source notification infrastructure that enables you to send in-app, SMS, chat, push, and e-mail notifications from a single dashboard.
Before we proceed, create your Discord server and right-click on the channel where you need to add the bot.
Select Edit Channel > Integrations
and Webhooks to create a new webhook URL.
Copy the Copy Webhook URL
and paste somewhere on your computer; we'll use it shortly.
Creating a Novu project
Run the code snippet below to create your Novu account.
npx novu init
Enter your application name and sign in to your Novu dashboard. The code snippet below contains the steps you need to follow after running npx novu init
.
Now let's setup your account and send your first notification
? What is your application name? Discord Bot
? Now lets setup your environment. How would you like to proceed? Create a free cloud account (Recommended)
? Create your account with: Sign-in with GitHub
? I accept the Terms and Conditions (https://novu.co/terms) and have read the Privacy Policy (https://novu.co/privacy) Yes
β Created your account successfully.
Visit the demo page, copy your subscriber ID from the page, and click the Skip Tutorial
button.
Next, activate the Discord chat channel on your Novu integrations store.
Finally, create a workflow that triggers the Chat notification.
From the code snippet above, I added a variable - {{content}}
as the Chat message content to enable us to send dynamic messages.
Remember to copy your API key from your dashboard, we'll use in the upcoming section.
Sending messages to the Discord channel
Add the following imports to the top of your index.js
file.
const { Novu, ChatProviderIdEnum } = require("@novu/node");
const novu = new Novu("<YOUR_API_KEY>");
const subscriberId = "<YOUR_SUBSCRIBER_ID>";
Create a function that attach the webhook URL to your subscriber details.
const sendChatMessage = async () => {
await novu.subscribers.setCredentials(
subscriberId,
ChatProviderIdEnum.Discord,
{
webhookUrl: "<DISCORD_WEBHOOK_URL>",
}
);
};
Finally, update the function to loop through the memes retrieved from the subreddit and send them to the Discord channel.
const sendChatMessage = async () => {
await novu.subscribers.setCredentials(
subscriberId,
ChatProviderIdEnum.Discord,
{
webhookUrl: "<DISCORD_WEBHOOK_URL>",
}
);
//ππ» gets the memes
const memes = await getMemes();
//ππ» loops through the memes
memes.forEach(async (meme) => {
//ππ» sends the meme via Novu
await novu
.trigger("discord", {
to: {
subscriberId,
},
payload: { content: meme },
})
.then((res) => console.log(res.data.data));
});
};
//ππ» execute the function
sendChatMessage();
The code snippet above gets the memes from the previous function -getMemes()
, loops through the array and sends them via Novu.
Congratulations! the memes should be displayed with your Discord channel, as shown below.
Check MEMEs every hour with Node Cron β°
Here, you'll learn how to schedule tasks with Node Cron - tiny task scheduler in pure JavaScript for Node.js based on GNU crontab.
Import the package into the index.js
file.
const cron = require("node-cron");
Then, call the sendChatMessage
function using Node Cron.
//ππ» schedules the task hourly
const hourlyTask = cron.schedule("0 * * * *", sendChatMessage);
console.log("Scheduled task to run every hour.");
The code snippet above executes the sendChatMessage
function every hour, enabling it to fetch the latest and random memes from the subreddit.
Congratulations on making it thus far!πΒ You can learn more about scheduling and automation with Node CronΒ here.
Final notes π
So far, you've learnt how to:
- convert XML data to JSON type,
- send chat messages with Novu,
- automate tasks with Node Cron,
- and build an automated Discord bot with Node.js.
Bots are computer programs designed to perform automated tasks or engage in conversations with people - and Discord bots are extremely helpful in tasks like moderation, custom commands, managing members' requests, and many more.
Today, if you have a Discord channel, you need a bot to help automate most of your moderation tasks.
The source code for this tutorial is available here:Β https://github.com/novuhq/blog/tree/main/meme-discord-bot-with-novu-reddit.
Thank you for reading!