Discord Bot Setup
Create the Discord application, bot token and environment variables a self-hosted answerLoops deployment needs, and learn how the bot picks up config changes without a restart.
Discord is the one channel where the operator of a self-hosted deployment has to create the bot. answerLoops cannot do it for you the way it does on the managed cloud. This page walks you through creating a Discord application, giving the app and bot services its credentials, and checking that the bot is picking up your settings.
When you are done, anyone who is an owner or admin of your answerLoops workspace can connect a Discord server from Integrations → Discord with one click, without ever seeing a token.
This page is only for the operator. Everything your team does inside answerLoops once Discord is wired up (choosing channels, escalation role, confidence threshold, Automatic Deflections, forum channels, multiple servers) is covered in the Discord integration guide. The environment variable reference there and the one below describe the same variables.
What the operator adds
| You do this once, on the server | Your team does this in the product |
|---|---|
| Create the Discord application and bot token | Click Add answerLoops to Discord and pick a server |
| Turn on the Message Content intent | Choose channels and save them |
| Register the OAuth redirect URL | Set the escalation role and confidence threshold |
Set the Discord environment variables on the app and bot services | Turn on Automatic Deflections when they trust the answers |
Set up the Discord application
- Go to discord.com/developers/applications and click New Application. Name it, for example, "answerLoops".
- Open the Bot tab. If you see Add Bot, click it.
- Under Token, click Reset Token and copy the value. This is
DISCORD_TOKEN. Discord shows it only once. - On the General Information tab, copy the Application ID. This is
DISCORD_CLIENT_ID(andDISCORD_APPLICATION_ID, which slash commands need). - Under OAuth2, copy the Client Secret. This is
DISCORD_CLIENT_SECRET.
On the Bot tab, under Privileged Gateway Intents, enable Message Content Intent. Without it Discord removes the text of every message before the bot receives it, so the bot looks online but nothing becomes a ticket.
Under OAuth2 → Redirects, add:
<your-app-url>/api/discord/callback<your-app-url> is the public address you set as AUTH_URL (for example https://support.yourcompany.com). Discord sends people back to this address after they authorize.
Add the variables in the table below to your .env (or your host's environment settings), then restart the app and bot services. DISCORD_TOKEN must be set on both services: the app service uses it to list a server's channels in the picker, and the bot service uses it to connect to Discord.
Sign in, open Integrations → Discord, click Add answerLoops to Discord, choose a server and approve. The channel picker opens next. See Cloud setup in the integration guide for what your team sees from here.
Environment variables
| Variable | Set on | What it is |
|---|---|---|
DISCORD_TOKEN | app and bot | The bot token from the Bot tab |
DISCORD_CLIENT_ID | app | The application ID. Together with the next two variables it makes the Add answerLoops to Discord button appear |
DISCORD_CLIENT_SECRET | app | The OAuth2 client secret from the same application |
DISCORD_APPLICATION_ID | bot | Usually the same value as DISCORD_CLIENT_ID. Needed for slash commands |
BOT_TARGET_URL | bot | Address the bot uses to reach the app, with no trailing slash. The bundled docker-compose.yml already sets it to http://app:3000 |
DISCORD_GUILD_ID | bot | Optional. Registers slash commands for one server only, which takes effect immediately |
DISCORD_TOKEN, DISCORD_CLIENT_ID and DISCORD_CLIENT_SECRET must all belong to the same Discord application. The full list of variables lives in Environment Variables.
How the bot picks up config changes
You never restart the bot to change channels. When someone saves a change in Integrations → Discord, the database notifies the running bot, which reloads straight away.
- What reloads: the channel list for the workspace and for every connected server, and the Slack polling list (the same notification drives it).
- What does not: the Discord bot token and environment variables. The bot is already logged in with the token it started with, so after you change
DISCORD_TOKENrestart thebotservice. - Joining and leaving servers: when the bot joins or leaves a server it refreshes its map of which server owns which channel, which source links on tickets rely on.
- Staying connected: the bot holds one dedicated database connection just for notifications and pings it every 4 minutes. If a heartbeat fails or the connection drops, which can happen when a serverless Postgres suspends an idle database, the bot reconnects and subscribes again after a short delay. No manual restart is needed.
Notifications need a direct (non-pooled) database connection. On plain Postgres, including the bundled Docker setup, nothing extra is needed. If you use a managed provider that gives you a pooled connection string, set DIRECT_DATABASE_URL to the provider's direct connection string so the bot receives them.
Slash commands
When DISCORD_APPLICATION_ID is set, the bot registers its slash commands every time it starts. There is no separate command to run.
/ask <question>searches your knowledge base and answers inline./summarizesummarizes the last 20 messages in the channel as bullet points. An optionalcount(5 to 50) changes how many.
Discord can take up to an hour to show commands registered for all servers. Set DISCORD_GUILD_ID while testing to register them for one server at once.