Back to skills
SkillHub ClubShip Full StackFull Stack

agent-discord

Interact with Discord servers - send messages, read channels, manage reactions

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,053
Hot score
99
Updated
March 20, 2026
Overall rating
C0.0
Composite score
0.0
Best-practice grade
C67.6

Install command

npx @skill-hub/cli install openclaw-skills-agent-discord

Repository

openclaw/skills

Skill path: skills/devxoul/agent-discord

Interact with Discord servers - send messages, read channels, manage reactions

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install agent-discord into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding agent-discord to shared team environments
  • Use agent-discord for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: agent-discord
description: Interact with Discord servers - send messages, read channels, manage reactions
version: 1.10.5
allowed-tools: Bash(agent-discord:*)
metadata:
  openclaw:
    requires:
      bins:
        - agent-discord
    install:
      - kind: node
        package: agent-messenger
        bins: [agent-discord]
---

# Agent Discord

A TypeScript CLI tool that enables AI agents and humans to interact with Discord servers through a simple command interface. Features seamless token extraction from the Discord desktop app and multi-server support.

## Quick Start

```bash
# Get server snapshot (credentials are extracted automatically)
agent-discord snapshot

# Send a message
agent-discord message send <channel-id> "Hello from AI agent!"

# List channels
agent-discord channel list
```

## Authentication

Credentials are extracted automatically from the Discord desktop app on first use. No manual setup required — just run any command and authentication happens silently in the background.

