How to Make a Discord Bot with AI (Claude/GPT)
Build an intelligent Discord bot powered by Claude or GPT-4. Step-by-step tutorial with full code examples, rate limiting, and deployment options.
Molted Team
molted.cloud
Build an intelligent Discord bot powered by Claude or GPT-4. Step-by-step tutorial with full code examples, rate limiting, and deployment options.
Molted Team
molted.cloud
A Discord bot that actually understands context, answers questions intelligently, and maintains conversation history across messages. Not the keyword-matching bots of 2020, but a real AI that integrates with Claude or GPT-4. Building one from scratch teaches you API integration, rate limiting, and asynchronous programming. Or you can skip straight to using one.
A Discord bot that:
The complete code is around 200 lines. Not a weekend project, but a solid afternoon.
About that API key: You don't necessarily need a pay-as-you-go API key. If you already have a Claude Pro, ChatGPT Plus, or similar subscription, you can often use that instead. Tools like OpenClaw support subscription-based authentication, so you're not stuck paying $100+/month in API fees on top of your existing $20 subscription. Those Reddit horror stories about "$700/month API bills"? Completely avoidable.
Go to the Discord Developer Portal and click "New Application". Name it whatever you want.
In your application, go to Bot → Reset Token. Copy this token and save it securely. This is your bot's password; never commit it to git or share it publicly.
Under Bot → Privileged Gateway Intents, enable:
Go to OAuth2 → URL Generator. Select:
bot, applications.commandsSend Messages, Read Message History, View ChannelsCopy the generated URL and open it in your browser to add the bot to your server.
mkdir discord-ai-bot
cd discord-ai-bot
npm init -y
npm install discord.js @anthropic-ai/sdk dotenvCreate a .env file:
DISCORD_TOKEN=your-bot-token
ANTHROPIC_API_KEY=your-anthropic-keyCreate .gitignore:
.env
node_modules/Create index.js:
require('dotenv').config();
const { Client, GatewayIntentBits, Partials } = require('discord.js');
const Anthropic = require('@anthropic-ai/sdk');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.DirectMessages,
],
partials: [Partials.Channel],
});
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
// Store conversation history per channel
const conversations = new Map();
client.once('ready', () => {
console.log(`Logged in as ${client.user.tag}`);
});
client.on('messageCreate', async (message) => {
// Ignore bot messages
if (message.author.bot) return;
// Check if bot was mentioned or is a DM
const isMentioned = message.mentions.has(client.user);
const isDM = !message.guild;
if (!isMentioned && !isDM) return;
// Remove the mention from the message
const content = message.content
.replace(/<@!?\d+>/g, '')
.trim();
if (!content) return;
// Get or create conversation history
const channelId = message.channel.id;
if (!conversations.has(channelId)) {
conversations.set(channelId, []);
}
const history = conversations.get(channelId);
// Add user message to history
history.push({ role: 'user', content });
// Keep only last 10 messages for context
if (history.length > 20) {
history.splice(0, history.length - 20);
}
try {
// Show typing indicator
await message.channel.sendTyping();
// Call Claude
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
system: 'You are a helpful assistant in a Discord server. Keep responses concise and friendly.',
messages: history,
});
const reply = response.content[0].text;
// Add assistant response to history
history.push({ role: 'assistant', content: reply });
// Send response (split if too long)
if (reply.length > 2000) {
const chunks = reply.match(/.{1,2000}/g);
for (const chunk of chunks) {
await message.reply(chunk);
}
} else {
await message.reply(reply);
}
} catch (error) {
console.error('Error:', error);
await message.reply('Sorry, I encountered an error. Please try again.');
}
});
client.login(process.env.DISCORD_TOKEN);Run it:
node index.jsMention your bot in Discord and it should respond.
Skip the coding?
OpenClaw includes Discord integration out of the box. Zero code needed.
Start 7-day trialIf you prefer GPT-4, install the OpenAI SDK:
npm install openaiReplace the Anthropic setup:
const OpenAI = require('openai');
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// In the message handler, replace the Claude call:
const response = await openai.chat.completions.create({
model: 'gpt-4o',
max_tokens: 1024,
messages: [
{ role: 'system', content: 'You are a helpful assistant in a Discord server.' },
...history,
],
});
const reply = response.choices[0].message.content;The basic implementation stores all history in memory. For production:
// Better context management with expiry
const conversations = new Map();
const CONTEXT_EXPIRY = 30 * 60 * 1000; // 30 minutes
const MAX_CONTEXT_LENGTH = 20;
function getConversation(channelId) {
const now = Date.now();
if (!conversations.has(channelId)) {
conversations.set(channelId, { messages: [], lastActivity: now });
}
const conv = conversations.get(channelId);
// Reset if stale
if (now - conv.lastActivity > CONTEXT_EXPIRY) {
conv.messages = [];
}
conv.lastActivity = now;
return conv.messages;
}
function addMessage(channelId, role, content) {
const messages = getConversation(channelId);
messages.push({ role, content });
// Trim to max length
while (messages.length > MAX_CONTEXT_LENGTH) {
messages.shift();
}
}
// Clean up old conversations periodically
setInterval(() => {
const now = Date.now();
for (const [id, conv] of conversations) {
if (now - conv.lastActivity > CONTEXT_EXPIRY) {
conversations.delete(id);
}
}
}, 60000);Both Discord and AI APIs have rate limits. Handle them gracefully:
const rateLimit = new Map();
const RATE_LIMIT_WINDOW = 60000; // 1 minute
const MAX_REQUESTS_PER_WINDOW = 10;
function isRateLimited(userId) {
const now = Date.now();
const userLimits = rateLimit.get(userId) || { count: 0, windowStart: now };
// Reset window if expired
if (now - userLimits.windowStart > RATE_LIMIT_WINDOW) {
userLimits.count = 0;
userLimits.windowStart = now;
}
if (userLimits.count >= MAX_REQUESTS_PER_WINDOW) {
return true;
}
userLimits.count++;
rateLimit.set(userId, userLimits);
return false;
}
// In message handler:
if (isRateLimited(message.author.id)) {
await message.reply('You are sending messages too quickly. Please wait a moment.');
return;
}Production bots need robust error handling:
async function callAI(messages, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
messages,
});
return response.content[0].text;
} catch (error) {
if (error.status === 429) {
// Rate limited, wait and retry
await new Promise(r => setTimeout(r, 1000 * (i + 1)));
continue;
}
if (error.status >= 500) {
// Server error, retry
await new Promise(r => setTimeout(r, 1000 * (i + 1)));
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}Let us handle the bot
Molted deploys OpenClaw with Discord ready. 7-day free trial.
Cheapest long-term. Run with PM2 for process management:
npm install -g pm2
pm2 start index.js --name discord-bot
pm2 startup
pm2 saveConnect your GitHub repo, set environment variables, deploy. Pricing based on usage, typically $5-10/month for a bot.
Similar to Railway, good free tier for small bots.
If you have a machine that is always on, run it there. Same PM2 setup as VPS.
Building a Discord bot from scratch teaches valuable skills: API integration, async programming, error handling, deployment. It is worth doing once for the learning experience.
But if you want a working AI bot without the coding and maintenance, pre-built solutions exist. OpenClaw, for example, includes Discord integration that connects in minutes. You configure a bot token, enable the channel, and you have AI responses without writing code.
The tradeoff is customization versus convenience. A custom bot does exactly what you program. OpenClaw does what OpenClaw does, but it does it reliably without you managing servers or debugging at 2 AM.
For teams, the calculation usually favors managed solutions. Developer time spent maintaining a Discord bot is developer time not spent on your actual product. For personal projects and learning, building your own is rewarding.
Free 7-day trial
OpenClaw on Molted includes full Discord integration. No coding, no hosting headaches.
7-day free trial · card on file · cancel anytime
Honest comparison of free AI chatbots including ChatGPT, Claude, Gemini, Copilot, and self-hosted options. Limits and catches explained.
Build an AI assistant for Microsoft Teams with Bot Framework: SSO, compliance, admin controls and the managed alternative if you would rather not host it.
The best Lindy alternatives if credits and workflow building wear you out: Sintra, Marcus, Taskade, Gumloop and a flat-priced always-on OpenClaw agent.
Trois clics, quinze secondes, et les vingt-quatre premières heures sont pour nous.
Dès 14 $/mois · en ligne en 3 clics · les 7 premiers jours offerts