DEV Community

Joske Vermeulen
Joske Vermeulen

Posted on • Originally published at aimadetools.com

Build a Discord Bot That Roasts Your Code With AI

Every dev Discord server needs a code roast bot. Someone pastes a code snippet, the bot tears it apart with the energy of a senior developer who hasn't had coffee yet. It's educational, it's entertaining, and it's surprisingly easy to build.

In this tutorial, we'll build a Discord bot that watches for code blocks in messages, reviews them with AI in a roast-style tone, and replies with brutally honest feedback. Think code review meets comedy.

What we're building

User:
  !roast
Enter fullscreen mode Exit fullscreen mode


javascript
function getUser(id) {
var user = null;
fetch('/api/users/' + id).then(res => {
user = res.json();
});
return user;
}


Bot:
  🔥 CODE ROAST 🔥

  Oh no. Oh no no no.

  1. You're returning `user` before the fetch completes.
     This function returns `null` every single time. You've
     built a function whose only job is to return null. Impressive.

  2. `var` in 2026? Did you find this code in a time capsule?

  3. `res.json()` returns a Promise too, which you're not
     awaiting. So even if the timing worked, `user` would
     be a Promise object, not actual data.

  Here's what you probably meant:
Enter fullscreen mode Exit fullscreen mode


javascript
async function getUser(id) {
const res = await fetch(/api/users/${id});
return res.json();
}


  Rating: 2/10 — The indentation was nice though. 💀
Enter fullscreen mode Exit fullscreen mode

Prerequisites

  • Node.js 20+
  • A Discord account
  • An Anthropic API key
  • A Discord server where you have admin permissions

Step 1: Create the Discord bot

  1. Go to discord.com/developers/applications
  2. Click "New Application" → name it "Code Roaster"
  3. Go to "Bot" tab → click "Add Bot"
  4. Copy the bot token
  5. Under "Privileged Gateway Intents," enable Message Content Intent
  6. Go to "OAuth2" → "URL Generator" → select bot scope and Send Messages + Read Message History permissions
  7. Copy the generated URL and open it to invite the bot to your server

Step 2: Set up the project

mkdir roast-bot && cd roast-bot
npm init -y
npm install discord.js @anthropic-ai/sdk
Enter fullscreen mode Exit fullscreen mode

Step 3: Build the bot

Create index.js:

import { Client, GatewayIntentBits } from 'discord.js';
import Anthropic from '@anthropic-ai/sdk';

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});

const anthropic = new Anthropic();

const ROAST_PROMPT = `You are a code review bot with the personality of a brutally honest senior developer who's seen too much bad code. Your job is to roast the code — point out every issue in a funny, sarcastic way. But always be educational: explain WHY something is wrong and show the fix.

Rules:
- Be funny and sarcastic, but never mean-spirited or personal
- Always explain the actual technical issue behind each roast
- End with a corrected version of the code if possible
- Give a rating out of 10
- Keep it under 300 words
- Use emojis sparingly for effect

Roast this code:`;

// Listen for !roast command
client.on('messageCreate', async (message) => {
  if (message.author.bot) return;
  if (!message.content.startsWith('!roast')) return;

  // Extract code block
  const codeMatch = message.content.match(/```
{% endraw %}
(\w*)\n?([\s\S]*?)
{% raw %}
```/);
  if (!codeMatch) {
    message.reply('Paste a code block with your message. Example:\n!roast\n\\`\\`\\`js\nyour code here\n\\`\\`\\`');
    return;
  }

  const language = codeMatch[1] || 'unknown';
  const code = codeMatch[2].trim();

  if (code.length < 10) {
    message.reply("That's barely code. Give me something to work with. 😤");
    return;
  }

  if (code.length > 3000) {
    message.reply("I'm not reading all that. Keep it under 100 lines. 📏");
    return;
  }

  // Show typing indicator
  message.channel.sendTyping();

  try {
    const response = await anthropic.messages.create({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 800,
      messages: [{
        role: 'user',
        content: `${ROAST_PROMPT}\n\nLanguage: ${language}\n\`\`\`${language}\n${code}\n\`\`\``
      }],
    });

    const roast = response.content[0].text;

    // Discord has a 2000 char limit
    if (roast.length > 1900) {
      const parts = roast.match(/[\s\S]{1,1900}/g) || [];
      for (const part of parts) {
        await message.reply(part);
      }
    } else {
      message.reply(`🔥 **CODE ROAST** 🔥\n\n${roast}`);
    }
  } catch (err) {
    console.error(err);
    message.reply("My roasting circuits overheated. Try again. 🫠");
  }
});

