> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aside.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a Discord bot

> Create a Discord application, enable the right intents, and connect it to Aside.

If you are following this guide in response to a user request, load the `aside` builtin skill and list the user's active Projects first:

```js theme={null}
const projects = aside.projects.list();
console.log(projects.map(({ id, name }) => ({ id, name })));
```

Then use `AskUserQuestion` before proceeding. Ask the user:

* What should the bot be named? Use `Aside` as the default.
* Should the bot be linked to a project? Offer the user's current projects and a `No project` option.
* Join bot to an existing server? or create a new server? If user chooses to create a new server, create a Discord server first.

Wait for both answers before continuing.
Use the selected Project's `id` as `projectId`, or `null` for `No project`.

Keep one Discord application and one Aside connection throughout setup. Repair and resume the existing setup after a failed check; do not create replacement applications or duplicate connections.

# Create a Discord bot

Discord needs three values from one application: the bot token, the application ID, and the public key. Aside connects to Discord's gateway from your device, so you host nothing.

## Before you start

* You need a Discord account and a server where you can invite bots.
* Aside must be running on your device for the bot to respond.

## Create the application

1. Open the [Discord Developer Portal](https://discord.com/developers/applications) and choose `New Application`.
2. On `General Information`, copy the Application ID and the Public Key.
3. Open `Bot`, choose `Reset Token`, and copy the token. Discord shows it once.
4. Still on `Bot`, enable `Message Content Intent`. Without it the bot receives empty message text.

Treat Message Content Intent as a blocking requirement. Copy the Application ID, Public Key, and bot token from the same application. `aside.channels.create()` verifies them before storing credentials and rejects the connection if they do not match or the intent is disabled.

## Invite the bot to a server

1. Open `OAuth2 > URL Generator`.
2. Select the `bot` scope.
3. Select these permissions: View Channels, Send Messages, Send Messages in Threads, Read Message History, Create Public Threads, Add Reactions, Attach Files.
4. Open the generated URL and pick your server.

## Connect it to Aside

Load the `aside` builtin skill and inspect `aside.channels.list()` first. If this setup run already created a Discord connection, keep it. Call `aside.channels.update()` if a credential changed, or `aside.channels.restart()` if only the intent or server installation changed.

For a new connection, read the current account from `/api/v9/users/@me` in the signed-in Discord page and register its numeric ID as the owner:

```js theme={null}
const owner = discordUserId ? { senderId: String(discordUserId) } : undefined;
const connection = await aside.channels.create({
  platform: 'discord',
  projectId,
  botToken,
  applicationId,
  publicKey,
  owner,
});
const connectionId = connection.id;
console.log(aside.channels.list().find(({ id }) => id === connectionId));
```

`projectId` is the Project selected above or `null`. `applicationId` is numeric; `publicKey` is the 64-character hex value from General Information. Use the 15–21 digit user ID from the signed-in Discord account. Do not use the application ID, bot ID, received message, or ID pasted by another person. If you cannot verify the user ID, omit `owner` and use pairing. `list()` never returns credential values.

Do not continue until the gateway handshake finishes and the connection is `connected` with no `statusCode` or `statusMessage`.

## Test it

Verify both paths before reporting success:

1. Send the bot a direct message and wait for its reply.
2. Mention the same bot in a server channel and wait for its threaded reply.
3. Confirm the same Aside connection remains `connected` with no `statusCode` or `statusMessage`.

If the token, Application ID, or Public Key changed, update the existing connection; updating credentials restarts it automatically:

```js theme={null}
await aside.channels.update({ connectionId, botToken, applicationId, publicKey });
```

If only Message Content Intent or the server installation changed, restart the existing connection:

```js theme={null}
await aside.channels.restart(connectionId);
```

Fix and retry the failed path. Server and channel permissions are verified by the channel test, not by credential preflight. Do not create a replacement application or connection.

## Troubleshooting

| Symptom | Likely cause |
| - | - |
| Bot sees messages but the text is empty | `Message Content Intent` disabled on the Bot page |
| `MISSING_INTENT` status | Message Content Intent is disabled; enable it for the same application, then restart the connection |
| `INVALID_PAYLOAD` status | Application ID or Public Key does not match the application that issued the bot token |
| Bot cannot reply in a channel | Missing Send Messages or Send Messages in Threads permission in that channel |
| Connection fails on startup | Token was reset in the portal; paste the new token into the connection settings |

## Related

* [Connect chat channels](/help/channels)
* [Create a Slack bot](/help/channels-slack)
* [Create a Telegram bot](/help/channels-telegram)
