Discord bots are a fantastic way to enhance your server, whether you're looking to streamline tasks, introduce fun features, or simply add a touch of entertainment. In this guide, weâll walk you through the steps to create a Discord bot in Python, complete with a fun number guessing game to engage your users. Weâll even add some fun extras like motivational messages, a fun fact if the user guesses the number using API requests, and a UI component to make the bot more interactive.
What youâll learn from this guide:
In this guide, youâll learn:
- How to set up Python and PyCharm as your coding environment.
- How to create a basic Discord bot using Pythonâs discord library.
- How to set up bot permissions and invite the bot to your server.
- How to create a number guessing game that responds to commands with â/â.
- How to make the bot mention the user and give feedback on whether their guess is too high or too low.
- How to add a fun fact using API, so the bot shares a cool fact about the guessed number.
- How to set up basic UI components (like buttons) to make interactions more fun.
Prerequisites
Before we start coding, hereâs what youâll need:
- Python installed on your computer. If you donât have it yet, you can download it from python.org. (https://www.python.org/downloads/)
After installing, open up terminal and check if Python is properly installed by typing:
python --versionYou should see a version number.
- Weâll be using PyCharm IDE, which makes writing code in Python easier. PyCharm is beginner friendly with many great features like virtual environment creation, that helps you keep track of installed libraries and organize your files. You can get the free version of PyCharm (Community Edition) from JetBrains (https://www.jetbrains.com/pycharm/download/).
- A Discord account and access to the Discord Developer Portal (https://www.discord.com/developers/applications). This is where weâll create and manage our bot.
Step 1: Setting up your coding environment in PyCharm
Alright, letâs set up our project in PyCharm and get everything ready for coding.
Creating a project
1. Open PyCharm and click on âNew Projectâ
2. Name your project and choose where you want to save it.
3. Create a virtual environment. PyCharm will ask you if youâd like to set up a new virtual environment. In the Interpreter type choose âProject venvâ, and make sure the Python version is set to your Python installation. Click Create, and PyCharm will open a new window with your project. Virtual environments are useful, especially when working with projects that have specific library requirements. They keep your libraries contained to this one project, which helps avoid conflicts with other Python projects.
Installing required libraries
Next, letâs install the libraries our bot will need:
- discord.py: This is a Python wrapper for the Discord API, allowing us to connect our bot and interact with Discord.
- requests: A library for making HTTP requests, which weâll use to get fun facts for the bot.
- python-dotenv: This library helps us securely load environment variables (like our bot token) from a file, so we donât hardcode sensitive information into our code.
Open the Terminal in PyCharm. You can find it at the bottom left sidebar. Make sure your virtual environment is activated (you should see (.venv) in the terminal).
Run the following command:
pip install discord.py requests python-dotenvOnce everything is installed, weâre ready to set up our bot.
Step 2: Creating your bot in the Discord Developer Portal
Head over to the Discord Developer Portal (https://www.discord.com/developers/applications) to set up the bot itself.
Create a new application
Click on New Application in the top right corner. Give it a name, like âNumber Guessing Bot,â and hit Create.
Add a bot to your application
Go to the Bot section on the left sidebar. Here you can change your botâs username, icon, banner. Next, click on the âReset Tokenâ You should see your bot's token. The bot token is your botâs unique key to access Discord, so keep it private to ensure its security. Now, go back to PyCharm and right click on your projectâs main folder and create a new file â.envâ. Copy the token and paste it into a file called .env in your project folder like this:
DISCORD_TOKEN=thetokenThis file will securely store the token, so itâs not exposed in your code.
Set up bot permissions
To make sure our bot works properly, letâs set up its permissions. While still on the Bot section, scroll down and check the âMessage Content Intentâ and âServer Members Intentâ. Then go to the OAuth2 section and scroll down to URL Generator.
Under Scopes select âBotâ and then choose:
- Send Messages: This will allow the bot to send messages.
- Read Message History: This will allow the bot to access messages in the channels itâs in.
- Mention Everyone: This will allow the bot to mention users, which we will need for congratulating users by name.
Then, choose âGuild Installâ, generate the link, paste it into your browser and invite the bot to your server.
Step 3: Writing the bot code
Now comes the fun part: coding the bot!
Setting up the bot with imports and initial configurations
The first thing you need to do is set up the necessary libraries and initialize the bot. The imports are the essential building blocks for the bot to work with Discordâs API, manage commands, and load the botâs token securely.
In PyCharm, create a new file main.py and add the following code:
import discord
import os
import random
import requests
from discord.ext import commands
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
intents = discord.Intents.default()
intents.messages = True
intents.members = True
intents.message_content = True
bot = commands.Bot(command_prefix="/", intents=intents)
active_games = {}
@bot.event
async def on_ready():
print(f'Logged in as {bot.user}')
We import âdiscordâ for the Discord API, âosâ for environment variables, ârandomâ for generating random numbers, ârequestsâ for making HTTP calls, and âdotenvâ to securely load the token from an .env file.
The bot will use Intents to specify which events (like reading messages) the bot is allowed to interact with.
The on_ready event function will get called when the bot successfully logs in. It will print the message provided in your PyCharm console. (We will need to add bot.run(TOKEN)line at the end of the code in order for it to run)
Making the /startGuess <number> command
The /startGuess <number> command starts the game by selecting a random number within a user specified range.
@bot.command(name="startGuess")
async def start_guess(ctx, max_range: int):
if ctx.author.id in active_games:
await ctx.send("You already have an active game! Finish it before starting a new one.")
return
if max_range < 1:
await ctx.send("Please provide a positive number greater than 1.")
return
secret_number = random.randint(1, max_range)
active_games[ctx.author.id] = {
"secret_number": secret_number,
"attempts": 0
}
await ctx.send(f"Game started! I'm thinking of a number between 1 and {max_range}. Start guessing with `/guess <your number>`.")
The @bot.command tells Discord to treat this function as a command. In our case, itâs the /startGuess command. The bot checks if the user already has an active game. If they do, it informs them to finish the current game. Then, it checks if the range is valid (greater than 1). If the range is valid, the bot generates a random number between 1 and the user's input max_range and stores this information in the active_games, with the key of the user's ID.
Adding the guess command to handle user guesses
Add the /guess command to allow users to submit guesses and get feedback.
@bot.command(name="guess")
async def guess(ctx, user_guess: int):
game = active_games.get(ctx.author.id)
if game:
game["attempts"] += 1
secret_number = game["secret_number"]
if user_guess < secret_number:
await ctx.send(f"{ctx.author.mention}, your guess is too low. Try again!")
elif user_guess > secret_number:
await ctx.send(f"{ctx.author.mention}, your guess is too high. Try again!")
else:
attempts = game["attempts"]
response = requests.get(f"http://numbersapi.com/{secret_number}/trivia")
trivia = response.text if response.status_code == 200 else "No trivia available."
await ctx.send(
f"đ Congrats {ctx.author.mention}! You guessed the number {secret_number} in {attempts} tries! Fun fact: {trivia}"
)
del active_games[ctx.author.id]
else:
await ctx.send(f"{ctx.author.mention}, you haven't started a game yet! Type `/startGuess` to begin.")
As in the previous function @bot.command, this time itâs with the name âguessâ. The /guess command will take the user's guess. The bot will also check if the user has an active game by looking up their user ID in the active_games dictionary. The bot will compare the userâs guess to the secret number.
If too low, it will inform the user to guess higher. If too high, it will ask them to guess lower. If the guess is correct the game will end and a fun fact about the number will be given using the Numbers API as well as a congrats message.
After the user wins, the game data will get removed from active_games.
Adding UI buttons and changing /startGuess <number> to /startGuess
Now weâll modify /startGuess to remove the need for a numeric range by adding a button-based UI. This will replace /startGuess <number> with just /startGuess.
from discord.ui import View, Button
pre_game_messages = [
"Get ready to guess!",
"Let's see if you can guess the number!",
"The guessing game is about to begin!"
]
class StartGameView(View):
def __init__(self, ctx):
super().__init__()
self.ctx = ctx
@discord.ui.button(label="Start", style=discord.ButtonStyle.green)
async def start_button(self, interaction: discord.Interaction, button: Button):
if self.ctx.author.id in active_games:
await interaction.response.send_message(
"You already have an active game! Finish it before starting a new one.",
ephemeral=True
)
return
await interaction.response.send_message("Enter your desired range in the pop-up modal.", ephemeral=True)
@discord.ui.button(label="Cancel", style=discord.ButtonStyle.red)
async def cancel_button(self, interaction: discord.Interaction, button: Button):
await interaction.response.send_message("Game setup canceled.", ephemeral=True)
@bot.command(name="startGuess")
async def start_guess_ui(ctx):
pre_game_message = random.choice(pre_game_messages)
await ctx.send(pre_game_message)
view = StartGameView(ctx)
await ctx.send("Ready to start the game?", view=view)
Make sure to update your /startGuess command to the new one, as we updated it to now work with the UI. This class creates a view that is a container for UI elements like buttons. It includes two buttons:
Start Button: Starts the game and asks the user to input the range.
Cancel Button: Cancels the game.
Adding the modal input for custom range
Now weâll add a modal that prompts the user to input their desired maximum range, making the setup fully interactive.
from discord.ui import Modal, TextInput
class RangeInputModal(Modal):
def __init__(self, ctx):
super().__init__(title="Set Game Range")
self.ctx = ctx
self.range_input = TextInput(label="Enter the maximum range", placeholder="e.g., 100")
self.add_item(self.range_input)
async def on_submit(self, interaction: discord.Interaction):
try:
max_range = int(self.range_input.value)
if max_range < 1:
await interaction.response.send_message("Please enter a number greater than 1.", ephemeral=True)
return
except ValueError:
await interaction.response.send_message("Please enter a valid number.", ephemeral=True)
return
secret_number = random.randint(1, max_range)
active_games[self.ctx.author.id] = {
"secret_number": secret_number,
"attempts": 0
}
await interaction.response.send_message(
f"Game started! I'm thinking of a number between 1 and {max_range}. Start guessing with `/guess <your number>`."
)
@discord.ui.button(label="Start", style=discord.ButtonStyle.green)
async def start_button(self, interaction: discord.Interaction, button: Button):
if self.ctx.author.id in active_games:
await interaction.response.send_message(
"You already have an active game! Finish it before starting a new one.",
ephemeral=True
)
return
modal = RangeInputModal(self.ctx)
await interaction.response.send_modal(modal)
It is important to update our â@discord.ui.button(label="Start"â Start button to the updated one. This new one contains the modal interaction which will allow us to input the number range. The on_submit method will be triggered when the user submits the modal. The input will get processed to start the game with the chosen range. The bot also checks if the input is valid.
import discord
import os
import random
import requests
from discord.ext import commands
from dotenv import load_dotenv
from discord.ui import Modal, TextInput, View, Button
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
intents = discord.Intents.default()
intents.messages = True
intents.members = True
intents.message_content = True
bot = commands.Bot(command_prefix="/", intents=intents)
active_games = {}
pre_game_messages = [
"Get ready to guess!",
"Let's see if you can guess the number!",
"The guessing game is about to begin!"
]
@bot.event
async def on_ready():
print(f'Logged in as {bot.user}')
class RangeInputModal(Modal):
def __init__(self, ctx):
super().__init__(title="Set Game Range")
self.ctx = ctx
self.range_input = TextInput(label="Enter the maximum range", placeholder="e.g., 100")
self.add_item(self.range_input)
async def on_submit(self, interaction: discord.Interaction):
try:
max_range = int(self.range_input.value)
if max_range < 1:
await interaction.response.send_message("Please enter a number greater than 1.", ephemeral=True)
return
except ValueError:
await interaction.response.send_message("Please enter a valid number.", ephemeral=True)
return
secret_number = random.randint(1, max_range)
active_games[self.ctx.author.id] = {
"secret_number": secret_number,
"attempts": 0
}
await interaction.response.send_message(
f"Game started! I'm thinking of a number between 1 and {max_range}. Start guessing with `/guess <your number>`."
)
class StartGameView(View):
def __init__(self, ctx):
super().__init__()
self.ctx = ctx
@discord.ui.button(label="Start", style=discord.ButtonStyle.green)
async def start_button(self, interaction: discord.Interaction, button: Button):
if self.ctx.author.id in active_games:
await interaction.response.send_message(
"You already have an active game! Finish it before starting a new one.",
ephemeral=True
)
return
modal = RangeInputModal(self.ctx)
await interaction.response.send_modal(modal)
@discord.ui.button(label="Cancel", style=discord.ButtonStyle.red)
async def cancel_button(self, interaction: discord.Interaction, button: Button):
await interaction.response.send_message("Game setup canceled.", ephemeral=True)
@bot.command(name="startGuess")
async def start_guess_ui(ctx):
pre_game_message = random.choice(pre_game_messages)
await ctx.send(pre_game_message)
view = StartGameView(ctx)
await ctx.send("Ready to start the game?", view=view)
@bot.command(name="guess")
async def guess(ctx, user_guess: int):
game = active_games.get(ctx.author.id)
if game:
game["attempts"] += 1
secret_number = game["secret_number"]
if user_guess < secret_number:
await ctx.send(f"{ctx.author.mention}, your guess is too low. Try again!")
elif user_guess > secret_number:
await ctx.send(f"{ctx.author.mention}, your guess is too high. Try again!")
else:
attempts = game["attempts"]
response = requests.get(f"http://numbersapi.com/{secret_number}/trivia")
trivia = response.text if response.status_code == 200 else "No trivia available."
await ctx.send(
f"đ Congrats {ctx.author.mention}! You guessed the number {secret_number} in {attempts} tries! Fun fact: {trivia}"
)
del active_games[ctx.author.id]
else:
await ctx.send(f"{ctx.author.mention}, you haven't started a game yet! Type `/startGuess` to begin.")
bot.run(TOKEN)
Now, to run the bot, simply run âpython main.pyâ in your PyCharm console. To stop the bot press CTRL + C.
Here is how the Bot looks in action:

Pressing âCancelâ will show this:

Pressing âStartâ will open the modal:

Full game with range â3â:

Starting a game while another one is in progress:

Congratulationsâyouâve built a Discord Bot using Python!
We hope this guide has been a fun and insightful introduction to building your very own Discord bot using Python. By now, youâve set up your coding environment, created a bot from scratch, and even added some interactive features like number guessing and fun fact sharing. Whether youâre planning to build more complex bots or just wanted to dip your toes into Python programming, youâve taken a big step forward. So, what will your next bot do? The possibilities are endless.
Do you have a project that requires software development skills or knowledge of specific programming languages? Or perhaps youâve developed software that needs to be tested? Contact us to learn more about our software testing and development services.





