Building a Discord Bot with AI Responses: Complete Guide
Create a Discord bot that uses free AI APIs to respond intelligently to messages.
Introduction
Discord bots with AI capabilities are popular for communities, support servers, and entertainment. This tutorial shows how to build one using free AI APIs — no paid tokens required.
Prerequisites
- Node.js 18+
- Discord Developer account
- Free API key from OpenRouter, Groq, or Together.ai
-
discord.jslibrary:npm install discord.js
Step 1: Discord Bot Setup
// bot.js
const { Client, GatewayIntentBits, Events } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent
]
});
client.once(Events.ClientReady, () => {
console.log(`Logged in as ${client.user.tag}`);
});
client.login(process.env.DISCORD_TOKEN);
Step 2: AI Integration (OpenRouter)
// ai.js
async function getAIResponse(prompt, provider = 'openrouter') {
const configs = {
openrouter: {
url: 'https://openrouter.ai/api/v1/chat/completions',
key: process.env.OPENROUTER_API_KEY,
model: 'google/gemini-2.0-flash-exp:free'
},
groq: {
url: 'https://api.groq.com/openai/v1/chat/completions',
key: process.env.GROQ_API_KEY,
model: 'llama-3.1-8b-instant'
}
};
const config = configs[provider];
if (!config.key) throw new Error(`No API key for ${provider}`);
const response = await fetch(config.url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${config.key}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: config.model,
messages: [
{ role: 'system', content: 'You are a helpful Discord bot. Keep responses under 2000 characters.' },
{ role: 'user', content: prompt }
],
temperature: 0.7,
max_tokens: 500
})
});
if (!response.ok) {
const err = await response.json();
throw new Error(`${provider}: ${err.error?.message || response.status}`);
}
const data = await response.json();
return data.choices[0].message.content;
}
module.exports = { getAIResponse };
Step 3: Message Handler with Fallback
// handler.js
const { getAIResponse } = require('./ai.js');
const PROVIDERS = ['groq', 'openrouter']; // Groq first for speed
async function handleMessage(message) {
// Ignore bots and non-mentions
if (message.author.bot) return;
if (!message.mentions.has(client.user)) return;
const prompt = message.content.replace(`<@${client.user.id}>`, '').trim();
if (!prompt) return;
await message.channel.sendTyping();
// Try providers in order until one works
for (const provider of PROVIDERS) {
try {
const response = await getAIResponse(prompt, provider);
await message.reply(response);
return; // Success
} catch (error) {
console.warn(`${provider} failed:`, error.message);
}
}
// All providers failed
await message.reply('🤖 All AI services are busy. Try again in a moment!');
}
module.exports = { handleMessage };
Step 4: Rate Limiting & Cooldowns
// cooldown.js
const cooldowns = new Map();
const COOLDOWN_MS = 5000; // 5 seconds per user
function checkCooldown(userId) {
const now = Date.now();
const lastUsed = cooldowns.get(userId) || 0;
if (now - lastUsed < COOLDOWN_MS) {
return COOLDOWN_MS - (now - lastUsed);
}
cooldowns.set(userId, now);
return 0;
}
// In handler.js:
async function handleMessage(message) {
// ... existing checks ...
const cooldown = checkCooldown(message.author.id);
if (cooldown > 0) {
await message.reply(`⏳ Please wait ${Math.ceil(cooldown/1000)}s before asking again.`);
return;
}
// ... rest of handler ...
}
Step 5: Complete Bot (bot.js)
require('dotenv').config();
const { Client, GatewayIntentBits, Events } = require('discord.js');
const { handleMessage } = require('./handler.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent
]
});
client.once(Events.ClientReady, () => {
console.log(`✅ ${client.user.tag} is online!`);
client.user.setActivity('AI powered | @me to chat');
});
client.on(Events.MessageCreate, handleMessage);
client.login(process.env.DISCORD_TOKEN);
Step 6: Environment Variables (.env)
DISCORD_TOKEN=your_bot_token_here
OPENROUTER_API_KEY=your_openrouter_key
GROQ_API_KEY=your_groq_key
# TOGETHER_API_KEY=your_together_key
Step 7: Deploy for Free
Option A: Railway (Free tier)
npm init -y
npm install discord.js dotenv
# Push to GitHub, connect to Railway
Option B: Render (Free tier)
- Connect GitHub repo
- Build:
npm install - Start:
node bot.js
Option C: Fly.io (Free allowance)
flyctl launch
flyctl deploy
Advanced Features
Slash Commands
const { REST, Routes } = require('discord.js');
const commands = [
{
name: 'ask',
description: 'Ask AI a question',
options: [{ name: 'question', type: 3, description: 'Your question', required: true }]
}
];
// Register on startup
const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN);
await rest.put(Routes.applicationCommands(client.user.id), { body: commands });
Conversation Memory
const conversations = new Map();
function getHistory(userId) {
return conversations.get(userId) || [];
}
function addToHistory(userId, role, content) {
const history = getHistory(userId);
history.push({ role, content });
if (history.length > 10) history.shift(); // Keep last 10
conversations.set(userId, history);
}
// In getAIResponse:
messages: [
{ role: 'system', content: '...' },
...getHistory(userId),
{ role: 'user', content: prompt }
]
// After response:
addToHistory(userId, 'user', prompt);
addToHistory(userId, 'assistant', response);
Cost: $0/month
| Component | Cost |
|---|---|
| Discord API | Free |
| OpenRouter/Groq/Together | Free tier |
| Hosting (Railway/Render/Fly) | Free tier |
| Total | $0 |
Troubleshooting
| Issue | Fix |
|---|---|
| "Missing Access" | Enable Message Content Intent in Developer Portal |
| Rate limited | Add cooldowns, use fallback providers |
| Bot offline | Check hosting logs, verify token |
| Slow responses | Use Groq for speed, add caching |
Conclusion
You now have a production-ready AI Discord bot running entirely on free tiers. Customize the system prompt for personality, add slash commands, and deploy to your community server.
Next steps: Add image generation, music, or moderation features using the same free API pattern.
Part of the AI Bot Tutorials series on Dev.to
Top comments (0)