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
- Python 3 installed. Check the discord.py documentation for the minimum supported version.
- A bot token. See create a bot and get its token.
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
- Turn on Message Content Intent on the Bot page in the Developer Portal.
- Run
python bot.py. - You should see
Logged in as MyBot#1234. Type!pingin a channel the bot can see.
Common mistakes
- Naming your file
discord.py: Python then imports your file instead of the library. Name itbot.pyormain.py. - Installing
discordinstead ofdiscord.py: install the package nameddiscord.py. on_messagestops commands working: if you overrideon_message, end it withawait bot.process_commands(message), or use@bot.listen()instead of@bot.event.
Next
Deploy it with deploy a discord.py bot to Schokr.