How do I handle rate-limiting?

Hi, all! Sorry if this is a silly question.

When I kick and re-invite my Discord bot to my server for diagnostic purposes, it needs to reinstall all of its commands. Unfortunately, I have implemented enough commands so far that the bot is rate-limited during the installation attempt, which prevents commands after a certain point from installing entirely. I want to program my bot to respond intelligently to rate-limiting and wait until a given interval has passed to continue submitting requests.

This seems straightforward enough, and I thought so too - but every attempt I have made to integrate this sort of mitigation into my codebase has met with failure. I’m at my wits’ end.

Here are some code samples:

In app.js (main executed file):

app.listen(PORT, () => {
  console.log("Listening on port", PORT);
  HasGuildCommands(process.env.APP_ID, process.env.GUILD_ID, [

HasGuildCommands, HasGuildCommand, and InstallGuildCommand in commands.js:

export async function HasGuildCommands(appId, guildId, commands) {
  if (guildId === "" || appId === "") return;
  commands.forEach((c) => HasGuildCommand(appId, guildId, c));

async function HasGuildCommand(appId, guildId, command) {
  let update = false;
  const endpoint = `applications/${appId}/guilds/${guildId}/commands`;
  try {
    const res = await DiscordRequest(endpoint, { method: "GET" });
    const data = await res.json();

    if (data) {
      const installedNames = => c["name"]);
      if (!installedNames.includes(command["name"])) {
        console.log(`Installing "${command["name"]}"`);
        InstallGuildCommand(appId, guildId, command);
        console.log(`Installed  "${command["name"]}"`);
      } else {
        console.log(`"${command["name"]}" command already installed.`);
        if (update) {
          console.log(`"Forcibly reinstalling "${command["name"]}"...`);
          InstallGuildCommand(appId, guildId, command);
  } catch (err) {
    console.error("Command has-check error: ", err);

export async function InstallGuildCommand(appId, guildId, command) {
  const endpoint = `applications/${appId}/guilds/${guildId}/commands`;
  try {
    await DiscordRequest(endpoint, { method: "POST", body: command });
  } catch (err) {
    console.error("Installation error: ", err);
    console.error("Command: ", command);

DiscordRequest in utils.js:

export async function DiscordRequest(endpoint, options) {
  const url = "" + endpoint;
  if (options.body) options.body = JSON.stringify(options.body);
  const res = await fetch(url, {
    headers: {
      Authorization: `Bot ${process.env.DISCORD_TOKEN}`,
      "Content-Type": "application/json, charset=UTF-8",
        "user agent name",

  if (!res.ok) {
    const data = await res.json();
    throw new Error(JSON.stringify(data));
  return res;

I suspect any code I’d wish to implement for my problems would have to go in DiscordRequest. What should I do next?

1 Like