Skip to content

Instantly share code, notes, and snippets.

@Samarthh2601
Last active October 3, 2023 14:11
Show Gist options
  • Save Samarthh2601/426ec7974f705303a2363c739dd82309 to your computer and use it in GitHub Desktop.
Save Samarthh2601/426ec7974f705303a2363c739dd82309 to your computer and use it in GitHub Desktop.

What exactly is a discord bot?


Discord bots are AI-driven tools that can help you automate tasks on your Discord server. They make it a lot easier to build a community that is truly engaged and can be used to moderate your server, welcome new members, or even ban people who are creating a bad environment for everyone else. Aside from moderation features, Discord bots let you and users add games, music, memes, and other fun, engaging, and entertaining content. Popular bots are a few like Mee6, Carl-Bot, Hydra, Dank Memer and more!

Requirements to start making bots with python


Before you start coding discord bots with python, there are some requirements that are necessary to get a full-fledged understanding about the working of the bots!

Few requirements are as follows:

  • Basic knowledge of variables, data types, keywords and some commonly used in-built functions in python
  • String methods, List methods, Dictionary methods, Set methods
  • Familiar with asynchronous programming within python. [Use case of keywords such as async and await and the library asyncio]
  • Have familiarity with Object Oriented Programming within python
  • An understanding about indentation
  • Have knowledge about scopes of variables, et cetera
  • Importing of libraries and local files into each other
  • Type Hinting of variables and parameters!

Creating your first bot application on discord and inviting it to your server!


Prior to starting to code a discord bot, there's some steps to follow to create a bot and invite it to a discord server! You can follow the steps below to get started!

  • Visit the discord developer portal and sign up/login.

  • Now click on the Applications tab from the left pane.

  • Now click on the New Application button from the top-right corner.

  • A prompt will appear to enter the name of your application AKA your bot. Type in your desired name and hit Create. This will take you to your bot's control panel webpage!

  • (Optional) In the General tab (selected by default), you can upload an avatar for your bot by clicking on your bot's current shown avatar or remove the avatar as desired!

  • Click on the Bot tab from the left pane and hit Add Bot and click Yes, do it!. If a messages with A wild bot has appeared! is flashed on your screen, this means that you have successfully added your first bot to an app on discord! Note: If you get an error such as Too many users have this username, please try another.. Head over to the General Information tab and change your application's name from the text box and hit Save Changes, now follow the same step again.

  • Now scroll down in the Bot tab and enable the Message Content intent and Members intent.

  • Go to the Oauth2 tab from the left pane and click on the URL Generator tab from the drop down and select bot from the list of scopes. This will show the same list of permissions as from the Bot page! Select the View Channels/Read Messages, Send Messages permissions (or others if required) and while this generates a URL at the bottom of the webpage, copy the URL and paste it in a new tab of your web browser and invite the bot to your test server!

  • With this you have now created your first bot and added it your server!

How actually is a discord bot with python made?


Discord bots work with a gateway connection from a piece of code sending requests to the API to perform certain functions. This seems a bit hectic to code by yourself and so to make life easier, API wrappers for python for the discord API such as discord.py, hikari, etc. were created! In this tutorial, we will use the discord.py library to code our first discord bot! A discord bot uses a token to connect your bot app with the gateway, you can find the token in the Bot page of your application! You may have to reset the token to copy it. We will need the token shortly!

Installing discord.py


The latest and up-to-date usable discord.py version can be installed using pip install discord.py

What are intents?


Intents is a feature of Discord that tells the gateway exactly which events to send your bot. By default discord.py has all intents enabled except for Members, Message Content, and Presences. These are needed for features such as on_member events, to get access to message content, and to get members' statuses.

Coding our first discord bot with python!


import discord
from discord.ext import commands

intents = discord.Intents.default()
intents.members = True
intents.message_content = True

bot = commands.Bot(command_prefix="!", intents=intents)

bot.run("token that you copied")

The above code will basically do nothing other than getting your bot online for the first time!

EXPLANATION

  • import discord imports the discord.py package that we just installed.
  • from discord.ext import commands imports the commands extension from the discord.py package!
  • intents = discord.Intents.default() enables all the unprivileged intents, in essence, all the intents excluding Members, Presences, Message Content intents are enabled. Now the bot will receive all the events except the privileged intents!
  • intents.members = True enables the Members intent in our code which tells discord.py to receive all Member events from the gateway!
  • intents.message_content = True enables the Message Content intent in our code which tells discord.py to connect with the discord gateway so as your bot is able to read the content of the messages sent by other users. Message content is required to detect invocation of message commands such as !ping, et cetera.
  • bot = commands.Bot(command_prefix="!", intents=intents) basically creates a Bot object which acts as a multi-purpose container which holds your message commands and slash commands, user commands et cetera. A Bot object is also capable of fetching guilds (servers) and users from the discord API itself to receive information about the same!
  • bot.run("token") connects your current bot application with the corresponding token passed to the run method and creates an active websocket connection with the discord gateway which frequently sends heartbeats to the discord API to keep the websocket connection with the discord API from dying. This is how the bot gets online! Note that this method creates an infinite loop and no code below this method will ever run!

