Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Coding Introduction

In this lesson, you’ll take your first steps in implementing your bot user, by creating a connection to Discord. You’ll install the discord.py library, and use it to create an instance of Client. You’ll also need to manage your Discord token, and keep it secret during development. To accomplish this you’ll use the dotenv library.

00:00 This is part five. In this time, you’ll be introduced to the coding required to begin making your bot user interactive. Now, since you’re here to learn how to make a Discord bot in Python, you’ll be using the discord.py file. discord.py, from now on I’ll refer to discord.py, is a Python library that exhaustively implements Discord’s APIs in an efficient and Pythonic way.

00:25 This includes utilizing Python’s implementation of Async IO. The first thing you have to do is install discord.py. If you are doing that in a shell or terminal window or something similar to that, you would do this with pip install -U discord.py.

00:43 However, if you’re like me and you like to use a Thonny IDE, you can install discord.py by using the package manager. You can access the package manager by going to the Tools menu,

00:55 and selecting Manage packages.

00:57 Search for discord.py

01:02 and click the Install button. I already have it installed, so I can’t re-install it, but as you can see, I can uninstall it or upgrade it when available. Once it completes installing, you can close that dialogue box and it’s ready to use.

01:16 So, let’s use it to create your first connection to Discord. In order to use discord.py, to create your first connection to Discord, or any connection to Discord, you need to create an instance of Client.

01:30 A Client is an object that represents a connection to Discord. A Client handles events, tracks state, and generally interacts with Discord APIs. What you have done with this script here—and a copy of this will be available for download—is create a Client and implemented its on_ready() event handler, which handles the event when the Client has established a connection to Discord, and it has finished preparing the data that Discord has sent, such as login state, guild and channel data, and more. In other words, the on_ready() method will be called, and then your message printed, once client is ready for further action.

02:09 You will learn more about event handlers a little further on in the course. Now, when you were working with, for lack of a better word, secrets, like your Discord token, just there—no, that is not an actual token—it is good practice to read it into your program using an environment variable.

02:27 Using an environment variable allows you to avoid putting “secrets” into source control. It also allows you to use different variables for development environments and production environments without having to remember to manually change your code. Now, while you could use something like export discord_token={your-token-here},

02:53 keep in mind, {your-token-here} is just a place holder, you would have to replace it with your actual token. An easier solution than this is to save a .env file on all machines that will be running this code.

03:09 Not only is this easier, as you won’t have to export your token every time that you clear the shell, but it also protects you from having to store any “secrets” in your shell’s history.

03:20 Create a new file and call it .env and put it in the same folder as your bot.py file. You will, of course, need to replace the {your-token-here} with your actual Discord token.

03:36 Please note, at this point that a .env file is not a file type that is specific to Python. Its syntax rules are a little different to Python.

03:45 This means that you will need to replace the entire section of {your-token-here}, including the curly braces. There should be nothing except your token after the equal sign. In order to get your Discord bot token, you take it from the Developer Portal page, click on the Bot menu again, on the left-hand side of the window, and click Copy beneath where it says Click to Reveal Token, just here.

04:12 You can regenerate it, if you feel it has been taken by somebody else, but generally speaking, especially when you’re first creating the bot, you won’t need to do that.

04:21 You’re going to have to believe that I’ve replaced the placeholder with my actual token. As mentioned earlier, it is a “secret”. You should never let anybody else see your Discord token, unless they are developing a bot with you and you really trust them. Now, if you look back at the bot.py code, you will see an import from a library called dotenv.

04:45 This library is useful for working with .env files.

04:50 load_dotenv loads environment variables from an .env file into your shell’s environment variables so that you can use them in your code.

05:01 You can install dotenv using pip, like this,

05:06 or again, if you’re using Thonny, like I prefer to, you can just install it using the package manager as was shown earlier. Ensure you search for python-dotenv as it’s shown here.

05:19 If you don’t, you will not get the correct library. Finally, within your code again, client.run() runs your Client using your bot’s token.

05:30 Now that you have set up both bot.py and your .env file, you can run your code. Let’s try that now. You can see it running bot.py,

05:43 and now you can see it has successfully connected to Discord. Great stuff! You have now reached the end of this particular video. If you watch the next one, you will build on this Client by interacting with more Discord APIs.

Avatar image for vincentstclair

vincentstclair on Aug. 4, 2020

I ran my code and got an SSL cert error. Followed all of the directions, and am using the same exact code as provided.

