Build a Discord Bot for Image Generation

Build a Discord Bot for Image Generation

A Discord bot that generates images on command is one of those projects that sounds complex but takes an afternoon to build. Your server members type a slash command, the bot calls an image API, and a branded graphic appears in the channel. Welcome cards, leaderboards, achievement badges, meme templates, all generated on the fly.

I built one for a gaming community that wanted automated leaderboard graphics. Every time someone hit a new rank, the bot generated a personalized achievement card and posted it to #achievements. The members loved it. Here's how to build something similar with Imejis.io and Discord.js. If you're new to image APIs, read our beginner guide to generating images with an API first. All pricing as of March 2026.

What a discord image generation bot can doWhat a Discord Image Generation Bot Can Do

Here's what Discord communities actually use image bots for:

Welcome cards: When a new member joins, the bot generates a card with their username, avatar, and a "Welcome to [Server]!" message. Posted automatically to #welcome.

Leaderboard graphics: Weekly or on-demand leaderboard images showing top players, XP rankings, or activity stats in a clean branded layout.

Achievement badges: "Level 10 Reached!", "100 Messages Sent!", "1 Year Member!" personalized achievement cards triggered by milestones. Gaming communities take this further with leaderboard graphics and rank badges.

Event announcements: "/event Game Night - Saturday 8pm EST" generates a branded event card with all the details.

Meme generation: "/meme top-text bottom-text" generates a meme from a template. Simple but fun.

Server stats: "/stats" generates an infographic showing member count, active users, messages per day, top channels.

PrerequisitesPrerequisites

Step 1 create a discord applicationStep 1: Create a Discord Application

  1. Go to the Discord Developer Portal
  2. Click "New Application" and name it (e.g., "Image Bot")
  3. Go to Bot in the sidebar, click "Add Bot"
  4. Copy the Bot Token (keep this secret)
  5. Under Privileged Gateway Intents, enable "Server Members Intent" if you want to detect new member joins
  6. Go to OAuth2 > URL Generator, select scopes: bot and applications.commands
  7. Select bot permissions: "Send Messages", "Attach Files", "Use Slash Commands"
  8. Copy the generated URL and open it to invite the bot to your server

Step 2 set up the projectStep 2: Set Up the Project

mkdir discord-image-bot && cd discord-image-bot
npm init -y
npm install discord.js dotenv

Create .env:

DISCORD_TOKEN=your-bot-token
DISCORD_CLIENT_ID=your-application-id
IMEJIS_API_KEY=your-imejis-api-key

Step 3 register slash commandsStep 3: Register Slash Commands

Create deploy-commands.js:

import "dotenv/config"
import { REST, Routes, SlashCommandBuilder } from "discord.js"
 
const commands = [
  new SlashCommandBuilder()
    .setName("welcome")
    .setDescription("Generate a welcome card")
    .addUserOption((option) =>
      option
        .setName("member")
        .setDescription("The member to welcome")
        .setRequired(true)
    ),
  new SlashCommandBuilder()
    .setName("achievement")
    .setDescription("Generate an achievement badge")
    .addUserOption((option) =>
      option
        .setName("member")
        .setDescription("The member who earned it")
        .setRequired(true)
    )
    .addStringOption((option) =>
      option
        .setName("title")
        .setDescription("Achievement title")
        .setRequired(true)
    ),
].map((cmd) => cmd.toJSON())
 
const rest = new REST().setToken(process.env.DISCORD_TOKEN)
await rest.put(Routes.applicationCommands(process.env.DISCORD_CLIENT_ID), {
  body: commands,
})
console.log("Slash commands registered!")

Run it once: node deploy-commands.js

Step 4 build the botStep 4: Build the Bot

Create index.js:

import "dotenv/config"
import { AttachmentBuilder, Client, GatewayIntentBits } from "discord.js"
 
const client = new Client({
  intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
})
 
const TEMPLATES = {
  welcome: "YOUR_WELCOME_TEMPLATE_ID",
  achievement: "YOUR_ACHIEVEMENT_TEMPLATE_ID",
}
 
