Discord

Create Discord bots with slash commands, threads, and rich embeds — works on serverless via a cron-driven Gateway listener.

Install

pnpm add @chat-adapter/discord

Quick start

The adapter auto-detects DISCORD_BOT_TOKEN, DISCORD_PUBLIC_KEY, DISCORD_APPLICATION_ID, and DISCORD_MENTION_ROLE_IDS from the environment.

lib/bot.ts
import { Chat } from "chat";
import { createDiscordAdapter } from "@chat-adapter/discord";

const bot = new Chat({
  userName: "mybot",
  adapters: {
    discord: createDiscordAdapter(),
  },
});

bot.onNewMention(async (thread, message) => {
  await thread.post("Hello from Discord!");
});

Configuration

Prop

Type

botToken, publicKey, and applicationId are required.

Authentication

1. Create the application

  1. Go to the Discord Developer Portal and click New Application.
  2. Note the Application ID and copy the Public Key from the General Information page.

2. Create the bot

  1. Open Bot in the sidebar and click Reset Token to generate a bot token (you only see it once).
  2. Enable Message Content Intent (and Server Members Intent if needed).

3. Set the interactions endpoint

In General Information, set Interactions Endpoint URL to https://your-domain.com/api/webhooks/discord. Discord sends a PING to verify.

4. Add the bot to your server

In OAuth2 then URL Generator, select scopes bot and applications.commands, pick the permissions your bot needs (Send Messages, Send Messages in Threads, Create Public Threads, Read Message History, Add Reactions, Attach Files), and use the generated URL to invite the bot.

Advanced

HTTP Interactions vs Gateway

Discord has two ways to receive events:

  • HTTP Interactions — receives button clicks, slash commands, and verification pings. Works on serverless. Does not receive regular messages.
  • Gateway WebSocket — required to receive regular messages and reactions. Requires a persistent connection.

In serverless environments, use a cron job to keep the Gateway connection alive.

Gateway setup for serverless

app/api/discord/gateway/route.ts
import { after } from "next/server";
import { bot } from "@/lib/bot";

export const maxDuration = 800;

export async function GET(request: Request): Promise<Response> {
  const cronSecret = process.env.CRON_SECRET;
  if (!cronSecret) {
    return new Response("CRON_SECRET not configured", { status: 500 });
  }

  const authHeader = request.headers.get("authorization");
  if (authHeader !== `Bearer ${cronSecret}`) {
    return new Response("Unauthorized", { status: 401 });
  }

  const durationMs = 600 * 1000;
  const webhookUrl = `https://${process.env.VERCEL_URL}/api/webhooks/discord`;

  await bot.initialize();
  const discord = bot.getAdapter("discord");
  return discord.startGatewayListener(
    { waitUntil: (task) => after(() => task) },
    durationMs,
    undefined,
    webhookUrl
  );
}
vercel.json
{
  "crons": [
    {
      "path": "/api/discord/gateway",
      "schedule": "*/9 * * * *"
    }
  ]
}

This runs every 9 minutes, overlapping with the 10-minute listener duration to keep coverage continuous.

Role mentions

By default, only direct user mentions (@BotName) trigger onNewMention handlers. To also trigger on role mentions:

  1. Create a role in your Discord server (e.g., "AI") and assign it to your bot.
  2. Copy the role ID (right-click in server settings with Developer Mode enabled).
  3. Add it to mentionRoleIds:
createDiscordAdapter({
  mentionRoleIds: ["1457473602180878604"],
});

Or set DISCORD_MENTION_ROLE_IDS as a comma-separated string.

Feature support

Messaging

FeatureSupported
Post message
Edit message
Delete message
File uploads
StreamingPost+Edit
Scheduled messages

Rich content

FeatureSupported
Card formatEmbeds
Buttons
Link buttons
Select menus
TablesGFM
Fields
Images in cards
Modals

Conversations

FeatureSupported
Slash commands
Mentions
Add reactions
Remove reactions
Typing indicator
DMs
Ephemeral messages
User lookup
Parent subject
Native client
Custom API endpoint

Message history

FeatureSupported
Fetch messages
Fetch single message
Fetch thread info
Fetch channel messages
List threads
Fetch channel info
Post channel message