Traceback (most recent call last):
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/aiohttp/connector.py", line 936, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore  # noqa
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/base_events.py", line 1050, in create_connection
    transport, protocol = await self._create_connection_transport(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/base_events.py", line 1080, in _create_connection_transport
    await waiter
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/sslproto.py", line 529, in data_received
    ssldata, appdata = self._sslpipe.feed_ssldata(data)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/sslproto.py", line 189, in feed_ssldata
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/ssl.py", line 944, in do_handshake
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1108)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "my_discord_bot.py", line 16, in <module>
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/discord/client.py", line 640, in run
    return future.result()
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/discord/client.py", line 621, in runner
    await self.start(*args, **kwargs)
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/discord/client.py", line 584, in start
    await self.login(*args, bot=bot)
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/discord/client.py", line 442, in login
    await self.http.static_login(token.strip(), bot=bot)
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/discord/http.py", line 261, in static_login
    data = await self.request(Route('GET', '/users/@me'))
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/discord/http.py", line 165, in request
    async with self.__session.request(method, url, **kwargs) as r:
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/aiohttp/client.py", line 1012, in __aenter__
    self._resp = await self._coro
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/aiohttp/client.py", line 480, in _request
    conn = await self._connector.connect(
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/aiohttp/connector.py", line 523, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/aiohttp/connector.py", line 858, in _create_connection
    _, proto = await self._create_direct_connection(
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/aiohttp/connector.py", line 1004, in _create_direct_connection
    raise last_exc
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/aiohttp/connector.py", line 980, in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
  File "/Users/EDITED/Desktop/Python_Virtual_Environments/Discord/lib/python3.8/site-packages/aiohttp/connector.py", line 938, in _wrap_create_connection
    raise ClientConnectorCertificateError(
aiohttp.client_exceptions.ClientConnectorCertificateError: Cannot connect to host discordapp.com:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1108)')]
Avatar image for vincentstclair

vincentstclair on Aug. 4, 2020

Fixed the issue. If you’re on a Mac, and you’re having similar issues, go check out the fix here: stackoverflow.com/questions/50236117/scraping-ssl-certificate-verify-failed-error-for-http-en-wikipedia-org

Avatar image for saifaljuhayni

saifaljuhayni on March 21, 2021

I got this error:

>>> %Run bot.py
Traceback (most recent call last):
  File "C:\Users\saifm\AppData\Roaming\Python\Python37\site-packages\bot.py", line 16, in <module>
  File "C:\Users\saifm\AppData\Roaming\Python\Python37\site-packages\discord\client.py", line 718, in run
    return future.result()
  File "C:\Users\saifm\AppData\Roaming\Python\Python37\site-packages\discord\client.py", line 697, in runner
    await self.start(*args, **kwargs)
  File "C:\Users\saifm\AppData\Roaming\Python\Python37\site-packages\discord\client.py", line 660, in start
    await self.login(*args, bot=bot)
  File "C:\Users\saifm\AppData\Roaming\Python\Python37\site-packages\discord\client.py", line 509, in login
    await self.http.static_login(token.strip(), bot=bot)
AttributeError: 'NoneType' object has no attribute 'strip'
Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on March 22, 2021

@saifaljuhayni It looks like the token variable in line 509 contains an empty value of None instead of the expected string:

await self.http.static_login(token.strip(), bot=bot)

Did you forget to set the DISCORD_TOKEN environment variable with your own Discord login token? If not, then maybe it’s not set within the same runtime enviromnent that you’re running your script?

Avatar image for mikecaronna

mikecaronna on June 14, 2021

I got an error that said ‘module’ object is not callable

Avatar image for Martin Breuss

Martin Breuss RP Team on June 15, 2021

Hi @mikecaronna. When and where are you getting that error, and what does the error message say exactly?

It’s possible that you have a set of parentheses () somewhere where they shouldn’t be, which means to Python that you want to call an object. However, only some objects are callable, and it seems that the object called “module” that you’re trying to call, isn’t.

However, it’s hard to give you any better pointers than this unless you share more information about your code and the error message here.

Avatar image for knizami

knizami on July 8, 2022

I’m using visual studio code and because of this when I create a new file it wont allow me to make it an any file like he did so I cannot change the file to an .env file which makes an error in my code because then token is not receiving anything. Does anyone have a solution to this error.

Avatar image for Chad Hidalgo

Chad Hidalgo on Oct. 7, 2022

I am getting this error at runtime:

Traceback (most recent call last): File line 10, in <module> client = discord.Client() TypeError: init() missing 1 required keyword-only argument: ‘intents’

Process finished with exit code 1

Avatar image for Chad Hidalgo

Chad Hidalgo on Oct. 7, 2022


You could use notepad or notepad++ to create the .env file and just be sure to save it in the same folder that your python file is saved.

Avatar image for Chad Hidalgo

Chad Hidalgo on Oct. 7, 2022

Replying to my own post with correction found on Stack Overflow

add under token = os.getenv(‘DISCORD_TOKEN’)

intents = discord.Intents.default()

modify client = discord.Client()

client = discord.Client(intents=intents)

[2022-10-06 17:38:34] [INFO ] discord.client: logging in using static token [2022-10-06 17:38:35] [INFO ] discord.gateway: Shard ID None has connected to Gateway AIRbot#4779 has connected to Discord!

Avatar image for Prade

Prade on June 30, 2023

I keep getting this error even though i have installed python-dotenv

Traceback (most recent call last): File “C:\Users\Kor\discordMod\bot.py”, line 5, in <module> from dotenv import load_dotenv ModuleNotFoundError: No module named ‘dotenv’

Avatar image for Martin Breuss

Martin Breuss RP Team on July 3, 2023

@Prade did you create and activate a virtual environment before installing python-dotenv? And are you running the Python script with the interpreter of your virtual environment?

The error seems to say that the package isn’t installed in the environment that you’re running the Python script in.

Become a Member to join the conversation.