async function generateImage(templateId, data) {
  const response = await fetch(`https://render.imejis.io/v1/${templateId}`, {
    method: "POST",
    headers: {
      "dma-api-key": process.env.IMEJIS_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(data),
  })
  return Buffer.from(await response.arrayBuffer())
}
 
// Handle /welcome command
client.on("interactionCreate", async (interaction) => {
  if (!interaction.isChatInputCommand()) return
 
  if (interaction.commandName === "welcome") {
    await interaction.deferReply()
 
    const member = interaction.options.getUser("member")
 
    const imageBuffer = await generateImage(TEMPLATES.welcome, {
      username: { text: member.displayName },
      avatar: { image: member.displayAvatarURL({ size: 256 }) },
      server_name: { text: interaction.guild.name },
      member_count: { text: `Member #${interaction.guild.memberCount}` },
    })
 
    const attachment = new AttachmentBuilder(imageBuffer, {
      name: "welcome.png",
    })
 
    await interaction.editReply({
      content: `Welcome to the server, ${member}! ๐ŸŽ‰`,
      files: [attachment],
    })
  }
 
  if (interaction.commandName === "achievement") {
    await interaction.deferReply()
 
    const member = interaction.options.getUser("member")
    const title = interaction.options.getString("title")
 
    const imageBuffer = await generateImage(TEMPLATES.achievement, {
      username: { text: member.displayName },
      avatar: { image: member.displayAvatarURL({ size: 256 }) },
      achievement_title: { text: title },
      date: {
        text: new Date().toLocaleDateString("en-US", {
          month: "long",
          day: "numeric",
          year: "numeric",
        }),
      },
    })
 
    const attachment = new AttachmentBuilder(imageBuffer, {
      name: "achievement.png",
    })
 
    await interaction.editReply({
      content: `${member} just earned an achievement! ๐Ÿ†`,
      files: [attachment],
    })
  }
})
 
client.once("ready", () => {
  console.log(`Bot is online as ${client.user.tag}`)
})
 
client.login(process.env.DISCORD_TOKEN)

Step 5 auto welcome new membersStep 5: Auto-Welcome New Members

Add automatic welcome card generation when someone joins:

client.on("guildMemberAdd", async (member) => {
  const welcomeChannel = member.guild.channels.cache.find(
    (ch) => ch.name === "welcome"
  )
 
  if (!welcomeChannel) return
 
  const imageBuffer = await generateImage(TEMPLATES.welcome, {
    username: { text: member.displayName },
    avatar: { image: member.displayAvatarURL({ size: 256 }) },
    server_name: { text: member.guild.name },
    member_count: { text: `Member #${member.guild.memberCount}` },
  })
 
  const attachment = new AttachmentBuilder(imageBuffer, {
    name: "welcome.png",
  })
 
  await welcomeChannel.send({
    content: `Welcome ${member}! We're glad you're here.`,
    files: [attachment],
  })
})

Every new member gets a personalized welcome card. No manual work.

Step 6 deployStep 6: Deploy

Discord bots need to stay online, so you can't use serverless functions. Good options:

  • Railway: Free tier, deploys from GitHub, stays running
  • Fly.io: Free tier with 3 shared VMs
  • Render: Free tier for background workers
  • Any VPS: A $5/month server handles most community bots

Start the bot: node index.js

Template design tips for discordTemplate Design Tips for Discord

Discord displays images in chat with specific constraints. Keep these in mind when designing your templates in Imejis.io:

Use a 16:9 or 2:1 aspect ratio. Discord's embed preview crops square images. Wide formats (1200x600, 800x400) display better in chat.

Dark backgrounds work best. Most Discord users are on dark theme. A bright white card looks jarring. Match Discord's dark gray (#36393f) or use your brand's dark palette.

Keep text large. Discord compresses images in chat. Text that looks fine at 1200px wide can be unreadable when Discord shrinks it to 400px in mobile view.

Avatar images need HTTPS URLs. Discord serves avatars over HTTPS. The displayAvatarURL() method returns the right format, but if you're using custom avatar URLs, make sure they're HTTPS.

Cost breakdownCost Breakdown

Server SizeMonthly Images (est.)Imejis.io PlanCost
Small (under 100 members)10-30Free$0
Medium (100-1,000 members)30-100Free$0
Large (1,000-10,000 members)100-500Basic ($14.99)$14.99
Very large (10,000+)500-2,000Basic-Pro$14.99-24.99

Most community bots stay well within the free tier of 100 images per month. Even a server with 1,000 members won't get 100 new joins per month in most cases.

Getting startedGetting Started

  1. Sign up for Imejis.io and design a welcome card template (dark background, 1200x600)
  2. Create a Discord app at the Developer Portal
  3. Copy the code from this tutorial and add your tokens
  4. Deploy to Railway and invite the bot to your server
  5. Test with /welcome @yourself to see it in action

The whole build takes 2-3 hours. I'd start with just the welcome card, get it working, then add achievement badges and other commands later.

For the JSON data format, see our Generate Images from JSON guide. For similar bot patterns, check our Slack Bot Image Generation tutorial. And for API pricing, see our Image Generation API Pricing Comparison.

FaqFAQ

Can a discord bot generate imagesCan a Discord bot generate images?

Yes. The bot listens for slash commands, calls Imejis.io with the data, and sends the image back to the channel. Takes about 3-4 seconds end to end.

What can i use a discord image bot forWhat can I use a Discord image bot for?

Welcome cards, leaderboard graphics, achievement badges, event announcements, meme generation, and server stats. Anything your community generates repeatedly.

Do i need to host my own serverDo I need to host my own server?

Yes, Discord bots need a persistent connection. Railway, Render, and Fly.io all have free tiers that work for most bots.

How much does this cost to runHow much does this cost to run?

$0 for most communities. Imejis.io free tier (100 images/month), Discord API (free), Railway hosting (free tier). You won't pay unless your server generates more than 100 images monthly.

What programming language do i needWhat programming language do I need?

This tutorial uses JavaScript with Discord.js. The image API is REST-based, so Python with discord.py works too, or any language with a Discord library. For a deeper Node.js walkthrough, see our Node.js integration guide.

Ship itShip It

Your community deserves better than text-only announcements. A welcome card with someone's name and avatar costs nothing to generate and makes every new member feel seen. Try Imejis.io free and build your Discord image bot this weekend.