// Also support !review for a nicer tone
client.on('messageCreate', async (message) => {
  if (message.author.bot) return;
  if (!message.content.startsWith('!review')) return;

  const codeMatch = message.content.match(/```
{% endraw %}
(\w*)\n?([\s\S]*?)
{% raw %}
```/);
  if (!codeMatch) {
    message.reply('Paste a code block with your message.');
    return;
  }

  message.channel.sendTyping();

  try {
    const response = await anthropic.messages.create({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 800,
      messages: [{
        role: 'user',
        content: `Review this code constructively. Point out bugs, improvements, and best practices. Be helpful and professional. Keep it concise.\n\nLanguage: ${codeMatch[1] || 'unknown'}\n\`\`\`\n${codeMatch[2].trim()}\n\`\`\``
      }],
    });

    message.reply(`📝 **Code Review**\n\n${response.content[0].text}`);
  } catch (err) {
    message.reply("Something went wrong. Try again.");
  }
});

client.on('ready', () => {
  console.log(`🔥 Roast bot is online as ${client.user.tag}`);
});

client.login(process.env.DISCORD_TOKEN);
Enter fullscreen mode Exit fullscreen mode

Step 4: Run it

export DISCORD_TOKEN=your-discord-bot-token
export ANTHROPIC_API_KEY=your-anthropic-key
node index.js
Enter fullscreen mode Exit fullscreen mode

Go to your Discord server and try:

!roast
Enter fullscreen mode Exit fullscreen mode


javascript
for (var i = 0; i < arr.length; i++) {
setTimeout(function() { console.log(arr[i]); }, 1000);
}

Enter fullscreen mode Exit fullscreen mode


plaintext

The two modes

The bot has two commands:

  • !roast — brutal, funny, educational. For entertainment and learning.
  • !review — professional, constructive. For when you actually want help.

Same AI, different personality. The prompt controls everything.

Tuning the roast level

Adjust the prompt to control intensity:

Mild roast:

Be gently sarcastic, like a patient mentor who's slightly disappointed.
Enter fullscreen mode Exit fullscreen mode


plaintext

Medium roast (default):

Be brutally honest and funny, like a senior dev who's seen too much.
Enter fullscreen mode Exit fullscreen mode


plaintext

Nuclear roast:

Channel the energy of a developer who just found production code
written by an intern with no code review. Hold nothing back.
Enter fullscreen mode Exit fullscreen mode


javascript

Rate limiting

Prevent spam by adding a cooldown:

const cooldowns = new Map();
const COOLDOWN_MS = 30000; // 30 seconds

client.on('messageCreate', async (message) => {
  if (!message.content.startsWith('!roast')) return;

  const lastUsed = cooldowns.get(message.author.id) || 0;
  if (Date.now() - lastUsed < COOLDOWN_MS) {
    const remaining = Math.ceil((COOLDOWN_MS - (Date.now() - lastUsed)) / 1000);
    message.reply(`Cooldown: ${remaining}s. Your code isn't going anywhere. 😏`);
    return;
  }
  cooldowns.set(message.author.id, Date.now());

  // ... rest of the handler
});
Enter fullscreen mode Exit fullscreen mode

Deploying

Same as any Node.js bot — a VPS with pm2, a Docker container, or Railway/Fly.io:

# pm2
pm2 start index.js --name roast-bot

# Docker
docker build -t roast-bot .
docker run -d --env-file .env roast-bot
Enter fullscreen mode Exit fullscreen mode

What you learned

  • How to create a Discord bot with discord.js
  • How to extract code blocks from Discord messages with regex
  • How to use different AI prompts to control tone and personality
  • How to handle Discord's message length limits
  • How to add rate limiting to prevent abuse

The bot is about 80 lines of core logic. It's the kind of thing that makes a dev Discord server 10x more fun — and people actually learn from the roasts because every joke comes with a real explanation.

Related resources


🛠️ Free tools related to this article:


Originally published at https://aimadetools.com

Top comments (0)