Discord servers need more than static bots — they need intelligent automation that understands context, manages workflows, and enhances team productivity. OpenClaw's Discord integration transforms your server into an AI-powered collaboration hub.
This guide covers everything from basic bot setup to advanced automation workflows that make your Discord server work smarter, not harder.
Why Build an OpenClaw Discord Bot?
Traditional Discord bots execute simple commands. OpenClaw Discord bots understand natural language, learn from interactions, and coordinate complex workflows across your entire tech stack.
Intelligent moderation: AI-powered content filtering and user management Project coordination: Connect Discord to GitHub, Jira, and project management tools Meeting automation: Schedule, prepare, and follow up on team meetings Knowledge management: Store and retrieve team knowledge through conversations Workflow triggers: Start complex automation from simple Discord commands
Prerequisites and Setup
Before building your OpenClaw Discord bot, ensure you have:
- OpenClaw installation (complete setup guide)
- Discord Developer Account and server admin access
- Python 3.9+ with discord.py library
- Basic understanding of Discord server management
- API keys for any external services you want to integrate
Required Dependencies
# Install Discord bot dependencies
pip install discord.py==2.3.2
pip install aiohttp==3.9.1
pip install asyncio-throttle==1.0.2
# OpenClaw Discord integration
pip install openclaw[discord]
Step 1: Create Discord Application and Bot
Discord Developer Portal Setup
- Visit Discord Developer Portal: https://discord.com/developers/applications
- Create New Application: Click "New Application" and name your bot
- Navigate to Bot section: Create a bot user for your application
- Copy Bot Token: Save this securely — it's your authentication key
- Configure Bot Permissions: Enable necessary permissions for your use case
Bot Permissions Checklist
For comprehensive OpenClaw integration, enable these permissions:
Text Permissions:
✅ Send Messages
✅ Send Messages in Threads
✅ Manage Messages
✅ Embed Links
✅ Attach Files
✅ Read Message History
✅ Add Reactions
✅ Use Slash Commands
Voice Permissions (optional):
✅ Connect
✅ Speak
✅ Use Voice Activity
Advanced Permissions:
✅ Manage Channels (for dynamic channel creation)
✅ Manage Roles (for automated role management)
✅ Kick Members (for moderation)
✅ Ban Members (for severe violations)
Generate Bot Invite URL
In the OAuth2 section, select:
- Scopes: bot, applications.commands
- Permissions: Copy the generated URL to invite your bot
Step 2: Configure OpenClaw Discord Integration
Update OpenClaw Configuration
Add Discord configuration to ~/.openclaw/config.yaml:
# Discord Integration Configuration
integrations:
discord:
enabled: true
bot_token: "YOUR_BOT_TOKEN_HERE"
guild_ids:
- 123456789012345678 # Your server ID(s)
command_prefix: "!"
activity_type: "watching"
activity_name: "for /help"
intents:
- messages
- guilds
- message_content
- members
moderation:
enabled: true
auto_moderate: true
log_channel: "mod-logs"
features:
slash_commands: true
context_menus: true
auto_responses: true
# Agent configuration for Discord
agents:
discord_agent:
name: "DiscordAssistant"
model: "gpt-4"
temperature: 0.7
integrations:
- discord
- github # Optional: for project management
- calendar # Optional: for meeting scheduling
personality: |
You are a helpful Discord bot assistant focused on team productivity.
Be concise but friendly. Use Discord markdown formatting.
Always maintain a professional but approachable tone.
Environment Variables
Update your .env file:
# Discord Configuration
DISCORD_BOT_TOKEN=your_bot_token_here
DISCORD_GUILD_ID=your_server_id_here
# Optional integrations
GITHUB_TOKEN=your_github_token
CALENDAR_API_KEY=your_calendar_api_key
Step 3: Build Core Discord Integration
Main Discord Integration Class
Create ~/.openclaw/integrations/discord_integration.py:
import discord
from discord.ext import commands, tasks
from discord import app_commands
import asyncio
import logging
from datetime import datetime, timedelta
from openclaw.core import Integration, Agent
class OpenClawDiscordBot(commands.Bot):
"""Enhanced Discord bot with OpenClaw integration"""
def __init__(self, agent: Agent, config: dict):
# Configure intents
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
intents.presences = True
# Initialize bot
super().__init__(
command_prefix=config.get('command_prefix', '!'),
intents=intents,
help_command=None
)
self.agent = agent
self.config = config
self.guild_ids = config.get('guild_ids', [])
async def setup_hook(self):
"""Called when the bot is starting up"""
# Load cogs (command groups)
await self.load_extension('cogs.general')
await self.load_extension('cogs.moderation')
await self.load_extension('cogs.project_management')
# Sync slash commands
for guild_id in self.guild_ids:
guild = discord.Object(id=guild_id)
self.tree.copy_global_to(guild=guild)
await self.tree.sync(guild=guild)
# Start background tasks
self.update_presence.start()
self.cleanup_old_messages.start()
logging.info("OpenClaw Discord bot setup complete")
async def on_ready(self):
"""Called when bot comes online"""
logging.info(f'{self.user} has connected to Discord!')
# Set bot presence
activity = discord.Activity(
type=discord.ActivityType.watching,
name=self.config.get('activity_name', 'for /help')
)
await self.change_presence(activity=activity)
async def on_message(self, message):
"""Handle incoming messages"""
# Ignore bot messages
if message.author.bot:
return
# Process commands first
await self.process_commands(message)
# Handle natural language interactions
if self.user.mentioned_in(message) or isinstance(message.channel, discord.DMChannel):
await self._handle_ai_interaction(message)
async def _handle_ai_interaction(self, message):
"""Process natural language message with AI"""
try:
# Show typing indicator
async with message.channel.typing():
# Extract context for AI
context = await self._build_message_context(message)
# Generate AI response
prompt = f"""
You are a Discord bot assistant. Respond to this message:
User: {message.author.display_name}
Message: {message.content}
Channel: {message.channel.name}
Context: {context}
Provide a helpful response using Discord markdown.
Keep responses under 2000 characters.
"""
response = await self.agent.generate_response(prompt)
# Send response
await message.reply(response[:2000])
except Exception as e:
logging.error(f"AI interaction error: {e}")
await message.reply("Sorry, I encountered an error processing your request.")
async def _build_message_context(self, message):
"""Build context for AI processing"""
context = {
'channel_name': message.channel.name,
'guild_name': message.guild.name if message.guild else 'DM',
'author_roles': [role.name for role in message.author.roles] if message.guild else [],
'recent_messages': []
}
# Get recent messages for context
if hasattr(message.channel, 'history'):
async for msg in message.channel.history(limit=5, before=message):
if not msg.author.bot:
context['recent_messages'].append({
'author': msg.author.display_name,
'content': msg.content[:100]
})
return context
@tasks.loop(minutes=15)
async def update_presence(self):
"""Update bot presence with status info"""
try:
# Get agent status
status = await self.agent.get_status()
activities = [
f"for /help",
f"{status.get('active_skills', 0)} skills active",
f"{len(self.guilds)} servers",
f"OpenClaw v{status.get('version', '1.0')}"
]
# Cycle through different activities
activity_text = activities[datetime.now().minute % len(activities)]
activity = discord.Activity(type=discord.ActivityType.watching, name=activity_text)
await self.change_presence(activity=activity)
except Exception as e:
logging.error(f"Presence update error: {e}")
@tasks.loop(hours=24)
async def cleanup_old_messages(self):
"""Daily cleanup of old bot messages"""
for guild in self.guilds:
for channel in guild.text_channels:
if channel.permissions_for(guild.me).manage_messages:
try:
# Delete bot messages older than 7 days
cutoff = datetime.now() - timedelta(days=7)
async for message in channel.history(after=cutoff):
if message.author == self.user and 'temp' in message.content.lower():
await message.delete()
except discord.Forbidden:
continue
class DiscordIntegration(Integration):
"""Main Discord integration for OpenClaw"""
def __init__(self, agent: Agent, config: dict):
super().__init__(agent, config)
self.bot = OpenClawDiscordBot(agent, config)
self.token = config.get('bot_token')
async def initialize(self):
"""Start Discord bot"""
try:
await self.bot.start(self.token)
except Exception as e:
logging.error(f"Discord bot failed to start: {e}")
raise
async def send_message(self, channel_id: int, content: str, embed=None):
"""Send message to specific channel"""
channel = self.bot.get_channel(channel_id)
if channel:
await channel.send(content=content, embed=embed)
async def create_embed(self, title: str, description: str, color=0x00ff00):
"""Create Discord embed"""
embed = discord.Embed(
title=title,
description=description,
color=color,
timestamp=datetime.now()
)
embed.set_footer(text="OpenClaw Bot", icon_url=self.bot.user.avatar.url)
return embed
async def cleanup(self):
"""Cleanup Discord integration"""
await self.bot.close()
# Register integration
def register_integration(agent, config):
return DiscordIntegration(agent, config)
Step 4: Create Slash Commands and Cogs
General Commands Cog
Create ~/.openclaw/cogs/general.py:
import discord
from discord.ext import commands
from discord import app_commands
class GeneralCog(commands.Cog):
"""General purpose Discord commands"""
def __init__(self, bot):
self.bot = bot
self.agent = bot.agent
@app_commands.command(name="status", description="Get OpenClaw agent status")
async def status(self, interaction: discord.Interaction):
"""Display bot and agent status"""
try:
await interaction.response.defer()
# Get comprehensive status
status = await self.agent.get_status()
embed = discord.Embed(
title="🤖 OpenClaw Bot Status",
color=0x00ff00,
timestamp=discord.utils.utcnow()
)
embed.add_field(
name="🔧 Agent Status",
value=f"**Name:** {status['name']}\n**Uptime:** {status['uptime']}\n**Memory:** {status['memory_usage']}",
inline=True
)
embed.add_field(
name="📊 Server Stats",
value=f"**Servers:** {len(self.bot.guilds)}\n**Latency:** {round(self.bot.latency * 1000)}ms",
inline=True
)
embed.add_field(
name="🛠️ Active Skills",
value=f"**Count:** {len(status.get('active_skills', []))}\n**Last Run:** {status.get('last_skill_run', 'Never')}",
inline=True
)
await interaction.followup.send(embed=embed)
except Exception as e:
await interaction.followup.send(f"❌ Error getting status: {str(e)}")
@app_commands.command(name="skills", description="List available OpenClaw skills")
async def skills(self, interaction: discord.Interaction):
"""List available skills"""
try:
await interaction.response.defer()
skills = await self.agent.get_available_skills()
embed = discord.Embed(
title="🛠️ Available Skills",
description="OpenClaw skills available on this server:",
color=0x0099ff
)
for skill in skills:
embed.add_field(
name=f"**{skill['name']}**",
value=f"{skill['description']}\n`/run {skill['name']}`",
inline=False
)
await interaction.followup.send(embed=embed)
except Exception as e:
await interaction.followup.send(f"❌ Error listing skills: {str(e)}")
@app_commands.command(name="run", description="Execute an OpenClaw skill")
@app_commands.describe(skill="Skill name to execute")
async def run_skill(self, interaction: discord.Interaction, skill: str):
"""Execute a specific skill"""
try:
await interaction.response.defer()
# Execute skill
result = await self.agent.run_skill(skill)
if result['status'] == 'success':
embed = discord.Embed(
title=f"✅ Skill Executed: {skill}",
description=result.get('summary', 'Skill completed successfully'),
color=0x00ff00
)
if result.get('output'):
embed.add_field(
name="📋 Output",
value=result['output'][:1000], # Limit to 1000 chars
inline=False
)
else:
embed = discord.Embed(
title=f"❌ Skill Failed: {skill}",
description=result.get('message', 'Unknown error'),
color=0xff0000
)
await interaction.followup.send(embed=embed)
except Exception as e:
await interaction.followup.send(f"❌ Error executing skill: {str(e)}")
@app_commands.command(name="help", description="Get help with OpenClaw bot")
async def help(self, interaction: discord.Interaction):
"""Display help information"""
embed = discord.Embed(
title="🤖 OpenClaw Bot Help",
description="AI-powered automation for your Discord server",
color=0x7289da
)
embed.add_field(
name="📋 Slash Commands",
value="`/status` - Bot status\n`/skills` - List skills\n`/run` - Execute skill\n`/help` - This help",
inline=False
)
embed.add_field(
name="💬 Natural Language",
value="Mention me or DM me for AI assistance:\n• \"@OpenClaw what's my schedule?\"\n• \"Help me plan the sprint\"",
inline=False
)
embed.add_field(
name="🔧 Moderation",
value="`/moderate` - Content moderation\n`/cleanup` - Channel cleanup\n`/audit` - Server audit",
inline=False
)
embed.add_field(
name="📊 Project Management",
value="`/github` - GitHub integration\n`/meeting` - Meeting tools\n`/standup` - Daily standups",
inline=False
)
await interaction.response.send_message(embed=embed)
async def setup(bot):
await bot.add_cog(GeneralCog(bot))
Project Management Cog
Create ~/.openclaw/cogs/project_management.py:
import discord
from discord.ext import commands
from discord import app_commands
from datetime import datetime, timedelta
class ProjectManagementCog(commands.Cog):
"""Project management and team coordination"""
def __init__(self, bot):
self.bot = bot
self.agent = bot.agent
@app_commands.command(name="github", description="GitHub repository operations")
@app_commands.describe(
action="Action to perform",
repo="Repository name (owner/repo)",
query="Search query or additional parameters"
)
async def github(self, interaction: discord.Interaction, action: str, repo: str = None, query: str = None):
"""GitHub integration commands"""
try:
await interaction.response.defer()
github_skill = "github_integration"
result = await self.agent.run_skill(github_skill, {
'action': action,
'repo': repo,
'query': query,
'user': interaction.user.display_name
})
if result['status'] == 'success':
embed = discord.Embed(
title=f"📚 GitHub: {action.title()}",
description=result.get('summary', 'Operation completed'),
color=0x24292e
)
if result.get('data'):
# Format GitHub data based on action
if action == 'issues':
for issue in result['data'][:5]: # Show top 5
embed.add_field(
name=f"#{issue['number']}: {issue['title']}",
value=f"**Status:** {issue['state']}\n**Author:** {issue['user']['login']}",
inline=False
)
elif action == 'prs':
for pr in result['data'][:5]:
embed.add_field(
name=f"#{pr['number']}: {pr['title']}",
value=f"**Status:** {pr['state']}\n**Author:** {pr['user']['login']}",
inline=False
)
await interaction.followup.send(embed=embed)
else:
await interaction.followup.send(f"❌ GitHub operation failed: {result['message']}")
except Exception as e:
await interaction.followup.send(f"❌ Error with GitHub integration: {str(e)}")
@app_commands.command(name="meeting", description="Schedule or manage meetings")
@app_commands.describe(
action="Meeting action (schedule, upcoming, notes)",
title="Meeting title",
time="Meeting time (e.g., '2:00 PM today')"
)
async def meeting(self, interaction: discord.Interaction, action: str, title: str = None, time: str = None):
"""Meeting management"""
try:
await interaction.response.defer()
if action == "schedule":
# Schedule new meeting
meeting_data = {
'title': title,
'time': time,
'organizer': interaction.user.display_name,
'channel': interaction.channel.name
}
result = await self.agent.run_skill('meeting_scheduler', meeting_data)
if result['status'] == 'success':
embed = discord.Embed(
title="📅 Meeting Scheduled",
description=f"**{title}**\nScheduled for {time}",
color=0x00ff00
)
embed.add_field(
name="📋 Details",
value=f"**Organizer:** {interaction.user.mention}\n**Channel:** {interaction.channel.mention}",
inline=False
)
else:
embed = discord.Embed(
title="❌ Scheduling Failed",
description=result.get('message', 'Unknown error'),
color=0xff0000
)
elif action == "upcoming":
# Show upcoming meetings
result = await self.agent.run_skill('upcoming_meetings')
embed = discord.Embed(
title="📅 Upcoming Meetings",
color=0x0099ff
)
if result['status'] == 'success' and result.get('meetings'):
for meeting in result['meetings'][:10]:
embed.add_field(
name=meeting['title'],
value=f"⏰ {meeting['time']}\n👥 {meeting['attendees']} attendees",
inline=True
)
else:
embed.description = "No upcoming meetings found."
await interaction.followup.send(embed=embed)
except Exception as e:
await interaction.followup.send(f"❌ Meeting error: {str(e)}")
@app_commands.command(name="standup", description="Daily standup management")
@app_commands.describe(
action="Standup action (start, status, summary)",
update="Your status update"
)
async def standup(self, interaction: discord.Interaction, action: str, update: str = None):
"""Daily standup automation"""
try:
await interaction.response.defer()
if action == "start":
# Start standup collection
embed = discord.Embed(
title="🚀 Daily Standup Started",
description="Team members, please share your updates using `/standup status`",
color=0xff9900
)
embed.add_field(
name="📋 Format",
value="• Yesterday: What did you accomplish?\n• Today: What are you working on?\n• Blockers: Any obstacles?",
inline=False
)
# Start collection process
await self.agent.run_skill('start_standup', {
'channel_id': interaction.channel.id,
'organizer': interaction.user.id
})
elif action == "status":
# Submit individual status
if not update:
await interaction.followup.send("❌ Please provide your status update.")
return
result = await self.agent.run_skill('submit_standup', {
'user_id': interaction.user.id,
'user_name': interaction.user.display_name,
'update': update,
'channel_id': interaction.channel.id
})
embed = discord.Embed(
title="✅ Status Submitted",
description=f"Thanks {interaction.user.display_name}! Your update has been recorded.",
color=0x00ff00
)
elif action == "summary":
# Generate standup summary
result = await self.agent.run_skill('standup_summary', {
'channel_id': interaction.channel.id
})
if result['status'] == 'success':
embed = discord.Embed(
title="📊 Standup Summary",
description=result['summary'],
color=0x7289da
)
else:
embed = discord.Embed(
title="❌ Summary Failed",
description=result.get('message', 'No standup data found'),
color=0xff0000
)
await interaction.followup.send(embed=embed)
except Exception as e:
await interaction.followup.send(f"❌ Standup error: {str(e)}")
async def setup(bot):
await bot.add_cog(ProjectManagementCog(bot))
Step 5: Advanced Features and Automation
Intelligent Moderation
Create ~/.openclaw/skills/discord_moderation.py:
from openclaw.core import Skill
import discord
import re
from datetime import datetime, timedelta
class DiscordModerationSkill(Skill):
"""AI-powered content moderation for Discord"""
name = "discord_moderation"
description = "Intelligent content moderation using AI analysis"
async def execute(self, message_content: str, author_info: dict, channel_info: dict, **kwargs):
"""Analyze content for moderation"""
try:
# AI analysis of message content
moderation_prompt = f"""
Analyze this Discord message for moderation concerns:
Content: "{message_content}"
Author: {author_info.get('display_name')} (roles: {author_info.get('roles', [])})
Channel: #{channel_info.get('name')}
Check for:
1. Hate speech or harassment
2. Spam or repetitive content
3. Off-topic content
4. Inappropriate language for server context
5. Self-promotion or advertising
Respond with JSON:
{{
"violation": true/false,
"severity": "low/medium/high",
"category": "spam/harassment/off-topic/inappropriate/advertising",
"confidence": 0.0-1.0,
"reason": "explanation",
"action": "none/warn/timeout/kick/ban"
}}
"""
analysis = await self.agent.generate_response(moderation_prompt)
# Parse AI response
import json
try:
result = json.loads(analysis)
except:
result = {"violation": False, "reason": "Analysis failed"}
# Take action based on analysis
if result.get('violation') and result.get('confidence', 0) > 0.7:
action_taken = await self._execute_moderation_action(
result.get('action', 'none'),
author_info,
channel_info,
result.get('reason')
)
result['action_taken'] = action_taken
return {
"status": "success",
"analysis": result,
"timestamp": datetime.now().isoformat()
}
except Exception as e:
return {"status": "error", "message": str(e)}
async def _execute_moderation_action(self, action, author_info, channel_info, reason):
"""Execute moderation action"""
discord_integration = self.agent.get_integration('discord')
if action == "warn":
# Send warning to user
warning_msg = f"⚠️ **Warning**: {reason}\nPlease review server rules."
await discord_integration.send_dm(author_info['id'], warning_msg)
return f"Warning sent to {author_info['display_name']}"
elif action == "timeout":
# Timeout user (requires timeout permission)
await discord_integration.timeout_user(
author_info['id'],
channel_info['guild_id'],
duration=timedelta(minutes=10),
reason=reason
)
return f"Timed out {author_info['display_name']} for 10 minutes"
return "No action taken"
Smart Channel Management
Create ~/.openclaw/skills/discord_channel_manager.py:
class DiscordChannelManagerSkill(Skill):
"""Intelligent Discord channel management"""
name = "discord_channel_manager"
async def execute(self, action: str, **kwargs):
"""Manage Discord channels intelligently"""
discord_integration = self.agent.get_integration('discord')
if action == "cleanup_inactive":
return await self._cleanup_inactive_channels()
elif action == "create_project_channels":
return await self._create_project_channels(kwargs)
elif action == "archive_completed_projects":
return await self._archive_completed_projects()
async def _cleanup_inactive_channels(self):
"""Archive channels with no recent activity"""
cutoff_date = datetime.now() - timedelta(days=30)
inactive_channels = []
for guild in self.bot.guilds:
for channel in guild.text_channels:
if channel.category and "archive" in channel.category.name.lower():
continue
try:
# Check last message date
async for message in channel.history(limit=1):
if message.created_at < cutoff_date:
inactive_channels.append(channel)
break
else:
# No messages found - very inactive
inactive_channels.append(channel)
except discord.Forbidden:
continue
# Move to archive category
archive_category = discord.utils.get(guild.categories, name="📁 Archived")
if not archive_category:
archive_category = await guild.create_category("📁 Archived")
archived_count = 0
for channel in inactive_channels[:5]: # Limit to 5 per run
try:
await channel.edit(category=archive_category)
archived_count += 1
except discord.Forbidden:
continue
return {
"status": "success",
"archived_count": archived_count,
"summary": f"Archived {archived_count} inactive channels"
}
async def _create_project_channels(self, project_info):
"""Create channels for new projects"""
guild_id = project_info.get('guild_id')
project_name = project_info.get('project_name')
team_members = project_info.get('team_members', [])
guild = self.bot.get_guild(guild_id)
if not guild:
return {"status": "error", "message": "Guild not found"}
# Create project category
category_name = f"🚀 {project_name}"
category = await guild.create_category(category_name)
# Create channels
channels_created = []
# General discussion
general_channel = await guild.create_text_channel(
f"{project_name}-general",
category=category,
topic=f"General discussion for {project_name}"
)
channels_created.append(general_channel)
# Development updates
dev_channel = await guild.create_text_channel(
f"{project_name}-dev",
category=category,
topic=f"Development updates and technical discussions"
)
channels_created.append(dev_channel)
# Planning and meetings
planning_channel = await guild.create_text_channel(
f"{project_name}-planning",
category=category,
topic=f"Sprint planning, meetings, and project coordination"
)
channels_created.append(planning_channel)
return {
"status": "success",
"channels_created": len(channels_created),
"category": category.name,
"summary": f"Created project workspace for {project_name}"
}
Step 6: Production Deployment
Docker Configuration
Create Dockerfile for production deployment:
FROM python:3.11-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Copy requirements and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
RUN pip install -e .
# Create non-root user
RUN useradd -m -u 1000 openclaw && chown -R openclaw:openclaw /app
USER openclaw
# Expose port for health checks
EXPOSE 8080
CMD ["python", "-m", "openclaw.integrations.discord_bot"]
Docker Compose Setup
version: '3.8'
services:
openclaw-discord:
build: .
environment:
- DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN}
- OPENAI_API_KEY=${OPENAI_API_KEY}
- GITHUB_TOKEN=${GITHUB_TOKEN}
volumes:
- ./data:/app/data
- ./logs:/app/logs
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
networks:
- openclaw-network
# Redis for caching and session management
redis:
image: redis:7-alpine
restart: unless-stopped
networks:
- openclaw-network
networks:
openclaw-network:
driver: bridge
Monitoring and Health Checks
Add health check endpoint to your bot:
from aiohttp import web
async def health_check(request):
"""Health check endpoint for monitoring"""
bot_status = {
'status': 'healthy' if bot.is_ready() else 'unhealthy',
'latency': round(bot.latency * 1000),
'guilds': len(bot.guilds),
'uptime': str(datetime.now() - start_time)
}
return web.json_response(bot_status)
# Add to your bot initialization
app = web.Application()
app.router.add_get('/health', health_check)
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, '0.0.0.0', 8080)
await site.start()
Advanced Integration Examples
GitHub Issue Automation
@commands.Cog.listener()
async def on_message(self, message):
"""Auto-create GitHub issues from Discord messages"""
if message.content.startswith("!issue"):
# Extract issue details from message
issue_text = message.content[6:].strip()
# Use AI to structure the issue
structured_issue = await self.agent.generate_response(f"""
Convert this Discord message into a GitHub issue:
"{issue_text}"
Provide:
- Title (concise)
- Description (detailed)
- Labels (bug, feature, enhancement, etc.)
- Priority (low, medium, high)
Format as JSON.
""")
# Create GitHub issue via OpenClaw skill
result = await self.agent.run_skill('create_github_issue', {
'repo': 'your-org/your-repo',
'issue_data': structured_issue,
'creator': message.author.display_name
})
if result['status'] == 'success':
await message.reply(f"✅ Issue created: {result['url']}")
Meeting Bot Integration
class MeetingBot(commands.Cog):
"""AI-powered meeting assistant"""
@app_commands.command(name="meeting-prep")
async def meeting_prep(self, interaction: discord.Interaction, meeting_name: str):
"""Prepare for upcoming meeting"""
# Get meeting details from calendar
meeting_data = await self.agent.run_skill('get_meeting_info', {
'meeting_name': meeting_name
})
if meeting_data['status'] == 'success':
# Generate prep materials
prep_materials = await self.agent.generate_response(f"""
Create meeting prep materials for:
{meeting_data['details']}
Include:
- Agenda items
- Key discussion points
- Action items from previous meetings
- Relevant documents/links
""")
# Send to private thread
thread = await interaction.channel.create_thread(
name=f"Meeting Prep: {meeting_name}",
message=await interaction.original_response()
)
await thread.send(prep_materials)
Troubleshooting and Best Practices
Common Issues and Solutions
Bot Not Responding to Commands:
# Debug command processing
@bot.event
async def on_command_error(ctx, error):
logging.error(f"Command error: {error}")
await ctx.send(f"Command error: {str(error)}")
Permission Issues:
# Check bot permissions before operations
async def check_permissions(channel, required_perms):
bot_perms = channel.permissions_for(channel.guild.me)
missing = [perm for perm in required_perms if not getattr(bot_perms, perm)]
if missing:
raise discord.Forbidden(f"Missing permissions: {', '.join(missing)}")
Rate Limit Management:
from discord.ext import commands
import asyncio
# Implement exponential backoff
async def safe_send_message(channel, content, max_retries=3):
for attempt in range(max_retries):
try:
return await channel.send(content)
except discord.HTTPException as e:
if e.status == 429: # Rate limited
retry_after = e.retry_after or (2 ** attempt)
await asyncio.sleep(retry_after)
else:
raise
raise discord.HTTPException("Max retries exceeded")
Security Best Practices
- Token Security: Store bot tokens in environment variables, never in code
- Permission Principle: Grant minimum required permissions only
- Input Validation: Sanitize all user inputs before processing
- Rate Limiting: Implement per-user rate limiting for commands
- Audit Logging: Log all moderation actions and admin commands
Performance Optimization
- Caching: Cache frequently accessed data (guild info, user roles)
- Async Operations: Use async/await for all Discord operations
- Message Batching: Batch multiple operations where possible
- Resource Limits: Set limits on AI processing and API calls
Why OpenClaw Discord Bot vs. Alternatives
OpenClaw Discord bots offer unique advantages over traditional Discord bot frameworks:
AI-Native: Built-in natural language processing and intelligent responses Workflow Integration: Connect Discord to your entire tech stack seamlessly Learning Capability: Bots improve over time based on server interactions Custom Logic: Full programming control for complex automation scenarios
For teams wanting advanced Discord automation without the technical complexity, consider MrDelegate's team automation features — offering similar AI-powered capabilities with zero setup required.
Start your free trial to experience AI-powered team automation that works across all your platforms.
Next Steps and Advanced Features
With your OpenClaw Discord bot running, consider these advanced enhancements:
- Voice channel automation for meeting transcription and summaries
- Cross-platform notifications linking Discord to email, Slack, and mobile
- Custom dashboard for server analytics and bot performance metrics
- Multi-server orchestration for managing multiple Discord communities
- Advanced AI personalities tailored to your team's communication style
Your Discord server becomes more than a chat platform — it transforms into an intelligent command center for your entire team's workflow.
Your AI executive assistant is ready.
Morning brief at 7am. Inbox triaged overnight. Calendar protected. Dedicated VPS. No Docker. Live in 60 seconds.