How to Send Discord Webhook With Application Command Triggered by Bot
🔍 WiseChecker

How to Send Discord Webhook With Application Command Triggered by Bot

Discord bots can send messages to a channel using a webhook instead of a regular bot message. A webhook message appears to come from a custom username and avatar, not from the bot itself. This is useful when you want a command response to look like it was sent by a specific user or service. Many bot developers want to trigger a webhook when a user runs a slash command. This article explains how to set up a bot that sends a webhook in response to an application command.

Key Takeaways: Sending Webhook Messages from a Discord Bot Command

  • discord.js executeWebhook method: Sends a message through an existing webhook object using the webhook ID and token.
  • InteractionCreate event: The event your bot listens for to catch slash command executions.
  • WebhookClient class: Creates a webhook client that can send messages without fetching the webhook from Discord each time.

ADVERTISEMENT

What Is a Discord Webhook and Why Use It With a Bot Command

A Discord webhook is a way to send messages to a channel programmatically. Unlike a regular bot message that shows the bot’s name and avatar, a webhook message can have any username and avatar you choose. This makes webhooks ideal for displaying formatted notifications, game stats, or logs that look like they come from an external service.

When you send a webhook from a bot command, the flow works like this:

  • A user runs a slash command on your Discord server.
  • Your bot receives an InteractionCreate event.
  • The bot creates or fetches a webhook for the target channel.
  • The bot sends the message via the webhook, using a custom name and avatar.
  • The bot replies to the user with a confirmation or ephemeral message.

The main benefit is visual consistency. For example, a server management bot can send a webhook message that looks like a system notification rather than a bot reply. The webhook message also cannot be deleted by users without the Manage Webhooks permission, which adds a layer of control.

Before you start, you need the following:

  • A Discord bot application created in the Discord Developer Portal.
  • The bot added to your server with the Send Messages and Manage Webhooks permissions.
  • Node.js installed on your development machine.
  • The discord.js library version 14 or later installed in your project.

Steps to Send a Discord Webhook From an Application Command

The implementation uses discord.js and the WebhookClient class. Follow these steps to build the feature.

  1. Set Up Your Project and Install Dependencies
    Create a new folder and initialize a Node.js project. Run npm init -y then install discord.js with npm install discord.js. Create a file named index.js.
  2. Create the Bot Client and Register a Slash Command
    In index.js, import discord.js and create a client with the GatewayIntentBits.Guilds intent. Use the client.on('ready') event to register a global slash command named webhook. The command should accept an optional string option for the message content.
  3. Listen for the InteractionCreate Event
    Add an event listener for interactionCreate. Check if the interaction is a chat input command and if the command name matches webhook.
  4. Fetch or Create a Webhook for the Channel
    Inside the command handler, get the channel where the command was run using interaction.channel. Use channel.fetchWebhooks() to see if a webhook already exists. If not, create one with channel.createWebhook(). Store the webhook ID and token for reuse.
  5. Create a WebhookClient and Send the Message
    Use the webhook ID and token to instantiate a WebhookClient. Call webhookClient.send({ content: 'Your message here', username: 'Custom Name', avatarURL: 'https://example.com/avatar.png' }). This sends the webhook message to the channel.
  6. Reply to the User
    After the webhook message is sent, reply to the interaction with interaction.reply({ content: 'Webhook sent!', ephemeral: true }). This confirms the action without cluttering the channel.

Here is a complete code example for the command handler:

const { Client, GatewayIntentBits, WebhookClient } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.once('ready', async () => {
  console.log(`Logged in as ${client.user.tag}`);
  const command = {
    name: 'webhook',
    description: 'Send a webhook message',
    options: [
      {
        name: 'message',
        description: 'The message content',
        type: 3, // STRING
        required: true,
      },
    ],
  };
  await client.application.commands.create(command);
});

client.on('interactionCreate', async (interaction) => {
  if (!interaction.isChatInputCommand()) return;
  if (interaction.commandName !== 'webhook') return;

  const channel = interaction.channel;
  let webhooks = await channel.fetchWebhooks();
  let webhook = webhooks.find(w => w.owner.id === client.user.id);

  if (!webhook) {
    webhook = await channel.createWebhook({
      name: 'Bot Webhook',
    });
  }

  const webhookClient = new WebhookClient({ id: webhook.id, token: webhook.token });
  const messageContent = interaction.options.getString('message');

  await webhookClient.send({
    content: messageContent,
    username: 'Custom Name',
    avatarURL: 'https://example.com/avatar.png',
  });

  await interaction.reply({ content: 'Webhook sent!', ephemeral: true });
});

client.login('YOUR_BOT_TOKEN');

Replace YOUR_BOT_TOKEN with your bot’s token from the Discord Developer Portal. The webhook username and avatar URL are hardcoded in this example. You can make them dynamic by adding command options.

ADVERTISEMENT

Common Issues When Sending Webhooks From Bot Commands

Webhook Not Created Because of Missing Permissions

If the bot does not have the Manage Webhooks permission, channel.createWebhook() throws an error. Ensure the bot role has this permission enabled in the server settings. Also check that the bot has the Send Messages permission for the target channel.

Webhook Token Expires After Bot Restart

A webhook token is generated when the webhook is created. If you delete the webhook and recreate it, the token changes. Store the webhook ID and token in a database or environment variable to avoid losing access. The token does not expire unless the webhook is deleted.

Webhook Message Does Not Appear in the Channel

If the webhook message does not appear, check that the channel ID is correct. The interaction.channel property returns the channel where the command was run. If you want to send the webhook to a different channel, fetch that channel by ID using client.channels.fetch().

Rate Limits When Sending Multiple Webhooks

Discord applies rate limits to webhook messages. The limit is 30 messages per webhook per 60 seconds. If your bot sends many webhooks quickly, implement a queue or delay to avoid hitting the rate limit. Use a library like p-limit to control concurrency.

Item WebhookClient.send() channel.send()
Message appearance Custom username and avatar Bot username and avatar
Permission required Manage Webhooks and Send Messages Send Messages only
Can be deleted by users No, only by users with Manage Webhooks Yes, by any user with Manage Messages
Rate limit 30 per 60 seconds per webhook 5 per 5 seconds per channel
Supports embeds Yes Yes

Now you can make your bot send webhook messages when a user runs a slash command. The webhook appears with a custom name and avatar, giving your command responses a professional look. For advanced use, add command options to let users set the webhook name and avatar dynamically. Consider storing webhook IDs in a database so the bot can reuse them across restarts.

ADVERTISEMENT