Build a Discord bot
In this tutorial you'll use Python to build and deploy a Discord chat bot application that uses Stable Diffusion via Replicate to generate images from text prompts.
Try it out in the #art channel on Replicate's Discord server.
Prerequisites
- Install Python 3.5 or later.
- A command-line shell (e.g. Terminal on Mac, gnome-terminal on Linux, or PowerShell on Windows)
- Sign up for a Replicate account.
- Sign up for a Discord account.
Set up a Discord Bot account
Follow discord.py's guide to set up a Discord Bot account. Give it a name like stable-diffusion-bot
. At the end of the first section, you'll need to turn on the "message content intent" option on the bot page. That permission is needed for your bot to read the content of messages, to get the prompts!
In the second half of the guide – inviting your bot – when it tells you to "tick the permissions required for your bot to function", you'll want to give the bot permission to "Send messages".
Write some code
This section walks you through steps required to set up a codebase.
🐇 Want to skip ahead? If you'd rather not copy and paste all the code below, then you can clone the replicate/replicate-discord-bot GitHub repo to start with a working project template.
Create a project directory
mkdir stable-diffusion-bot
cd stable-diffusion-bot
Define Python dependencies
Next you'll define some of the Python package dependencies needed by your project.
Install the poetry command-line tool and create a new pyproject.toml
file:
poetry init -n
Then add dependencies:
poetry add discord.py python-dotenv replicate
Configure environment and secrets
Create a file named .env
. This text file will be used to store secrets for your development environment. Paste in the following:
REPLICATE_API_TOKEN=<your-token>
DISCORD_TOKEN=<your-token>
Visit replicate.com/account to copy and paste your Replicate API token. If you didn't subscribe before, you'll need to now to get hold of the token.
The Discord token is the token you copied when creating your bot from the Discord guide. If you don't have it, you can generate a new one by visiting discord.com/applications, selecting your bot application, selecting "Bot" from the side menu, and clicking "Reset Token".
✋ The .env
file contains secrets, so it should not be shared with anyone. If you're planning to turn your project into a Git repository, be sure to create a .gitignore
file and add .env
to it.
Write the bot
Create a new file called bot.py
and paste the following code into it:
from discord import Intents
from discord.ext import commands
from dotenv import load_dotenv
import os
import replicate
load_dotenv()
intents = Intents.default()
intents.message_content = True
bot = commands.Bot(
command_prefix="!",
description="Runs models on Replicate!",
intents=intents,
)
@bot.command(aliases=["sd"])
async def stable_diffusion(ctx, *, prompt):
"""Generate an image from a text prompt using the stable-diffusion model"""
msg = await ctx.send(f"“{prompt}”\n> Generating...")
model = replicate.models.get("stability-ai/stable-diffusion")
version = model.versions.get("db21e45d3f7023abc2a46ee38a23973f6dce16bb082a930b0c49861f96d1e5bf")
image = version.predict(prompt=prompt)[0]
await msg.edit(content=f"“{prompt}”\n{image}")
bot.run(os.environ["DISCORD_TOKEN"])
This file defines the command for your bot (!stable_diffusion
) and how it works. When you want to make changes to your bot later, this will be the file you come back to.
Run your bot locally
Now that you've written the code for your bot, it's time to run it!
The Discord API uses a system called Gateway which supports real-time communication over WebSockets. This means you can run your bot from any computer, even if it's not exposed to the public internet. No need to configure any webhooks!
Run this command to start your bot locally:
poetry run python bot.py
Use the bot
Check your bot is running by typing !help
into one of the channels on your Discord server. Your bot should respond with the list of commands it can run, including !stable_diffusion
.
Now try generating an image:
!stable_diffusion an astronaut riding a horse
Your bot should write a message saying "Generating...", and then 20–40 seconds later it should swap out that message for the newly generated image. 🥳
Deploy your bot (optional)
Running your bot locally is convenient, especially when you're actively working on it. The downside, however, is that it can only run when you're online. If you're building a bot for a server, you probably want it to be online even when you aren't.
There are lots of ways to deploy an application like this. Some of the easiest are services like Vercel, Fly or Heroku. In this tutorial, you'll use Fly to deploy the bot to the cloud.
To get started, see Fly's "speedrun" guide to install the flyctl
command-line tool and create a Fly account.
Then create a new file called Dockerfile
and paste the following code into it:
FROM python:3.10
RUN pip install poetry
WORKDIR /code
COPY poetry.lock pyproject.toml /code/
RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi
COPY . /code
CMD python bot.py
Then create a new Fly application:
flyctl launch
That command will generate a new file called fly.toml
, but it's designed for running web apps so you'll need to make a few changes. Remove the [[services]]
block and everything below it. Your modified file should look something like this:
app = "name-of-your-fly-app"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
[experimental]
allowed_public_ports = []
auto_rollback = true
Then configure your Fly app using the secrets from your local .env
file:
flyctl secrets set REPLICATE_API_TOKEN=... DISCORD_TOKEN=...
That's it! Your bot is now running in the cloud.
Next steps
Now might be a good time to tinker with the bot a bit. Some ideas:
- Generate multiple images instead of a single one, and show them all.
- Add another command that runs a different model.
- Take the image output and run it through another model, like an upscaler.
- Turn it into a game. Perhaps a game of telephone, or a game of Pictionary.