Files
Ben Sabic 6b17c603fb feat: add apiUrl config option to all platform adapters (#377)
* feat: add apiUrl config option to all platform adapters

Add a consistent `apiUrl` option across all 8 adapters for custom API
endpoint configuration (e.g. GovSlack, GitHub Enterprise, GCC-High
Teams). Includes env var fallbacks and unit tests for each adapter.

* add changeset for adapter apiUrl feature

---------

Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
2026-04-14 13:01:57 +10:00
..
2026-04-13 22:08:02 -04:00
2026-04-13 22:08:02 -04:00
2026-03-09 16:09:42 -07:00
2026-02-27 09:58:28 -08:00

@chat-adapter/discord

npm version npm downloads

Discord adapter for Chat SDK. Configure with HTTP Interactions and Gateway WebSocket support.

Installation

pnpm add @chat-adapter/discord

Usage

The adapter auto-detects DISCORD_BOT_TOKEN, DISCORD_PUBLIC_KEY, DISCORD_APPLICATION_ID, and DISCORD_MENTION_ROLE_IDS from environment variables:

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!");
});

Discord application setup

1. Create application

  1. Go to the Discord Developer Portal
  2. Click New Application and give it a name
  3. Note the Application ID from the General Information page
  4. Copy the Public Key from the General Information page

2. Create bot

  1. Go to the Bot section in the left sidebar
  2. Click Reset Token to generate a new bot token
  3. Copy and save the token (you won't see it again)
  4. Enable these Privileged Gateway Intents:
    • Message Content Intent
    • Server Members Intent (if needed)

3. Configure interactions endpoint

  1. Go to General Information
  2. Set Interactions Endpoint URL to https://your-domain.com/api/webhooks/discord
  3. Discord sends a PING to verify the endpoint

4. Add bot to server

  1. Go to OAuth2 then URL Generator
  2. Select scopes: bot, applications.commands
  3. Select bot permissions: Send Messages, Send Messages in Threads, Create Public Threads, Read Message History, Add Reactions, Attach Files
  4. Copy the generated URL and open it to invite the bot to your server

Architecture: HTTP Interactions vs Gateway

Discord has two ways to receive events:

HTTP Interactions (default):

  • Receives button clicks, slash commands, and verification pings
  • Works out of the box with serverless
  • Does not receive regular messages

Gateway WebSocket (required for messages):

  • Receives regular messages and reactions
  • Requires a persistent connection
  • In serverless environments, use a cron job to maintain the connection

Gateway setup for serverless

1. Create Gateway route

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();

  return bot.adapters.discord.startGatewayListener(
    { waitUntil: (task) => after(() => task) },
    durationMs,
    undefined,
    webhookUrl
  );
}

2. Configure Vercel Cron

{
  "crons": [
    {
      "path": "/api/discord/gateway",
      "schedule": "*/9 * * * *"
    }
  ]
}

This runs every 9 minutes, ensuring overlap with the 10-minute listener duration.

3. Add environment variables

Add CRON_SECRET to your Vercel project settings.

Role mentions

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

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

Or set DISCORD_MENTION_ROLE_IDS as a comma-separated string in your environment variables.

Configuration

All options are auto-detected from environment variables when not provided.

Option Required Description
botToken No* Discord bot token. Auto-detected from DISCORD_BOT_TOKEN
publicKey No* Application public key. Auto-detected from DISCORD_PUBLIC_KEY
applicationId No* Discord application ID. Auto-detected from DISCORD_APPLICATION_ID
mentionRoleIds No Array of role IDs that trigger mention handlers. Auto-detected from DISCORD_MENTION_ROLE_IDS (comma-separated)
logger No Logger instance (defaults to ConsoleLogger("info"))

*botToken, publicKey, and applicationId are required — either via config or env vars.

Environment variables

DISCORD_BOT_TOKEN=your-bot-token
DISCORD_PUBLIC_KEY=your-application-public-key
DISCORD_APPLICATION_ID=your-application-id
DISCORD_MENTION_ROLE_IDS=1234567890,0987654321  # Optional
CRON_SECRET=your-random-secret                   # For Gateway cron

Features

Messaging

Feature Supported
Post message Yes
Edit message Yes
Delete message Yes
File uploads Yes
Streaming Post+Edit fallback

Rich content

Feature Supported
Card format Embeds
Buttons Yes
Link buttons Yes
Select menus No
Tables GFM
Fields Yes
Images in cards Yes
Modals No

Conversations

Feature Supported
Slash commands Yes
Mentions Yes
Add reactions Yes
Remove reactions Yes
Typing indicator Yes
DMs Yes
Ephemeral messages No (DM fallback)

Message history

Feature Supported
Fetch messages Yes
Fetch single message No
Fetch thread info Yes
Fetch channel messages Yes
List threads Yes
Fetch channel info Yes
Post channel message Yes

Testing

Run a local tunnel (e.g., ngrok) to test webhooks locally:

ngrok http 3000

Update the Interactions Endpoint URL in the Discord Developer Portal to your ngrok URL.

Troubleshooting

Bot not responding to messages

  1. Check Gateway connection: Messages require the Gateway WebSocket, not just HTTP interactions
  2. Verify Message Content Intent: Enable this in the Bot settings
  3. Check bot permissions: Ensure the bot can read messages in the channel

Role mentions not triggering

  1. Verify role ID: Enable Developer Mode in Discord settings, then right-click the role
  2. Check mentionRoleIds config: Ensure the role ID is in the array
  3. Confirm bot has the role: The bot must have the role assigned

Signature verification failing

  1. Check public key format: Should be a 64-character hex string (lowercase)
  2. Verify endpoint URL: Must exactly match what's configured in Discord Developer Portal
  3. Check for body parsing: Don't parse the request body before verification

License

MIT