How to Make a Discord Bot in Python (discord.py), Step by Step
A Discord bot is a program that logs in to Discord with its token and reacts to what happens on your server. With Python and the discord.py library, your first one takes about fifteen minutes: this one has two slash commands, /hello and /dice.
1. Create the bot on Discord
Create the application
Go to discord.com/developers/applications, click “New Application” and give it a name. That's your bot.
Get the token
In the “Bot” tab, click “Reset Token” and copy the token. It's the bot's password: whoever has it controls the bot, so don't share it or push it to GitHub.
Invite it to your server
In “OAuth2” → “URL Generator”, tick “bot” and “applications.commands”, pick the permissions (to start with, “Send Messages”) and open the link it gives you to add the bot to your Discord server. To see what each permission lets the bot do, build the link with the bot permissions calculator.
Rather not set it up yourself? Discord bot hosting from €1.50 a month, no contract and a full refund within 72 hours. Or create a free Discord bot, no card needed.
2. The code
Three files in one folder. requirements.txt lists the libraries; .env holds the token (no quotes); and app.py is the bot. Prefer JavaScript? It's the same bot in the discord.js guide.
discord.py
python-dotenvDISCORD_TOKEN=paste-your-token-hereimport os
import random
import discord
from discord import app_commands
from dotenv import load_dotenv
load_dotenv() # reads the token from the .env file
intents = discord.Intents.default()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)
@tree.command(name="hello", description="Says hello")
async def hello(interaction: discord.Interaction):
await interaction.response.send_message(f"Hello, {interaction.user.mention}!")
@tree.command(name="dice", description="Rolls a 6-sided die")
async def dice(interaction: discord.Interaction):
await interaction.response.send_message(f"🎲 You rolled a {random.randint(1, 6)}")
@client.event
async def on_ready():
await tree.sync() # publishes the /hello and /dice commands
print(f"Logged in as {client.user}")
client.run(os.environ["DISCORD_TOKEN"])3. Try it on your computer
With Python 3.10 or newer: open a terminal in the folder, install the libraries with “pip install -r requirements.txt” and start it with “python app.py”. When it says “Logged in as…”, type /hello on your server. Slash commands can take a few minutes to show up the first time.
4. Keep it online all the time (for free)
As long as the program is running on your computer, the bot works; turn the computer off and it disconnects. To keep it online all the time it has to be hosted on a server.
On NapNodes: create the free bot, switch it to Python in “Settings” → “Language”, upload the three files in “Files” (or set your GitHub repository, without the .env) and click “Start”. The libraries in requirements.txt install themselves at startup and app.py is the startup file that comes set. The whole process is in the Discord bot hosting guide.
The NapNodes free bot has 256 MB, plenty for a bot like this one, and you only have to renew it with one click every week. If it grows, or you'd rather not have to remember, the Mini plan has 512 MB and stays online with nothing to renew (Discord bot pricing).
Frequently asked questions
What do I need to make a Discord bot in Python?
Python 3.10 or newer, the discord.py library and an application created in the Discord Developer Portal, which is where you get the token.
Why don't the slash commands show up?
The first time, Discord can take a few minutes to show them. Also check that you ticked “applications.commands” when you invited the bot. If they still don't appear, see how to sync them and what else to check.
Where do I put the bot token?
In a .env file the bot reads when it starts. Never in code you push to GitHub: whoever has the token controls the bot.
How do I keep the bot online all the time?
By hosting it on a server. NapNodes has a free 256 MB bot that you only have to renew with one click every week (why it goes offline on Replit and which free options there are).
Shall we set it up for you?
Discord bot hosting from €1.50 a month, never oversold: your RAM is yours alone. And if you'd rather start without paying, there's a free Discord bot, no card needed.
Free tool: Discord bot permissions calculator. Tick your bot's permissions and get the number and the invite link; or paste a number and see which permissions it grants.
Free tool: Discord intents calculator. Tick what your bot does or search the event you're not getting: the intents, the discord.js or discord.py code and what to enable in the portal.
Free tool: Discord timestamp generator. Pick a date, time and time zone and copy the <t:…> so everyone on Discord sees the time in their own zone, or a countdown.
Free tool: Discord colored text generator. Write on Discord in red, green or yellow, with backgrounds, bold and underline: the ansi block ready to paste, and the line for your bot.
Free tool: Discord embed generator. Build an embed with a title, colour, fields and images, see it as Discord shows it and copy the discord.js, discord.py or webhook JSON code.
Keep reading
- How to Make a Discord Bot in JavaScript (discord.js), Step by Step
Make your first Discord bot with Node.js and discord.js: create the application, get the token, add slash commands (/hello) and keep it online for free.
- Discord Bot Hosting: Keep Your Bot Online, Free or Paid
Keep your Discord bot online around the clock: Node.js or Python, upload your code or pull it from GitHub, where the token goes and how much RAM it needs.
- My Bot's Slash Commands Aren't Showing: Syncing in discord.py and discord.js
Why your Discord bot's slash (/) commands don't appear and how to publish them: tree.sync() in discord.py, REST.put in discord.js, global or per server.