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.js library: 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