NewSchokr 13 is here. A whole new UI, seven locations, snapshots and more. Read more →

How to make a discord.py bot from scratch (2.x)

Create a discord.py 2.x bot with intents and commands.Bot, load the token from a .env file and respond to your first command.

Updated · 1 min read

A minimal discord.py 2.x bot is a single Python file: set up discord.Intents, create a commands.Bot, add a command and call bot.run() with your token. Build and test it on your computer first, then deploy it to Schokr.

Prerequisites

1. Create the project and a virtual environment

mkdir my-bot
cd my-bot
python -m venv .venv
# Windows: .venv\Scripts\activate
source .venv/bin/activate
pip install discord.py python-dotenv

The virtual environment keeps the bot's packages separate from the rest of your system. You don't upload it to Schokr.

2. Store the token in .env

Create .env next to your code:

DISCORD_TOKEN=paste-your-token-here

If you use git, add .env and .venv/ to .gitignore.

3. Write bot.py

import os

import discord
from discord.ext import commands
from dotenv import load_dotenv

load_dotenv()

intents = discord.Intents.default()
intents.message_content = True  # needed for prefix commands like !ping

bot = commands.Bot(command_prefix="!", intents=intents)


@bot.event
async def on_ready():
    print(f"Logged in as {bot.user} (ID: {bot.user.id})")


@bot.command()
async def ping(ctx: commands.Context):
    await ctx.send(f"Pong! {round(bot.latency * 1000)} ms")


@bot.command()
async def hello(ctx: commands.Context, *, name: str = "there"):
    await ctx.send(f"Hello, {name}!")


bot.run(os.environ["DISCORD_TOKEN"])

About intents

discord.Intents.default() turns on every intent except the three privileged ones: message_content, members and presences. Prefix commands need message_content because the bot has to read the message text. Any privileged intent you enable in code must also be turned on in the Developer Portal, or you'll get PrivilegedIntentsRequired. See privileged intents.

If you only use slash commands, you can leave message_content off. See slash commands in discord.py.

4. Create requirements.txt

pip freeze > requirements.txt

Or write it by hand with just what you use:

discord.py>=2.4
python-dotenv>=1.0

5. Run it

  1. Turn on Message Content Intent on the Bot page in the Developer Portal.
  2. Run python bot.py.
  3. You should see Logged in as MyBot#1234. Type !ping in a channel the bot can see.

Common mistakes

  • Naming your file discord.py: Python then imports your file instead of the library. Name it bot.py or main.py.
  • Installing discord instead of discord.py: install the package named discord.py.
  • on_message stops commands working: if you override on_message, end it with await bot.process_commands(message), or use @bot.listen() instead of @bot.event.

Next

Deploy it with deploy a discord.py bot to Schokr.