Skip to main content

Discord

A Discord connection reaches https://discord.com/api/v10 as a bot you own. It suits the read-heavy jobs you would otherwise do by scrolling: pulling a channel's recent history into a summary, checking who is in a server, or looking up a message someone linked. Posting and deleting are included too, but both start switched off and ask a human before they run.

What you need

A bot token. That is a static credential, so this connector works end to end today: you paste the token once and the gateway seals it.

  1. Open the Discord Developer Portal and choose New Application.

  2. Go to Bot and choose Reset Token, then copy the token. Discord shows it once.

  3. On the same page, under Privileged Gateway Intents, enable what you need:

    • Server Members Intent — required by members.list. Without it that call fails.
    • Message Content Intent — required to see message text. Without it Discord still answers messages.list, but content, embeds, attachments and components come back empty, except on the bot's own messages, direct messages sent to it, and messages that mention it.

    You can enable both yourself in the portal while your app has fewer than 10,000 users. Past that, Discord reviews the app before it keeps privileged-intent access.

  4. Go to OAuth2 → URL Generator, tick the bot scope, and choose the least permissions that cover what you want:

    • View Channels and Read Message History — everything read-only.
    • Send Messages — only if the agent should post.
    • Manage Messages — only if it should delete other people's messages. A bot can always delete its own.

    Leave Mention Everyone unticked. By default Discord turns @everyone, @here and role mentions inside a bot's message into real pings, and withholding that permission is what stops a posted message notifying the whole server.

  5. Open the generated URL, choose the server, and authorise. The bot sees only the channels its role can see, so Discord's own channel permissions are a second place to narrow this down.

The bot token is the whole credential. The client id and client secret on the OAuth2 page are for user sign-in flows and are not used here.

Add the connection

In the console, open Access → Connections → Add connection and pick Discord from the catalog. Paste the bot token when the form asks for the credential. It is sealed on your gateway at that moment and never displayed again, and from then on Permaura injects it server-side on each approved call.

Adding the connection makes these actions possible, not permitted. An agent cannot touch any of them until a grant allows it.

What the agent can do

Capabilities are namespaced under the connection id, so an agent sees messages.list as <connection>.messages.list.

ActionWhat it doesOn by default
guilds.readReads a server's metadata; with_counts adds approximate member and presence countsYes
channels.listLists the channels in a serverYes
channels.readReads one channelYes
members.listLists server members, paged with limit and afterYes
messages.listReads a channel's message history, filtered with limit, before, after or aroundYes
messages.readReads a single message by idYes
messages.createPosts a message to a channelNo, and it asks for approval
messages.deleteDeletes a messageNo, and it asks for approval

Posting is irreversible in the way that matters: other people see it immediately, and deleting it afterwards does not unsend the notification. That is why it stays off until you switch it on, and prompts you every time even then.

Good to know

  • The host is pinned. Every call goes to discord.com and nowhere else, whatever an agent asks for.
  • Ids are snowflakes, not names. Turn on User Settings → Advanced → Developer Mode in the Discord client, then right-click a server, channel or message to copy its id.
  • Rate limits. A bot gets 50 requests per second globally, on top of per-route buckets described by the X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset-After response headers. When you exceed one, Discord returns 429 with a retry_after value in seconds.
  • Empty message text is an intent problem, not a bug. If messages.list returns messages with blank content, the Message Content Intent is off.
  • The bot must actually be in the server and its role must be able to view the channel, otherwise reads come back 403 no matter what the token allows.
  • messages.create accepts allowed_mentions, which narrows who a message is allowed to ping. Omit it and Discord applies its permissive default, so pair it with withholding Mention Everyone rather than relying on either alone.
  • Deletions show up as the bot in the server's audit log, and cannot be undone.
  • Permaura sends the User-Agent header Discord requires on API requests; you do not need to configure it.
  • There is no sandbox. Use a private test server while you are working out what the agent should do.