Most people are familiar with the Discord bot API. You create a “bot user”, and you use the Discord API to send and receive messages using that bot. Users can choose to add a bot with very little permissions to their server, or make the bot administrator entirely. The Discord bot API is very safe as a) you are not giving access to your user account and all your messages, instead you are giving access just to messages in a particular server and b) you can give access to only certain things, such as reactions or images in a server and c) you can revoke that access any time you want. But there two issues with the bot API. One is that only server admins can add bots, and even if you managed to get into a private Discord server you still can’t do things with the messages as your bot user has to be added by an admin for you to get access. Another is that the bot API cannot control your user account details, such as profile picture, username, etc. To deal with these issues, Discord came up with a new solution. The OAuth2 API. But even if you finally managed to get an access token after the entire auth flow, their API is not very user-friendly, in my opinion.
So what is the solution? Well, many people don’t know this, but the Discord Bot API doesn’t actually check if you’re a bot before sending the message, or updating the profile picture. The bot API is the same thing that the Discord web app, and the Discord mobile app use. But how is that possible, you ask. You need to authenticate each request to the Bot API with a bot token, and that can only be gotten by going to the Discord Developers Platform and signing up for a bot user. Well, that’s not exactly right. You see, Discord creates a “bot token” for each user on the platform, by encrypting their username and password with a random key. And that token is used by the Discord application to essentially send a message on your behalf. And we can use that token to basically turn your Discord account into a bot account — without people realizing it either!
Getting your “Bot Token”
Go to the Discord web application. If you are on the mobile or desktop version, sorry. This is not going to work. Once you are on the application, press F12 on your keyboard. This should open up a weird screen — That’s the debug screen inside Chrome. Press the two arrows and click on “Application”.
Oh yeah. They show you the warning about not pasting anything in there. Don’t worry! I’m not going to ask you to type anything. After you click on “Application”, click on “Local Storage” in the left pane and open the “https://discord.com” storage cache.
Now, search for “token” in the Filter bar near the top. Nothing should show up. Don’t worry! Click on the small tablet icon near the top left.
After that turns blue, your token should hopefully show up!
Copy that! We will be calling that YOUR_USER_TOKEN for the rest of this tutorial.
Actually building something
To get started, install the latest version of NodeJS (16+ as off this article).
Next, open your terminal. This is called “Command Prompt” on Windows and “Terminal” on Mac and Linux. Enter the following commands (we’ll actually be installing an older version of discord.js because the latest version doesn’t work well with this):
npm init (keep pressing enter)
npm i -g nodemon
npm i discord.js@11
After that, open Visual Studio Code (or any other code editor that you prefer). Don’t close the Terminal. We will need it later. Open the folder “Documents/discord-bot” (different file paths for each operating system). You should see two files, package.json and package-lock.json already existing. If you don’t, you’ve probably opened the wrong folder.
Next, create a file called
index.js in the same folder. Type in the following code (be sure to replace YOUR_USER_TOKEN with the actual token):
Line 1–3: Importing the Discord.js module and creating two new client objects
Line 5: Logging in using your user token
Line 7–9: Waiting till the client has logged in and printing your username to the console
Go back to your terminal and type the following command:
It should print out your username! Cool, right?
Now, this looks really simple, but this is just logging in right? I bet reading messages is going to be a lot harder. Um… Not really. Add this line to your code:
Try sending a message on Discord. The terminal should now print out the message. Why is that? Due to the nature of Discord being centered around Guilds rather than DMs, even when you send a message it registers as a new message. So how do we prevent that?
Go to Discord and open settings. Go to Advanced settings and enable Developer Mode.
Now go back to one of your servers. Right click your own user ad select Copy ID. Let’s call this INSERT_YOUR_ID.
Now let’s edit our code! Replace the on message function with this:
Now try sending a message. Nothing should happen. But if someone else sends a message, the program should print it out.
Setting up a bot to forward this message to a different channel
Now we have to create a bot that can forward any messages from your personal Discord to a different channel. Go to the Discord Developers Portal and create an application. Head over to the “Bot” section. Click “Create bot”. Customize your bots username and profile picture. Uncheck the “Public bot” button since we do not want random people adding our bot to their server. Copy the bot token. This is referred to as YOUR_BOT_TOKEN.
Now we must actually add the bot to our server. For this, head over to the OAuth2 section in the left menu bar. Scroll down to where it asks you to select scopes and select only bot. This is very important. Next, scroll down even further and select “Send messages”. Now scroll back up and copy the URL that is shown. Paste that URL in your browser. It should ask you if you want to add the bot to your server. Click yes. The bot should now be in your server!
Next, open Discord and go to the channel into which you would like the bot to push our messages to. And you know it! Copy the ID. This will be YOUR_CHANNEL_ID.
Now let’s edit our code a bit. Since now we’re sending using the bot instead of the user, we need to change the
if message.author.id !== INSERT_YOUR_ID with
if message.author.id !== INSERT_BOT_ID , replacing INSERT_BOT_ID with the bot’s id, taken as we mentioned before.
Line 1–10: Logging in as before, but know we are logging in with the bot account too.
Line 12–15: We are printing any new messages to the console if they have (text) content.
Line 16–20: If the message’s author isn’t the bot, and if the message has (text) content, then send it using the bot to the forwarding channel.
It should seem as if the project is done here, but there is a little bit more work to do. Right now we are only checking for text content to forward. But we would like to check for attachments and embeds too. Here is the entire code for this project, including the changes made for allowing attachments and embeds:
Line 5: We are importing a module to convert between message and rich embeds. What is the difference? Honestly, I don’t know. But I know this much. Discord (or Discord.js) gives a messageEmbed object when we get a message with an embed in it, and we need to give it a richEmbed object when we want to send a message with an embed in it. You cannot natively convert between those two (at least, not in this version), so I am using this module to convert between the embed we get from the server to the embed we need to send to a different server.
Line 26–31: Looping between all the attachments and embeds in the message and forwarding them to the other channel one-by-one.
Line 35–41: Printing all errors to the console so that NodeJS doesn’t “crash” the program whenever an uncaughtException or unhandledRejection (the two most common errors in JS) occurs.
And… You’re done! Hope you enjoyed the tutorial, and I really really hope that you are able to find some application for Discord.js in one of your applications. Have a great day!