The author selected the Free and Open Source Fund to receive a donation as part of the Write for DOnations program.
Discord is a popular voice and text messaging platform used by gamers, open-source communities, conference organizers, and more. It has gained popularity due to features like superb voice chat, various text channels, and extensibility using automated assistants or “bots.”
In this guide, you will build a Discord bot using the Python programming language and deploy it to an Ubuntu 20.04 server. You’ll be using the Discord Python library, discord.py
, to program your bot.
Note: Discord has two different names for their chat/voice rooms. They refer to these as both Servers and Guilds, depending on where you are in the documentation. For this tutorial, we will use the term Guild. Just know that these terms can be used interchangeably and often are in the official Discord documentation.
To complete this tutorial, you’ll need:
Before you start coding, you need to create and register your bot in the Discord developer portal.
Sign in to the developer portal and click on the New Application button to start the process. A Discord application allows you to interact with the Discord API. Bots are bound to applications; that is how they function.
Next, add a name for the application in the modal and press the Create button. For this tutorial, we’ll name ours SammySharkBot
.
Discord will create your application. Next, you’ll note a page with information regarding your bot. You can choose to add a picture to serve as an icon for your bot. Click on the Choose a Neat Icon button in the App Icon section of the page. This is not required.
If you did upload an icon, you’d note a dialog box prompting you to save your changes. Press Save Changes to save your icon.
Now that you’ve set up your application, it’s time to create a bot that is associated with the application. Navigate to the Bot link in the Settings navigation pane on the left-hand side of the screen.
Now click the Add Bot button to add the bot to your application.
Once you’ve done that, a Bot will appear with the optional icon you set up earlier. Remember this page; you’ll need to come back to it later to retrieve the API Token.
You’ll be prompted with a modal that states Adding a bot user gives your app visible life in Discord. However, this action is irrevocable! Choose wisely. Go ahead and press Yes, do it! to create the bot user.
Next, navigate to the OAuth2 link in the Settings navigation pane on the left-hand side of the screen. You need to add the appropriate permissions so your bot can function properly.
You’ll need to add the scopes in which your bot can function. Only check the bot option because that’s all you want this bot to do. For more information about the other scopes, visit the Discord OAuth2 Documentation.
Now scroll down and give your bot the following permissions: View Channels, Send Messages, Read Message History. This will give your bot a limited set of actions that it can perform. If you want to create a bot with no restrictions, you can select the Administrator option; this is not recommended.
Once you have done this, a Discord URL followed by a Copy button will appear. Click that button to copy the link and open it in a new window in your browser.
A prompt will appear for your bot to connect your Guild. You may have permission to install bots in multiple Guilds, so you may note more than one here. Select the Guild you wish to install your bot into and click Authorize.
Before a bot is added to your Guild, Discord shows you all the permissions the bot will have. This ensures that you are aware of what you are installing. If you don’t want the bot to have a specific permission, you can uncheck it. However, don’t do that for this bot because the bot won’t work otherwise. Click Authorize to accept and add the bot to your Guild.
Go back to your Guild and check the channel where posts about new members appear. You will note that your bot joined your Guild. Your bot will also appear in the member list on the right-hand side, although the bot will appear offline; this will change after you start the bot code.
Now that your bot is added to your Guild, you are ready to bring it to life with some Python code.
Before you get started coding, you need to set up your Python developer environment. In this step, you will install and activate your Python requirements within a virtual environment for easier management.
First, create a directory in your home directory that you can use to store all of your virtual environments:
- mkdir ~/.venvs
Now create your virtual environment using Python:
python3 -m venv ~/.venvs/discord
This will create a directory called discord
within your .venvs
directory. Inside, it will install a local version of Python and a local version of pip
. You can use this to install and configure an isolated Python environment for your project.
Before you install your project’s Python requirements, activate the virtual environment:
- source ~/.venvs/discord/bin/activate
Your prompt should change to indicate that you are now operating within a Python virtual environment. It will look something like this: (discord)user@host:~$
.
With your virtual environment active, install discord.py
with the local instance of pip
:
- pip install discord.py
Note: Once you have activate your virtual environment (when your prompt has (discord)
preceding it), use pip
instead of pip3
, even if you are using Python 3. The virtual environment’s copy of the tool is always named pip
, regardless of the Python version.
Now that you have the Discord package installed, you will need to save this requirement and its dependencies. This is good practice so you can recreate your developer environment as needed.
Use pip
to save your environment’s information to a requirements.txt
file:
- pip freeze > requirements.txt
You now have the libraries necessary to build a discord bot.
You will now begin coding your Discord bot. Once completed, your bot will listen for certain phrases shared in a text chat, and then it will respond to them accordingly. Specifically, your bot will flip a coin on behalf of the users.
In this step, you will build a minimal version of your bot. You will then add more functionality in Step 4 and Step 5.
To begin, open a file named bot.py
in your preferred text editor:
- nano bot.py
Now add the following imports to the file: os
, random
, and discord
. The os
library will allow you to read valuable information, such as API Tokens
and Guild Name
from your environment variables. The random
library will allow you to generate the output for your random events. And the discord
library will provide you with the methods, objects, and decorators required to interact with the discord API. The code is as follows:
import os
import random
import discord
Next, you will need to retrieve the Discord API token and your bot’s guild from environment variables. You’ll use the method getenv
from the os
library in the Python standard library. Append the following code to bot.py
:
...
token = os.getenv("DISCORD_TOKEN")
my_guild = os.getenv("DISCORD_GUILD")
In version 1.5 of discord.py
, Intents
were introduced. This was a breaking change from prior versions of Discord libraries that allowed bots to subscribe to certain events that happen within the Guild. For this tutorial, you’ll set the client’s available intents to default, but you may need to revisit if you plan on interacting with the GUILD_PRESENCES
or GUILD_MEMBERS
intents. These are Privileged Gateway Intents.
Append the following code to bot.py
to properly set up the intents:
...
intents = discord.Intents.default()
client = discord.Client(intents=intents)
Now, let’s write some code that responds to an event in Discord. Events are actions that happen on the Discord Guild, such as sending a message or joining a channel. For a full list of supported events, check the Discord Event Reference API.
The first segment of code will activate on the on_ready
event. This event triggers when your bot loads into a Guild. Note that the Discord API does not guarantee that this event only happens once. If you are planning on putting code here that should only run once, do some checks to ensure that it indeed only executes once.
You’ll write a print statement that prints when your bot has successfully connected to your Guild. Discord bots require the use of async
methods so that the bot sits in a ready state and waits for calls.
Append the following code to the end of bot.py
:
...
@client.event
async def on_ready():
for guild in client.guilds:
if guild.name == my_guild:
break
print(
f"{client.user} is connected to the following guild:\n"
f"{guild.name}(id: {guild.id})"
)
You use a for
loop to find your Guild among all available Guilds, and then you print information about the Guild and your connection to it.
Finally, you need to tell the client to run when the script is executed using your API token. Append the following line to bot.py
to run your bot:
...
client.run(token)
At this point, your code should look like this:
import os
import random
import discord
token = os.getenv("DISCORD_TOKEN")
my_guild = os.getenv("DISCORD_GUILD")
intents = discord.Intents.default()
client = discord.Client(intents=intents)
@client.event
async def on_ready():
for guild in client.guilds:
if guild.name == my_guild:
break
print(
f"{client.user} is connected to the following guild:\n"
f"{guild.name}(id: {guild.id})"
)
client.run(token)
You have just written the skeleton code that will allow your bot to connect to a Guild. Now you will test your bot’s basic functionality.
Before you code any more, check that your bot can connect to Discord. Navigate back to the discord developer panel and click on the Bot link in the navigation bar on the left. From here, locate the Token underneath the bot username and click the Copy button to copy the token to your clipboard.
Once you have copied the token, return to the terminal with your activated virtual environment. Export the Discord token so it is available in the environment variables for your bot to read on startup:
- export DISCORD_TOKEN=YOUR_DISCORD_TOKEN
Now you need to get the Guild name that your bot will join. Navigate to your Discord Guild. The Guild name should be in the top left-hand corner of your Guild page. This was the name you chose when you created a Guild in the prerequisites section.
Now, export the Discord Guild so it is available in the environment variables for your bot to read on startup:
- export DISCORD_GUILD=YOUR_DISCORD_GUILD
Now that you have exported the necessary environment variables, you are ready to test your bot:
Run the application:
- python3 bot.py
It might take a few seconds, but you will receive an output like this. Note that your bot number and id
will differ:
OutputSammySharkBot#8143 is connected to the following Guild:
SammyShark(id: 801529616116350998)
Navigate back to your Discord Guild and you will note that your bot now has a green circle near its name. This indicates that the bot is online.
You may notice in your terminal that your code does not terminate. This is because the bot is a constantly running process. To stop your bot at any time, press the CTRL + C key combo.
Now that your bot is working, it’s time to extend its functionality. For your bot to respond to messages sent in the text chat, you’ll need to listen to the on_message
event. This function takes in one argument, message
, which contains the message object, including various attributes and methods for responding to messages.
One thing that you’ll need to ensure is that your bot doesn’t answer itself. If the bot were to interpret its own message as a trigger, then it would create an infinite loop. To avoid this, check that the user sending the message isn’t the bot.
Append the following code to bot.py
to declare the on_message
function and to check who sent the message:
...
@client.event
async def on_message(message):
if message.author == client.user:
return
Lastly, add the code to flip the coin. You will also perform a string manipulation on the message content to lower case (or upper, if you prefer) so you don’t have to worry about matching exact case in strings. Use the randint()
function in the Python random
library to simulate flipping a coin. Finally, once you have crafted a message, you will send it to the channel using the method for sending a message. Remember, this is asynchronous programming, so you’ll have to use the await
keyword when sending the message.
Append the following code to bot.py
within the on_message
function; this will add the coin-flipping functionality:
message_content = message.content.lower()
if "flip a coin" in message_content:
rand_int = random.randint(0, 1)
if rand_int == 0:
results = "Heads"
else:
results = "Tails"
await message.channel.send(results)
What follows is the finished code for the bot. Ensure that your code looks like this, or copy and paste this code:
import os
import random
import discord
token = os.getenv("DISCORD_TOKEN")
my_guild = os.getenv("DISCORD_GUILD")
intents = discord.Intents.default()
client = discord.Client(intents=intents)
@client.event
async def on_ready():
for guild in client.guilds:
if guild.name == my_guild:
break
print(
f"{client.user} is connected to the following guild:\n"
f"{guild.name}(id: {guild.id})"
)
@client.event
async def on_message(message):
if message.author == client.user:
return
message_content = message.content.lower()
if "flip a coin" in message_content:
rand_int = random.randint(0, 1)
if rand_int == 0:
results = "Heads"
else:
results = "Tails"
await message.channel.send(results)
client.run(token)
Now that the bot is finished, it’s time to test it. Save and close the file.
Rerun the app:
- python3 bot.py
After the app connects to your Guild, navigate to the #general channel in your Discord Guild. Type flip a coin
in the text chat, and the bot will respond with either Heads or Tails.
Now that you have confirmed that your bot is functional, you are ready to deploy it to production on an Ubuntu 20.04 server.
You can leave your bot running from your local machine, but having to leave a terminal active or worry about power outages can be annoying. For convenience, you can deploy it to a server.
It is best practice to run your bot as a non-root user. This tutorial uses the username sammy.
First, copy your code and Python library requirements to the server using the scp
command. Send everything to your user’s root directory:
- scp bot.py requirements.txt sammy@your_server_ip:~
Next, ssh into your server:
- ssh sammy@my_server_ip
You will now enter commands into the server’s terminal.
You need to install the proper Python system packages to run your bot on your server.
Install python3
, python3-venv
, and screen
:
- sudo apt update && sudo apt install python3 python3-venv screen
Now, you’re going to use a tool called screen to create a virtual terminal. Without this tool, if you were to exit your terminal while the bot was running, the process would terminate, and your bot would go offline. With this tool, you can connect and disconnect to sessions so your code remains running. To learn more about screen, check out our tutorial on installing and using screen.
To start a screen session, use the following command:
- screen
screen will prompt you with a license agreement. Press Return to continue.
Now that you have a virtual session set up, you need to create a Python virtual environment to run your code.
First, like before, create a directory to store your virtual environments:
- mkdir ~/.venvs
Then create a new virtual environment:
- python3 -m venv ~/.venvs/discord
Activate the virtual environment:
- source ~/.venvs/discord/bin/activate
Next, install the necessary libraries using pip:
- pip install -r requirements.txt
Before you can run your bot, you’ll need to export the DISCORD_TOKEN
and DISCORD_GUILD
so your bot can access the API Key and Guild information:
- export DISCORD_TOKEN=YOUR_DISCORD_TOKEN
- export DISCORD_GUILD=YOUR_DISCORD_GUILD
Finally, run your bot:
- python3 bot.py
Your bot will start up and start accepting messages. You can disconnect from the screen session using the key combination CTRL + A + D. When you are ready to reconnect to the session, you can use this screen
command:
- screen -r
You have successfully built a Discord bot using Python. The application runs on a server and responds to certain phrases shared in a Guild.
In this tutorial, you set up a Discord Guild, built a Discord bot, installed the bot in your Guild, and deployed the bot to an Ubuntu 20.04 server. You’ve only begun to explore the Discord API. Bots are powerful and extendable. To explore other capabilities, check out the discord.py API docs.
Alternately, if you wish learn more about Python programming, visit our tutorial series, How To Code in Python 3.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Are we able to run our bots using digital ocean apps? I would prefer to do it that way if possible.
I tried it initially, but it crashes after 1-2 messages.