On macOS, the system may prompt for your Keychain password the first time (required to decrypt Discord's stored token). This is a one-time prompt.

**IMPORTANT**: NEVER guide the user to open a web browser, use DevTools, or manually copy tokens from a browser. Always use `agent-discord auth extract` to obtain tokens from the desktop app.

### Multi-Server Support

```bash
# List all available servers
agent-discord server list

# Switch to a different server
agent-discord server switch <server-id>

# Show current server
agent-discord server current

# Check auth status
agent-discord auth status
```

## Memory

The agent maintains a `~/.config/agent-messenger/MEMORY.md` file as persistent memory across sessions. This is agent-managed — the CLI does not read or write this file. Use the `Read` and `Write` tools to manage your memory file.

### Reading Memory

At the **start of every task**, read `~/.config/agent-messenger/MEMORY.md` using the `Read` tool to load any previously discovered server IDs, channel IDs, user IDs, and preferences.

- If the file doesn't exist yet, that's fine — proceed without it and create it when you first have useful information to store.
- If the file can't be read (permissions, missing directory), proceed without memory — don't error out.

### Writing Memory

After discovering useful information, update `~/.config/agent-messenger/MEMORY.md` using the `Write` tool. Write triggers include:

- After discovering server IDs and names (from `server list`, `snapshot`, etc.)
- After discovering useful channel IDs and names (from `channel list`, `snapshot`, etc.)
- After discovering user IDs and names (from `user list`, `user me`, etc.)
- After the user gives you an alias or preference ("call this the dev server", "my main channel is X")
- After discovering channel structure (categories, voice channels)

When writing, include the **complete file content** — the `Write` tool overwrites the entire file.

### What to Store

- Server IDs with names
- Channel IDs with names and categories
- User IDs with display names
- User-given aliases ("dev server", "announcements channel")
- Commonly used thread IDs
- Any user preference expressed during interaction

### What NOT to Store

Never store tokens, credentials, or any sensitive data. Never store full message content (just IDs and channel context). Never store file upload contents.

### Handling Stale Data

If a memorized ID returns an error (channel not found, server not found), remove it from `MEMORY.md`. Don't blindly trust memorized data — verify when something seems off. Prefer re-listing over using a memorized ID that might be stale.

### Format / Example

```markdown
# Agent Messenger Memory

## Discord Servers

- `1234567890123456` — Acme Dev (default)
- `9876543210987654` — Open Source Community

## Channels (Acme Dev)

- `1111111111111111` — #general (General category)
- `2222222222222222` — #engineering (Engineering category)
- `3333333333333333` — #deploys (Engineering category)

## Users (Acme Dev)

- `4444444444444444` — Alice (server owner)
- `5555555555555555` — Bob

## Aliases

- "dev server" → `1234567890123456` (Acme Dev)
- "deploys" → `3333333333333333` (#deploys in Acme Dev)

## Notes

- User prefers --pretty output for snapshots
- Main server is "Acme Dev"
```

> Memory lets you skip repeated `channel list` and `server list` calls. When you already know an ID from a previous session, use it directly.

## Commands

### Auth Commands

```bash
# Extract token from Discord desktop app (usually automatic)
agent-discord auth extract
agent-discord auth extract --debug

# Check auth status
agent-discord auth status

# Logout from Discord
agent-discord auth logout
```

### Message Commands

```bash
# Send a message
agent-discord message send <channel-id> <content>
agent-discord message send 1234567890123456789 "Hello world"

# List messages
agent-discord message list <channel-id>
agent-discord message list 1234567890123456789 --limit 50

# Get a single message by ID
agent-discord message get <channel-id> <message-id>
agent-discord message get 1234567890123456789 9876543210987654321

# Delete a message
agent-discord message delete <channel-id> <message-id> --force

# Acknowledge/mark a message as read
agent-discord message ack <channel-id> <message-id>

# Search messages in current server
agent-discord message search <query>
agent-discord message search "project update" --limit 10
agent-discord message search "hello" --channel <channel-id> --author <user-id>
```

### Channel Commands

```bash
# List channels in current server (text channels only)
agent-discord channel list

# Get channel info
agent-discord channel info <channel-id>
agent-discord channel info 1234567890123456789

# Get channel history (alias for message list)
agent-discord channel history <channel-id> --limit 100
```

### Server Commands

```bash
# List all servers
agent-discord server list

# Get server info
agent-discord server info <server-id>

# Switch active server
agent-discord server switch <server-id>

# Show current server
agent-discord server current
```

### User Commands

```bash
# List server members
agent-discord user list

# Get user info
agent-discord user info <user-id>

# Get current user
agent-discord user me
```

### DM Commands

```bash
# List DM channels
agent-discord dm list

# Create a DM channel with a user
agent-discord dm create <user-id>
```

### Mention Commands

```bash
# List recent mentions
agent-discord mention list
agent-discord mention list --limit 50
agent-discord mention list --guild <server-id>
```

### Friend Commands

```bash
# List all relationships (friends, blocked, pending requests)
agent-discord friend list
agent-discord friend list --pretty
```

### Note Commands

```bash
# Get note for a user
agent-discord note get <user-id>

# Set note for a user
agent-discord note set <user-id> "Note content"
```

### Profile Commands

```bash
# Get detailed user profile
agent-discord profile get <user-id>
```

### Member Commands

```bash
# Search guild members
agent-discord member search <guild-id> <query>
agent-discord member search 1234567890123456789 "john" --limit 20
```

### Thread Commands

```bash
# Create a thread in a channel
agent-discord thread create <channel-id> <name>
agent-discord thread create 1234567890123456789 "Discussion" --auto-archive-duration 1440

# Archive a thread
agent-discord thread archive <thread-id>
```

### Reaction Commands

```bash
# Add reaction (use emoji name without colons)
agent-discord reaction add <channel-id> <message-id> <emoji>
agent-discord reaction add 1234567890123456789 9876543210987654321 thumbsup

# Remove reaction
agent-discord reaction remove <channel-id> <message-id> <emoji>

# List reactions on a message
agent-discord reaction list <channel-id> <message-id>
```

### File Commands

```bash
# Upload file
agent-discord file upload <channel-id> <path>
agent-discord file upload 1234567890123456789 ./report.pdf

# List files in channel
agent-discord file list <channel-id>

# Get file info
agent-discord file info <channel-id> <file-id>
```

### Snapshot Command

Get comprehensive server state for AI agents:

```bash
# Full snapshot
agent-discord snapshot

# Filtered snapshots
agent-discord snapshot --channels-only
agent-discord snapshot --users-only

# Limit messages per channel
agent-discord snapshot --limit 10
```

Returns JSON with:
- Server metadata (id, name)
- Channels (id, name, type, topic)
- Recent messages (id, content, author, timestamp)
- Members (id, username, global_name)

## Output Format

### JSON (Default)

All commands output JSON by default for AI consumption:

```json
{
  "id": "1234567890123456789",
  "content": "Hello world",
  "author": "username",
  "timestamp": "2024-01-15T10:30:00.000Z"
}
```

### Pretty (Human-Readable)

Use `--pretty` flag for formatted output:

```bash
agent-discord channel list --pretty
```

## Key Differences from Slack

| Feature | Discord | Slack |
|---------|---------|-------|
| Server terminology | Server | Workspace |
| Channel identifiers | Snowflake IDs | Channel name or ID |
| Message identifiers | Snowflake IDs | Timestamps (ts) |
| Threads | Thread ID field | Thread timestamp |
| Mentions | `<@user_id>` | `<@USER_ID>` |

**Important**: Discord uses Snowflake IDs (large numbers like `1234567890123456789`) for all identifiers. You cannot use channel names directly - use `channel list` to find IDs first.

## Common Patterns

See `references/common-patterns.md` for typical AI agent workflows.

## Templates

See `templates/` directory for runnable examples:
- `post-message.sh` - Send messages with error handling
- `monitor-channel.sh` - Monitor channel for new messages
- `server-summary.sh` - Generate server summary

## Error Handling

All commands return consistent error format:

```json
{
  "error": "Not authenticated. Run \"auth extract\" first."
}
```

Common errors:
- `Not authenticated`: No valid token (auto-extraction failed — see Troubleshooting)
- `No current server set`: Run `server switch <id>` first
- `Message not found`: Invalid message ID
- `Unknown Channel`: Invalid channel ID

## Configuration

Credentials stored in: `~/.config/agent-messenger/discord-credentials.json`

Format:
```json
{
  "token": "user_token_here",
  "current_server": "1234567890123456789",
  "servers": {
    "1234567890123456789": {
      "server_id": "1234567890123456789",
      "server_name": "My Server"
    }
  }
}
```

**Security**: File permissions set to 0600 (owner read/write only)

## Limitations

- No real-time events / Gateway connection
- No voice channel support
- No server management (create/delete channels, roles)
- No slash commands
- No webhook support
- Plain text messages only (no embeds in v1)
- User tokens only (no bot tokens)

## Troubleshooting

### Authentication fails or no token found

Credentials are normally extracted automatically. If auto-extraction fails, run it manually with debug output:

```bash
agent-discord auth extract --debug
```

Common causes:
- Discord desktop app is not installed or not logged in
- macOS Keychain access was denied (re-run and approve the prompt)
- Discord is not running and LevelDB files are stale

### `agent-discord: command not found`

**`agent-discord` is NOT the npm package name.** The npm package is `agent-messenger`.

If the package is installed globally, use `agent-discord` directly:

```bash
agent-discord server list
```

If the package is NOT installed, use `bunx agent-messenger discord`:

```bash
bunx agent-messenger discord server list
```

**NEVER run `bunx agent-discord`** — it will fail or install a wrong package since `agent-discord` is not the npm package name.

## References

- [Authentication Guide](references/authentication.md)
- [Common Patterns](references/common-patterns.md)


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/authentication.md

```markdown
# Authentication Guide

## Overview

agent-discord uses Discord's user token extracted directly from the Discord desktop application. This provides seamless authentication without manual token management.

## Token Extraction

### Automatic Extraction

The simplest way to authenticate:

```bash
agent-discord auth extract

# Use --debug for troubleshooting extraction issues
agent-discord auth extract --debug
```

This command:
1. Detects your operating system (macOS, Linux, Windows)
2. Locates the Discord desktop app data directory
3. Reads the LevelDB storage containing session data
4. Extracts user token
5. Validates token against Discord API before saving
6. Discovers ALL joined servers
7. Stores credentials securely in `~/.config/agent-messenger/discord-credentials.json`

### Platform-Specific Paths

**macOS:**
```
~/Library/Application Support/discord/
```

**Linux:**
```
~/.config/discord/
```

**Windows:**
```
%APPDATA%\discord\
```

The tool searches within:
- `Local Storage/leveldb/` - Primary token storage

### What Gets Extracted

- **token**: User token (starts with a base64-encoded user ID)
- **servers**: All servers you're a member of

## Multi-Server Management

### List Servers

See all available servers:

```bash
agent-discord server list
```

Output:
```json
[
  {
    "id": "1234567890123456789",
    "name": "My Server",
    "current": true
  },
  {
    "id": "9876543210987654321",
    "name": "Another Server",
    "current": false
  }
]
```

### Switch Server

Change the active server:

```bash
agent-discord server switch 9876543210987654321
```

All subsequent commands will use the selected server until you switch again.

### Current Server

Check which server is active:

```bash
agent-discord server current
```

## Credential Storage

### Location

Credentials are stored in:
```
~/.config/agent-messenger/discord-credentials.json
```

### Format

```json
{
  "token": "user_token_here",
  "current_server": "1234567890123456789",
  "servers": {
    "1234567890123456789": {
      "server_id": "1234567890123456789",
      "server_name": "My Server"
    },
    "9876543210987654321": {
      "server_id": "9876543210987654321",
      "server_name": "Another Server"
    }
  }
}
```

### Security

- File permissions: `0600` (owner read/write only)
- Tokens are stored in plaintext (same as Discord desktop app)
- Keep this file secure - it grants full access to your Discord account

## Authentication Status

Check if you're authenticated:

```bash
agent-discord auth status
```

Output when authenticated:
```json
{
  "authenticated": true,
  "user": "username",
  "current_server": "1234567890123456789",
  "servers_count": 5
}
```

Output when not authenticated:
```json
{
  "error": "Not authenticated. Run \"auth extract\" first."
}
```

## Token Lifecycle

### When Tokens Expire

Discord user tokens can be invalidated when:
- You change your password
- You enable/disable 2FA
- Discord forces a logout
- You manually log out of the desktop app

### Re-authentication

If commands start failing with auth errors:

```bash
# Re-extract credentials
agent-discord auth extract

# Verify it worked
agent-discord auth status
```

## Troubleshooting

### Using Debug Mode

For any extraction issues, run with `--debug` to see detailed information:

```bash
agent-discord auth extract --debug
```

This shows:
- Which Discord directory was found
- Token extraction progress
- Token validation results
- Server discovery details

### "Discord desktop app not found"

**Cause**: Discord desktop app not installed or in non-standard location

**Solution**:
1. Install Discord desktop app
2. Log in to your account
3. Run `agent-discord auth extract` again

### "No Discord token found"

**Cause**: Not logged into Discord or token storage corrupted

**Solution**:
1. Open Discord desktop app
2. Make sure you're logged in (can see your servers)
3. Run `agent-discord auth extract --debug` to see details

### "Permission denied reading Discord data"

**Cause**: Insufficient file system permissions

**Solution** (macOS):
1. Grant Terminal/iTerm full disk access in System Preferences
2. Security & Privacy -> Privacy -> Full Disk Access
3. Add your terminal application

### "Token validation failed" errors

**Cause**: Token expired or invalidated

**Solution**:
```bash
# Re-extract fresh credentials
agent-discord auth extract

# Test authentication
agent-discord auth status
```

## Security Considerations

### What agent-discord Can Access

With extracted credentials, agent-discord has the same permissions as you in Discord:
- Read all channels you have access to
- Send messages as you
- Upload/download files
- Manage reactions
- Access user information
- View server member lists

### What agent-discord Cannot Do

- Access channels you don't have permission for
- Perform admin operations (unless you're an admin)
- Access other users' DMs without existing conversation
- Manage server settings (not implemented)

### Best Practices

1. **Protect credentials.json**: Never commit to version control
2. **Use server switching**: Keep different contexts separate
3. **Re-extract periodically**: Keep tokens fresh
4. **Revoke if compromised**: Change your Discord password to invalidate tokens

## Manual Token Management (Advanced)

If automatic extraction fails, you can manually create the credentials file:

```bash
# Create config directory
mkdir -p ~/.config/agent-messenger

# Create credentials file
cat > ~/.config/agent-messenger/discord-credentials.json << 'EOF'
{
  "token": "YOUR_TOKEN_HERE",
  "current_server": "1234567890123456789",
  "servers": {
    "1234567890123456789": {
      "server_id": "1234567890123456789",
      "server_name": "My Server"
    }
  }
}
EOF

# Set secure permissions
chmod 600 ~/.config/agent-messenger/discord-credentials.json
```

If the user already has a token value, they can populate the file above. Otherwise, always prefer `agent-discord auth extract` to obtain the token automatically from the desktop app.

**Warning**: Self-botting (using user tokens for automation) may violate Discord's Terms of Service. Use responsibly and at your own risk.

```

### references/common-patterns.md

```markdown
# Common Patterns

## Overview

This guide covers typical workflows for AI agents interacting with Discord using agent-discord.

**Important**: Discord uses Snowflake IDs (large numbers like `1234567890123456789`) for channels, messages, and users. You cannot use channel names directly - always get IDs from `channel list` first.

## Pattern 1: Send a Simple Message

**Use case**: Post a notification or update to a channel

```bash
#!/bin/bash

# First, get channel ID from channel list
CHANNELS=$(agent-discord channel list)
CHANNEL_ID=$(echo "$CHANNELS" | jq -r '.[] | select(.name=="general") | .id')

# Send message using channel ID
agent-discord message send "$CHANNEL_ID" "Deployment completed successfully!"

# With error handling
RESULT=$(agent-discord message send "$CHANNEL_ID" "Hello world")
if echo "$RESULT" | jq -e '.id' > /dev/null 2>&1; then
  echo "Message sent!"
else
  echo "Failed: $(echo "$RESULT" | jq -r '.error')"
  exit 1
fi
```

**When to use**: Simple one-off messages after looking up the channel ID.

## Pattern 2: Monitor Channel for New Messages

**Use case**: Watch a channel and respond to new messages

```bash
#!/bin/bash

CHANNEL_ID="1234567890123456789"
LAST_ID=""

while true; do
  # Get latest message
  MESSAGES=$(agent-discord message list "$CHANNEL_ID" --limit 1)
  LATEST_ID=$(echo "$MESSAGES" | jq -r '.[0].id // ""')
  
  # Check if new message
  if [ "$LATEST_ID" != "$LAST_ID" ] && [ -n "$LAST_ID" ]; then
    CONTENT=$(echo "$MESSAGES" | jq -r '.[0].content')
    AUTHOR=$(echo "$MESSAGES" | jq -r '.[0].author')
    
    echo "New message from $AUTHOR: $CONTENT"
    
    # Process message here
    # Example: Respond to mentions
    if echo "$CONTENT" | grep -q "bot"; then
      agent-discord message send "$CHANNEL_ID" "You called?"
    fi
  fi
  
  LAST_ID="$LATEST_ID"
  sleep 5
done
```

**When to use**: Building a simple bot that reacts to messages.

**Limitations**: Polling-based, not real-time. For production bots, use Discord's Gateway API with a proper bot token.

## Pattern 3: Get Server Overview

**Use case**: Understand server state before taking action

```bash
#!/bin/bash

# Get full snapshot
SNAPSHOT=$(agent-discord snapshot)

# Extract key information
SERVER_NAME=$(echo "$SNAPSHOT" | jq -r '.server.name')
CHANNEL_COUNT=$(echo "$SNAPSHOT" | jq -r '.channels | length')
MEMBER_COUNT=$(echo "$SNAPSHOT" | jq -r '.members | length')

echo "Server: $SERVER_NAME"
echo "Channels: $CHANNEL_COUNT"
echo "Members: $MEMBER_COUNT"

# List all text channels
echo -e "\nChannels:"
echo "$SNAPSHOT" | jq -r '.channels[] | "  #\(.name) (\(.id))"'

# List recent activity
echo -e "\nRecent messages:"
echo "$SNAPSHOT" | jq -r '.recent_messages[] | "  [\(.channel_name)] \(.author): \(.content[0:50])"'
```

**When to use**: Initial context gathering, status reports, server summaries.

## Pattern 4: Find Channel by Name

**Use case**: Get channel ID from channel name

```bash
#!/bin/bash

get_channel_id() {
  local channel_name=$1
  
  CHANNELS=$(agent-discord channel list)
  CHANNEL_ID=$(echo "$CHANNELS" | jq -r --arg name "$channel_name" '.[] | select(.name==$name) | .id')
  
  if [ -z "$CHANNEL_ID" ]; then
    echo "Channel #$channel_name not found" >&2
    return 1
  fi
  
  echo "$CHANNEL_ID"
}

# Usage
GENERAL_ID=$(get_channel_id "general")
if [ $? -eq 0 ]; then
  agent-discord message send "$GENERAL_ID" "Hello!"
fi
```

**When to use**: When you know channel name but need the ID.

## Pattern 5: Multi-Channel Broadcast

**Use case**: Send the same message to multiple channels

```bash
#!/bin/bash

MESSAGE="System maintenance in 30 minutes"
CHANNEL_NAMES=("general" "announcements" "dev")

# Get all channels once
CHANNELS=$(agent-discord channel list)

for name in "${CHANNEL_NAMES[@]}"; do
  CHANNEL_ID=$(echo "$CHANNELS" | jq -r --arg n "$name" '.[] | select(.name==$n) | .id')
  
  if [ -z "$CHANNEL_ID" ]; then
    echo "Channel #$name not found, skipping"
    continue
  fi
  
  echo "Posting to #$name..."
  RESULT=$(agent-discord message send "$CHANNEL_ID" "$MESSAGE")
  
  if echo "$RESULT" | jq -e '.id' > /dev/null 2>&1; then
    echo "  Posted to #$name"
  else
    echo "  Failed to post to #$name"
  fi
  
  # Rate limit: Don't spam Discord API
  sleep 1
done
```

**When to use**: Announcements, alerts, status updates across channels.

## Pattern 6: File Upload with Context

**Use case**: Share a file with explanation

```bash
#!/bin/bash

CHANNEL_ID="1234567890123456789"
REPORT_FILE="./daily-report.pdf"

# Upload file
UPLOAD_RESULT=$(agent-discord file upload "$CHANNEL_ID" "$REPORT_FILE")

if echo "$UPLOAD_RESULT" | jq -e '.id' > /dev/null 2>&1; then
  FILE_ID=$(echo "$UPLOAD_RESULT" | jq -r '.id')
  echo "File uploaded: $FILE_ID"
  
  # Send context message
  agent-discord message send "$CHANNEL_ID" "Daily report is ready! Key highlights:
- 95% test coverage
- 3 bugs fixed
- 2 new features deployed"
else
  echo "Upload failed: $(echo "$UPLOAD_RESULT" | jq -r '.error')"
  exit 1
fi
```

**When to use**: Automated reporting, log sharing, artifact distribution.

## Pattern 7: User Lookup and Mention

**Use case**: Find a user and mention them in a message

```bash
#!/bin/bash

CHANNEL_ID="1234567890123456789"
USERNAME="john"

# Get server members
USERS=$(agent-discord user list)
USER_ID=$(echo "$USERS" | jq -r --arg name "$USERNAME" '.[] | select(.username | contains($name)) | .id' | head -1)

if [ -z "$USER_ID" ]; then
  echo "User $USERNAME not found"
  exit 1
fi

# Send message with mention
agent-discord message send "$CHANNEL_ID" "Hey <@$USER_ID>, the build is ready for review!"
```

**When to use**: Notifications, task assignments, code review requests.

**Note**: Discord mentions use format `<@USER_ID>`.

## Pattern 8: Reaction-Based Workflow

**Use case**: Use reactions as simple state indicators

```bash
#!/bin/bash

CHANNEL_ID="1234567890123456789"

# Send deployment message
RESULT=$(agent-discord message send "$CHANNEL_ID" "Deploying v2.1.0 to production...")
MSG_ID=$(echo "$RESULT" | jq -r '.id')

# Mark as in-progress
agent-discord reaction add "$CHANNEL_ID" "$MSG_ID" "hourglass"

# Simulate deployment
sleep 5

# Remove in-progress, add success
agent-discord reaction remove "$CHANNEL_ID" "$MSG_ID" "hourglass"
agent-discord reaction add "$CHANNEL_ID" "$MSG_ID" "white_check_mark"

# Send completion message
agent-discord message send "$CHANNEL_ID" "Deployed v2.1.0 to production successfully!"
```

**When to use**: Visual status tracking, workflow states, quick acknowledgments.

## Pattern 9: Error Handling and Retry

**Use case**: Robust message sending with retries

```bash
#!/bin/bash

send_with_retry() {
  local channel_id=$1
  local message=$2
  local max_attempts=3
  local attempt=1
  
  while [ $attempt -le $max_attempts ]; do
    echo "Attempt $attempt/$max_attempts..."
    
    RESULT=$(agent-discord message send "$channel_id" "$message")
    
    if echo "$RESULT" | jq -e '.id' > /dev/null 2>&1; then
      echo "Message sent successfully!"
      return 0
    fi
    
    ERROR=$(echo "$RESULT" | jq -r '.error // "Unknown error"')
    echo "Failed: $ERROR"
    
    # Don't retry on certain errors
    if echo "$ERROR" | grep -q "Unknown Channel"; then
      echo "Channel not found - not retrying"
      return 1
    fi
    
    if [ $attempt -lt $max_attempts ]; then
      sleep $((attempt * 2))  # Exponential backoff
    fi
    
    attempt=$((attempt + 1))
  done
  
  echo "Failed after $max_attempts attempts"
  return 1
}

# Usage
CHANNEL_ID="1234567890123456789"
send_with_retry "$CHANNEL_ID" "Important message!"
```

**When to use**: Production scripts, critical notifications, unreliable networks.

## Pattern 10: Switch Servers for Operations

**Use case**: Work with multiple Discord servers

```bash
#!/bin/bash

# List all servers
SERVERS=$(agent-discord server list)
echo "Available servers:"
echo "$SERVERS" | jq -r '.[] | "  \(.name) (\(.id)) \(if .current then "[current]" else "" end)"'

# Switch to a specific server
TARGET_SERVER=$(echo "$SERVERS" | jq -r '.[] | select(.name | contains("Production")) | .id')
if [ -n "$TARGET_SERVER" ]; then
  agent-discord server switch "$TARGET_SERVER"
  echo "Switched to Production server"
fi

# Now operations use the new server
agent-discord channel list
```

**When to use**: Managing multiple servers, cross-server operations.

## Best Practices

### 1. Always Get Channel IDs First

```bash
# Good - look up channel ID
CHANNELS=$(agent-discord channel list)
CHANNEL_ID=$(echo "$CHANNELS" | jq -r '.[] | select(.name=="general") | .id')
agent-discord message send "$CHANNEL_ID" "Hello"

# Bad - hardcoded IDs without documentation
agent-discord message send 1234567890123456789 "Hello"
```

### 2. Check for Success

```bash
# Good
RESULT=$(agent-discord message send "$CHANNEL_ID" "Hello")
if echo "$RESULT" | jq -e '.id' > /dev/null 2>&1; then
  echo "Success!"
else
  echo "Failed: $(echo "$RESULT" | jq -r '.error')"
fi

# Bad
agent-discord message send "$CHANNEL_ID" "Hello"  # No error checking
```

### 3. Rate Limit Your Requests

```bash
# Good - respect Discord API limits
for channel_id in "${CHANNEL_IDS[@]}"; do
  agent-discord message send "$channel_id" "$MESSAGE"
  sleep 1  # 1 second between requests
done

# Bad - rapid-fire requests
for channel_id in "${CHANNEL_IDS[@]}"; do
  agent-discord message send "$channel_id" "$MESSAGE"
done
```

### 4. Cache Channel Lists

```bash
# Good - fetch once, reuse
CHANNELS=$(agent-discord channel list)
for name in "${CHANNEL_NAMES[@]}"; do
  id=$(echo "$CHANNELS" | jq -r --arg n "$name" '.[] | select(.name==$n) | .id')
  agent-discord message send "$id" "$MESSAGE"
done

# Bad - fetch repeatedly
for name in "${CHANNEL_NAMES[@]}"; do
  CHANNELS=$(agent-discord channel list)  # Wasteful!
  id=$(echo "$CHANNELS" | jq -r --arg n "$name" '.[] | select(.name==$n) | .id')
  agent-discord message send "$id" "$MESSAGE"
done
```

### 5. Use Reactions for Quick Feedback

```bash
# Good - reactions are lightweight
agent-discord reaction add "$CHANNEL_ID" "$MSG_ID" "thumbsup"

# Okay - but more verbose for simple acknowledgment
agent-discord message send "$CHANNEL_ID" "Acknowledged!"
```

## Anti-Patterns

### Don't Poll Too Frequently

```bash
# Bad - polls every second (may get rate limited)
while true; do
  agent-discord message list "$CHANNEL_ID" --limit 1
  sleep 1
done

# Good - reasonable interval
while true; do
  agent-discord message list "$CHANNEL_ID" --limit 1
  sleep 10  # 10 seconds
done
```

### Don't Ignore Errors

```bash
# Bad
agent-discord message send "$CHANNEL_ID" "Hello"
# Continues even if it failed

# Good
RESULT=$(agent-discord message send "$CHANNEL_ID" "Hello")
if ! echo "$RESULT" | jq -e '.id' > /dev/null 2>&1; then
  echo "Failed to send message"
  exit 1
fi
```

### Don't Spam Channels

```bash
# Bad - sends 100 messages
for i in {1..100}; do
  agent-discord message send "$CHANNEL_ID" "Message $i"
done

# Good - batch into single message
MESSAGE="Updates:"
for i in {1..100}; do
  MESSAGE="$MESSAGE\n$i. Item $i"
done
agent-discord message send "$CHANNEL_ID" "$MESSAGE"
```

## See Also

- [Authentication Guide](authentication.md) - Setting up credentials
- [Templates](../templates/) - Runnable example scripts

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "devxoul",
  "slug": "agent-discord",
  "displayName": "Agent Discord",
  "latest": {
    "version": "1.10.5",
    "publishedAt": 1772811604649,
    "commit": "https://github.com/openclaw/skills/commit/e02d6e83b8adffc9a57e8d1182534e8c13e59951"
  },
  "history": [
    {
      "version": "1.9.2",
      "publishedAt": 1772690019066,
      "commit": "https://github.com/openclaw/skills/commit/c1fa489444759a6fd37f70689635df477879b20d"
    },
    {
      "version": "1.8.1",
      "publishedAt": 1772601711638,
      "commit": "https://github.com/openclaw/skills/commit/a9f23f87b8c80516cf3a88c83456a27de59c625a"
    }
  ]
}

```