discord-skillv1.0.0latest
by ryan321
Discord bot integration for AI agents — send messages, read channels, manage servers, react, moderate, and more using the discord.js SDK.
Install
https://clawskills.io/api/skills/discord-skill/releases/1.0.0/SKILL.mdGive this URL to your OpenClaw agent to install.
Agent prompt
Fetch the skill from https://clawskills.io/api/skills/discord-skill/releases/1.0.0/SKILL.md and follow its Quick Start section to install, configure, and verify the discord-skill skill (v1.0.0).
Or copy this full prompt to give your agent.
SKILL.md
---
name: discord-skill
version: 1.0.0
url: https://clawskills.io/api/skills/discord-skill/releases/1.0.0/SKILL.md
artifact_sha256: 75c07ce2748f26b0d366e7bbc159f2b68a8d15b3a8c6c03bfc2177ce852f6fb4
signature: aME1P8Kfw5jTnthvJ33lrtqPd2j3HPzogue44Zd6MeFtt46Xux8LT8wVf1bGJ+z4E8ArnK4BB1aI7TUMLgwIDA==
key_id: 625b196966442b38cf1c7188ba15fa81
verify: https://clawskills.io/docs/verification
---
# Discord Skill
Send messages, read channels, manage servers, and interact with Discord communities using the official `discord.js` SDK.
---
## Overview
- **What it does:**
Lets an AI agent interact with Discord via a bot -- send messages, read channel history, list servers and channels, manage roles, react to messages, and moderate content via the `discord.js` Node.js SDK.
- **When to use it:**
When the user wants to interact with Discord: posting messages to channels, reading conversation history, managing server members, sending DMs, or moderating a community.
- **Requirements:**
- OS: macOS / Linux / Windows
- Runtime: Node.js 18+
- Accounts: Discord account with a bot application configured in the Discord Developer Portal
---
## Quick start
### Install
```bash
npm install discord.js@14.25.1
```
### Configure
Add your credentials in the **OpenClaw runtime environment** (Control UI env editor if available, process env, or `.env`):
```bash
# Required — set in OpenClaw runtime environment:
# DISCORD_BOT_TOKEN — your Discord bot token
#
# Optional non-secret config (can go in openclaw.json env block):
# DISCORD_GUILD_ID — default guild (server) ID for operations
#
# Get your token from: https://discord.com/developers/applications > Your App > Bot > Token
```
### Verify
```bash
node -e "const{Client,GatewayIntentBits}=require('discord.js');const c=new Client({intents:[GatewayIntentBits.Guilds]});c.once('ready',()=>{console.log(JSON.stringify({username:c.user.username,id:c.user.id,guilds:c.guilds.cache.size},null,2));c.destroy()});c.login(process.env.DISCORD_BOT_TOKEN)"
```
**Expected result:**
Prints JSON with your bot's `username`, `id`, and the number of `guilds` it has joined, confirming authentication works.
---
## Core tasks
### Send a message to a channel
```text
Send "Hello from my agent!" to the Discord channel with ID 123456789012345678.
```
### Read channel message history
```text
Show me the last 10 messages from the Discord channel with ID 123456789012345678.
```
### List servers (guilds) the bot is in
```text
List all Discord servers the bot is a member of, showing each server's name and member count.
```
### List channels in a server
```text
List all text channels in the Discord server with ID 987654321098765432.
```
### Reply to a specific message
```text
Reply to message ID 111222333444555666 in channel 123456789012345678 saying "Thanks for letting us know!"
```
### Add a reaction to a message
```text
Add a thumbsup reaction to message ID 111222333444555666 in channel 123456789012345678.
```
### Create a new text channel
```text
Create a new text channel called "project-updates" in the Discord server with ID 987654321098765432.
```
### Delete a message
```text
Delete message ID 111222333444555666 from channel 123456789012345678.
```
---
## SDK usage reference
This skill uses the `discord.js` npm package (no MCP server). The agent must write Node.js code to interact with the Discord API. Below is the complete reference for constructing the client and calling each endpoint.
### Client initialization
discord.js uses a persistent WebSocket connection. Each script must create a client, wait for `ready`, perform operations, then destroy the client:
```javascript
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});
client.once('ready', async () => {
try {
// ... perform operations here
} finally {
client.destroy();
}
});
client.login(process.env.DISCORD_BOT_TOKEN);
```
### Gateway intents reference
| Intent | Required for |
|---|---|
| `Guilds` | List guilds, channels, roles |
| `GuildMessages` | Receive and read messages in guild channels |
| `MessageContent` | Read message text content (privileged — must enable in Developer Portal) |
| `GuildMembers` | List and manage guild members (privileged — must enable in Developer Portal) |
| `DirectMessages` | Receive and read DMs |
| `GuildMessageReactions` | Receive reaction events |
Only include the intents your operation needs. `Guilds` is required for most operations.
### Send a message
```javascript
const channel = await client.channels.fetch('CHANNEL_ID');
const sent = await channel.send('Hello from my agent!');
// sent => Message { id: '...', content: 'Hello from my agent!', channelId: '...' }
```
With an embed:
```javascript
const channel = await client.channels.fetch('CHANNEL_ID');
await channel.send({
content: 'Check this out:',
embeds: [{
title: 'Status Update',
description: 'Everything is running smoothly.',
color: 0x00ff00,
}],
});
```
### Reply to a message
```javascript
const channel = await client.channels.fetch('CHANNEL_ID');
const message = await channel.messages.fetch('MESSAGE_ID');
await message.reply('Thanks for letting us know!');
```
### Read channel history
```javascript
const channel = await client.channels.fetch('CHANNEL_ID');
const messages = await channel.messages.fetch({ limit: 10 });
// messages => Collection<Snowflake, Message>
messages.forEach(msg => {
// msg => { id, content, author: { username, id }, createdTimestamp }
});
```
### List guilds
```javascript
const guilds = client.guilds.cache;
guilds.forEach(guild => {
// guild => { id, name, memberCount }
});
```
For full guild details (requires fetching):
```javascript
const guild = await client.guilds.fetch('GUILD_ID');
// guild => { id, name, memberCount, ownerId, ... }
```
### List channels in a guild
```javascript
const guild = await client.guilds.fetch('GUILD_ID');
const channels = await guild.channels.fetch();
// Filter to text channels only
const { ChannelType } = require('discord.js');
const textChannels = channels.filter(ch => ch.type === ChannelType.GuildText);
textChannels.forEach(ch => {
// ch => { id, name, topic, position }
});
```
### Add a reaction
```javascript
const channel = await client.channels.fetch('CHANNEL_ID');
const message = await channel.messages.fetch('MESSAGE_ID');
await message.react('\u{1F44D}'); // thumbsup emoji
```
Using a custom emoji:
```javascript
await message.react('CUSTOM_EMOJI_ID');
```
### Remove a reaction
```javascript
const channel = await client.channels.fetch('CHANNEL_ID');
const message = await channel.messages.fetch('MESSAGE_ID');
const reaction = message.reactions.cache.get('\u{1F44D}');
await reaction.users.remove(client.user.id);
```
### Create a text channel
```javascript
const { ChannelType } = require('discord.js');
const guild = await client.guilds.fetch('GUILD_ID');
const channel = await guild.channels.create({
name: 'project-updates',
type: ChannelType.GuildText,
topic: 'Project status updates',
});
// channel => { id, name, type, topic }
```
### Delete a message
```javascript
const channel = await client.channels.fetch('CHANNEL_ID');
const message = await channel.messages.fetch('MESSAGE_ID');
await message.delete();
```
### Send a DM
```javascript
const user = await client.users.fetch('USER_ID');
await user.send('Hello via DM!');
```
### Get guild member info
```javascript
const guild = await client.guilds.fetch('GUILD_ID');
const member = await guild.members.fetch('USER_ID');
// member => { user: { username, id }, nickname, roles, joinedTimestamp }
```
### Kick / ban a member
```javascript
const guild = await client.guilds.fetch('GUILD_ID');
const member = await guild.members.fetch('USER_ID');
// Kick (can rejoin with invite)
await member.kick('Reason for kick');
// Ban (cannot rejoin)
await member.ban({ reason: 'Reason for ban' });
```
### Bot permissions reference
| Permission | Required for |
|---|---|
| `SendMessages` | Send messages to channels |
| `ReadMessageHistory` | Read past messages |
| `ViewChannel` | See channels and their content |
| `ManageMessages` | Delete messages from other users |
| `ManageChannels` | Create, edit, delete channels |
| `AddReactions` | Add reactions to messages |
| `ManageRoles` | Assign and modify roles |
| `KickMembers` | Kick members from the server |
| `BanMembers` | Ban members from the server |
### Error handling pattern
```javascript
try {
const channel = await client.channels.fetch('CHANNEL_ID');
await channel.send('Hello!');
} catch (err) {
if (err.code === 50001) {
console.error('Missing Access — bot cannot see this channel');
} else if (err.code === 50013) {
console.error('Missing Permissions — bot lacks required permission');
} else if (err.code === 10003) {
console.error('Unknown Channel — check the channel ID');
} else if (err.code === 10004) {
console.error('Unknown Guild — check the guild ID');
} else if (err.code === 10008) {
console.error('Unknown Message — check the message ID');
} else if (err.code === 50035) {
console.error('Invalid Form Body —', err.message);
} else if (err.httpStatus === 429) {
console.error('Rate limited — discord.js handles retries automatically');
} else {
console.error('Discord API error:', err.message);
}
}
```
### Discord API error codes
| Code | Meaning |
|---|---|
| `10003` | Unknown Channel |
| `10004` | Unknown Guild |
| `10008` | Unknown Message |
| `50001` | Missing Access |
| `50013` | Missing Permissions |
| `50035` | Invalid Form Body |
| `40001` | Unauthorized (invalid token) |
| `40007` | User banned from guild |
---
## Environment variable contract
| Variable | Purpose | Required | Where to set |
|---|---|---|---|
| `DISCORD_BOT_TOKEN` | Discord bot token | Yes | OpenClaw runtime environment |
| `DISCORD_GUILD_ID` | Default server/guild ID | Optional | `env` block in `openclaw.json` |
Credentials set in the OpenClaw runtime environment are automatically available to scripts executed by the agent.
---
## Configuration
* **Secrets / credentials required:**
* `DISCORD_BOT_TOKEN` -- Your bot's token from the Discord Developer Portal. Required for all operations.
* **How to obtain credentials:**
1. Go to https://discord.com/developers/applications
2. Click "New Application" and name it
3. Go to "Bot" in the sidebar and click "Add Bot"
4. Under "Token", click "Reset Token" and copy the token
5. Under "Privileged Gateway Intents", enable "Message Content Intent" (required for reading message content)
6. Go to "OAuth2" > "URL Generator", select `bot` scope and desired permissions
7. Use the generated URL to invite the bot to your server
* **Config files used:**
* No config files — this is an SDK-only skill. Credentials are read from environment variables at runtime.
* **How to reset / re-auth:**
* Go to https://discord.com/developers/applications > Your App > "Bot" > "Reset Token"
* Update your environment variable with the new token
---
## Security & Guardrails
### Secrets handling
* Never paste bot tokens into chat.
* Always use environment variables (`DISCORD_BOT_TOKEN`).
* Never pass tokens as command-line arguments (visible in `ps` output).
* If a token is compromised, reset it immediately in the Developer Portal -- the old token is invalidated instantly.
### Confirmations (before risky actions)
* Always confirm with the user before:
* Sending messages to channels (visible to all channel members)
* Sending direct messages to users
* Deleting messages (irreversible)
* Creating or deleting channels
* Banning or kicking members
* Modifying roles or permissions
* Show the exact message text and target channel/user before sending.
### Rate limits
* Discord enforces rate limits per route (typically 5 requests per 5 seconds for messages).
* Do not retry aggressively on 429 responses -- respect the `Retry-After` header.
* The `discord.js` SDK handles rate limiting automatically by default -- it queues requests and waits when limits are hit.
* Avoid sending messages in rapid succession to prevent the bot from being flagged.
### Data minimization
* Return summaries by default -- do not dump full message history unless the user asks.
* Avoid logging or echoing tokens in output.
* When reading history, use `limit: 10` unless the user requests more.
* Strip unnecessary metadata (internal IDs, raw timestamps) from responses before presenting.
### Permissions / scopes
* **Required bot permissions:** Send Messages, Read Message History, View Channels
* **Optional permissions:** Manage Messages (for deletion), Manage Channels (for creation), Add Reactions, Manage Roles, Kick Members, Ban Members
* **Privileged intents:** Message Content Intent (required to read message text in guild channels), Server Members Intent (required for member management)
* **Least privilege:** Start with Send Messages, Read Message History, and View Channels. Add more permissions only as needed. Only enable privileged intents that are required for the user's use case.
### Network access
* **Domains used:**
* `discord.com` -- Discord API requests
* `gateway.discord.gg` -- WebSocket gateway connection
* `cdn.discordapp.com` -- asset downloads (avatars, attachments)
### Local storage
* **Writes to:** Nothing -- this skill does not write to the filesystem beyond the installed npm package in `node_modules/`.
* **Does not access:** SSH keys, browser profiles, keychains, password stores, or any local files.
### Revoke / rotate
* Reset token: https://discord.com/developers/applications > Your App > "Bot" > "Reset Token" (old token is immediately invalidated)
* Remove bot from a server: Server Settings > Integrations > find the bot > Remove
* After rotation, update your environment variable and re-run the Verify command to confirm.
---
## Troubleshooting
* **Error:** `An invalid token was provided`
* Fix: Check that `DISCORD_BOT_TOKEN` is set correctly. Reset the token in the Developer Portal if needed.
* **Error:** `Missing Access` or `Missing Permissions`
* Fix: The bot lacks the required permission in the target channel or server. Re-invite the bot with the correct permissions using the OAuth2 URL Generator.
* **Error:** `Privileged intent provided is not enabled`
* Fix: Go to the Developer Portal > Your App > "Bot" and enable "Message Content Intent" under Privileged Gateway Intents. This is required for reading message content.
* **Error:** `Unknown Channel` or `Unknown Guild`
* Fix: Verify the channel/guild ID is correct and the bot has been invited to the server.
* **Error:** `429 You are being rate limited`
* Fix: The `discord.js` SDK handles rate limits automatically. If you still see this, reduce message frequency. Do not override the SDK's built-in rate limit handling.
* **Problem:** "Bot appears online but doesn't respond"
* Fix: Ensure the correct intents are specified in the `Client` constructor. Missing intents cause the bot to silently ignore events.
* **Problem:** "Message content is empty"
* Fix: Enable the "Message Content Intent" in the Developer Portal and include `GatewayIntentBits.MessageContent` in the client intents.
---
## Release notes
* v1.0.0:
* Initial release
* Send messages, read history, list guilds/channels, reply, react, create channels, delete messages
* Uses `discord.js@14.25.1`
---
## Links
* Package: https://www.npmjs.com/package/discord.js
* Package repo: https://github.com/discordjs/discord.js
* API docs: https://discord.js.org/docs
* Developer portal: https://discord.com/developers/applications
* Discord API docs: https://discord.com/developers/docs
* Permissions reference: https://discord.com/developers/docs/topics/permissions
---
## Publisher
* **Publisher:** @Agentopolis
Security Guardrails
secrets/credential handlingconfirmation before risky actionsrate limitingdata minimizationpermissions/scopesnetwork access disclosurelocal storage disclosuretoken revocation/rotation
Releases
1.0.0listedcurrent
2/15/2026External Interfaces
Secrets & Environment Variables
DISCORD_BOT_TOKENDISCORD_GUILD_ID
Packages
npm install discord.js@14.25.1
Languages
javascript
Network Domains
discord.comwww.npmjs.comgithub.comdiscord.js.orggateway.discord.ggcdn.discordapp.com
File System Access
none detected
Files Included (1)
SKILL.md15.8 KB