Creating commands with discord.py for the bot!


Basic Structure of a message command in discord.py!


Message commands in discord.py are held by the Bot itself and created through the Bot.command method of the Bot class. An asynchronous function is decorated with this method which indicates to discord.py that the decorated function is to be a message command! The function takes a default argument which is an instance of a Context object and is to be the first parameter of the function. This parameter is internally handled by discord.py whenever a command invocation occurs! The Context argument holds useful information about the invoked command and invoker of the command! The Context argument is also named as ctx by convention! If no name of the command is specified in the decorator for the command, then the name of the function is used for the command name instead! A simple message command in action!

bot = commands.Bot(command_prefix="!", intents=...)

@bot.command(name="hello")
async def hello(ctx: commands.Context) -> None:
    await ctx.send("Hello There!")

The hello command can be invoked by !hello. Make sure to enable the message content intent too!

A simple bot with a Message command!


import discord
from discord.ext import commands

intents = discord.Intents.default()
intents.members = True
intents.message_content = True

bot = commands.Bot(command_prefix="!", intents=intents)

@bot.command()
async def hello(ctx: commands.Context) -> None:
    await ctx.send("Hello There!")

bot.run("token that you copied")

Creating a more complex command!


The following command will return a quote from an API!

import discord
from discord.ext import commands 
import aiohttp

intents = discord.Intents.default()
intents.members = True
intents.message_content = True

bot = commands.Bot(command_prefix="!", intents=intents)

@bot.command()
async def quote(ctx: commands.Context) -> None:
    resp = await bot.http.get("https://zenquotes.io/api/random")
    if resp.status != 200:
        return await ctx.reply("Could not get a quote!")
    data = await resp.json()[0]
    await ctx.send(f"**{data['q']}** - *{data['a']}*")

async def main() -> None:
    async with bot:
        async with aiohttp.ClientSession() as session:
            bot.http = session
            await bot.start("token")

NOTE: start is another method which is the same as run.

  • Here a single ClientSession has been created to save resources rather than creating a ClientSession on every command invocation which would have been unnecessary and a bad practice.
  • bot.http basically acts a container for the ClientSession object which can be used anywhere in the code and the value of the variable can be set from anywhere and any command! Such variables are known as bot variables and helpful for if facing any variable scope issues! Before naming your bot variables, it is important to check what you name them as you are likely to overwrite a property or method of the Bot class such as command, cogs, et cetera. NOTE: Use the aiohttp library instead of requests as discord bots are asynchronous and requests is not an asynchronous library which if used will block all the other functions and the internal heartbeat sending requests to the discord API, eventually disconnecting your bot from the gateway and terminating the connection.

Retrieving user information!

import discord
from discord.ext import commands
import asyncio
import aiohttp

intents = discord.Intents.default()
intents.members = True
intents.message_content = True

bot = commands.Bot(command_prefix="!", intents=intents)

#getting the information about the author of the command invocation
@bot.command()
async def username(ctx: commands.Context) -> None:
    await ctx.send(ctx.author.name)

bot.run("token")

The above command when run using !username will send back the name of the author of the command invocation!

Sending Embeds

import discord
from discord.ext import commands
import asyncio
import aiohttp

intents = discord.Intents.default()
intents.members = True
intents.message_content = True

bot = commands.Bot(command_prefix="!", intents=intents)

@bot.command()
async def embed(ctx: commands.Context, *, text: str) -> None:
    embed = discord.Embed(title=ctx.author.name, description=text, colour=discord.Colour.random()).set_thumbnail(url=ctx.author.display_avatar.url)
    await ctx.send(embed=embed)

bot.run("token")
  • In the embed command, we can see a new parameter definition named as text here. This will simply allow us to accept another argument passed during command invocation. For example !embed this is my text will capture the content from this to text in the parameter named as text. The presence of * which makes the text argument a keyword-argument captures the whole argument sent after a space ( ) as arguments work on the basis of spaces. If * was absent, then the argument content which would have been captured would just have been this instead of this is my text.
  • embed = discord.Embed(...) initiates an Embed object to which the arguments are passed. .set_thumbnail sets an image of the avatar of the author on the top-right corner of the embed and await ctx.send(embed=embed) sends an embed back as a response. Note that embed= is a keyword-argument.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment