Skip to content

Discord API

Created: 2020-02-17 09:06:25 -0800 Modified: 2020-08-13 11:34:20 -0700

  • Their official intro guide is here
  • In order to make a bot, you need an application first. Discord.js has a complete guide on all of these steps if you’d prefer that to my notes below.
    • Create an application
      • Go here
      • Click “New Application”
      • This’ll give you a client ID and a client secret
    • Create a bot
      • Click “Bot” on the left side of this page
      • Click “Add Bot” (note: if adding a bot to a server after it’s already in one, you’ll have to go to the OAuth2 tab to generate an invite link)
      • This will let you change the username and get a secret token
      • You may want to toggle the “Public bot” checkbox so that only you can add it to servers
    • Invite that bot to a server
      • Click “OAuth2” on the left side of this page
      • For scopes, choose “bot”
        • You’ll immediately see a URL generated in that same section. Here’s where you can pick the bot’s permissions. There aren’t easily visible explanations for each permission on the site, so you could either use this page or right-click your server in Discord itself → Server Settings → Roles → General Permissions and look at the descriptions there.
          • In general, it’s good practice to pick the minimum set of permissions required for your bot to function, that way it’s more resilient to attacks/exploits and just bad code.
            • If you mess up this list, that’s okay; you can just modify the bot’s role in your server after it’s there.
          • Also, keep in mind that when adding a bot, the person adding that bot can choose a subset of the permissions manifested.
          • I think a good starting permission set is just one permission: “Send Messages”. I also wanted to be able to manage reactions on polls, so I added “Manage Messages”.
      • Your bot will be listed as “offline” in the channel until you log in via the API.
      • You’re authorizing the bot as yourself since your bot doesn’t have a username/password combo as a regular account does.
  • If you ever accidentally leak your bot’s token, you should generate a new one as soon as possible: - Click “Bot” on the left side of this page - Click “Regenerate”
    • To get your server ID, just right-click the server in your list (you may need Developer Mode enabled):
      • Pasted image 20240104133737.png
  • Command creation limits
    • You are limited to some number of total CHAT_INPUT commands
    • You’re only able to create so many commands per day

The types of the REST APIs are sometimes hard to find. For example, PUT-ing into Routes.applicationGuildCommands has a returned type of RESTPutAPIApplicationCommandsResult:

const data = (await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: restCommands },
)) as RESTPutAPIApplicationCommandsResult

As for how to find this yourself, I think you just have to know what to look for:

bawb95: searched for RESTPostAPIApplicationCommandsJSONBody in hte discord api types github and looked down a few lines ^^ bawb95: yeah just assume the response is close to the input type

  • Embeds are described in the DiscordJS guide here. There’s a visualizer here so that you don’t have to build/test repeatedly (alternatively, use
  • Some fields can’t be empty, so if you want them to render as though they’re empty, you can italicize a space in markdown with ”_ _“.
  • People won’t even be able to see embedded messages unless they have this setting enabled: Settings → Text & Images → Link preview → Show website preview info from links pasted into chat
  • Use the user’s displayAvatarURL instead of just avatarURL since the display version falls back to the default avatar if you don’t have one.
  • Basic code to edit an embed in v11.5:
    • Note: this fetches the most recent embed from the last 50 messages, but you could also just save the message ID when you create the embed and find that via channel.fetchMessage.
const guild = this.discordClient.guilds.first();
const channels = guild.channels.array();
const generalChannel = _.find(channels, { type: 'text', name: 'general' });
// Make Discord cache the messages
await generalChannel.fetchMessages({ limit: 50 });
const messageWithEmbed = _.find(
(m) => _.size(m.embeds) > 0
const receivedEmbed = new Discord.RichEmbed(messageWithEmbed.embeds[0]);
receivedEmbed.setTitle('SOME VERY LONG TEXT');
  • I chose this over some other suggestions because it’s stable, it’s being updated, and it seems to have the features that I need. The documentation also seems good. The other suggestions were Akairo, which doesn’t seem to be updated as frequently, and Eris, which isn’t as feature-rich.
  • This is a JavaScript library for communicating with the Discord API.
  • Their startup guide is very good and covers the absolute basics like installing NodeJS, using a terminal, etc.
  • Their documentation is a totally separate page that has more reference information
  • Use formatters to format messages for Discord rather than piecing the strings together yourself
  • A “message” contains many properties, and while getting started, I wanted to know some basics, so I’ll include the highlights here:
    • member” and “author”, and you get various properties by accessing both of these. The “member” property is only for server-specific messages as opposed to DMs, that way you can see server-specific properties.
    • Member represents the user for server-specific messages (as opposed to DMs), so you can see things like the nickname which don’t exist for DMs.
      • ”nickname”, which is the user’s display name in Discord.
    • Mentions contains all @-tagged names in the message in order. This doesn’t mean that there are no words in between like “hello @Adam and @Bob”. To get just the tags, I used Lodash’s “map”
const mentionedMembers = mentions.members.array();
const names =, "user.tag");
  • Author always exists
    • ”username” - just your username, e.g. Adam13531
    • ”tag” - your username and a discriminator, e.g. Adam13531#3531
  • Channel is for differentiating between text, DM, or group DM messages. They all inherit from GuildChannel, which has a “type” property to let you see whether the channel is a DM, for example.
    • If the channel is a DM, then will respond via DM (as opposed to having to do

I only had this happen in a single case: I had an automatically applied Twitch role that was given to subscribers of the channel (reference). At one point, I changed the grace period in Discord’s integration settings, and I think it made a new role.

createReactionCollector’s “remove” event

Section titled createReactionCollector’s “remove” event

This just doesn’t work before version 12.

V11 code:

V12 code: