This comprehensive tutorial will guide you through the process of setting up Botkit, creating your first bot extension using Pycord, and understanding the core concepts of Discord bot development.
Before we begin, ensure you have the following:
- Python 3.11 or higher installed
- Basic understanding of Python and Discord concepts
- A Discord account and access to the Discord Developer Portal
Tip
If you haven't already, create a Discord application and bot user in the Discord Developer Portal. You'll need the bot token for later steps.
If you don't have Git installed, you'll need to install it to clone the Botkit repository.
- Visit the Git website and download the appropriate version for your operating system.
- Follow the installation instructions for your OS.
Tip
On Windows, you can use the Git Bash terminal that comes with Git for a Unix-like command-line experience.
To verify Git is installed correctly, open a terminal or command prompt and run:
git --version
You should see the installed Git version in the output.
Now that Git is installed, let's clone the Botkit repository:
- Open a terminal or command prompt.
- Navigate to the directory where you want to store your bot project.
- Run the following command:
git clone https://github.com/nicebots-xyz/botkit
- Once the cloning is complete, navigate into the Botkit directory:
cd botkit
[!INFO] Cloning the repository creates a local copy of Botkit on your machine, allowing you to build your bot using the Botkit framework.
Install the required dependencies using PDM (Python Dependency Manager):
- If you haven't installed PDM yet, install it using pip:
pip install pdm
- Install the project dependencies:
pdm install
Note
PDM will read the pyproject.toml
file and install all necessary dependencies
for Botkit.
- In the root directory of your Botkit project, create a file named
config.yml
. - Open
config.yml
in a text editor and add the following content:
bot:
token: "YOUR_BOT_TOKEN_HERE"
slash:
enabled: true # Required for slash commands to work
Replace YOUR_BOT_TOKEN_HERE
with the actual token of your Discord bot.
Caution
Never share your bot token publicly or commit it to version control. Treat it like a password.
Now, let's create a new folder for our extension:
- Navigate to the
src/extensions
directory in your Botkit project. - Create a new folder called
my_first_extension
:
mkdir src/extensions/my_first_extension
The __init__.py
file is crucial for Python to recognize the directory as a package:
- Inside the
my_first_extension
folder, create a file named__init__.py
:
touch src/extensions/my_first_extension/__init__.py
- Open
__init__.py
in your preferred text editor and add the following content:
from .main import setup, default
__all__ = ["setup", "default"]
Note
This file imports and exposes the necessary components from our main.py
file
(which we'll create next). It allows Botkit to access these components when loading
the extension.
The main.py
file will contain the main logic for our extension:
- In the
my_first_extension
folder, create a file namedmain.py
:
touch src/extensions/my_first_extension/main.py
- Open
main.py
in your text editor and add the following content:
import discord
from discord.ext import commands
from typing import Dict, Any
class MyFirstExtension(commands.Cog):
def __init__(self, bot: discord.Bot):
self.bot = bot
def setup(bot: discord.Bot):
bot.add_cog(MyFirstExtension(bot))
default = {
"enabled": True
}
Let's break down what we've done here:
- We import the necessary modules from discord and discord.ext.
- We use
typing
to add type hints, which improves code readability and helps catch errors early. - We define a
MyFirstExtension
class that inherits fromcommands.Cog
. This class will contain our commands and listeners. - The
setup
function is required by Botkit to add our cog to the bot. - We define a
default
dictionary for the extension's configuration.
Tip
Using type hints (like bot: discord.Bot
) helps catch errors early and
improves code readability. It's a good practice to use them consistently in your code.
Now, let's add some commands to our extension. We'll create a simple "hello" command and a more complex "userinfo" command.
Add the following methods to your MyFirstExtension
class in main.py
:
@discord.slash_command(name="hello", description="Say hello to the bot")
async def hello(self, ctx: discord.ApplicationContext):
await ctx.respond(f"Hello, {ctx.author.name}!")
@discord.slash_command(name="userinfo", description="Get information about a user")
async def userinfo(
self,
ctx: discord.ApplicationContext,
user: discord.Option(discord.Member, "The user to get info about", default=None)
):
user = user or ctx.author
embed = discord.Embed(title=f"User Info - {user.name}", color=user.color)
embed.set_thumbnail(url=user.display_avatar.url)
embed.add_field(name="ID", value=user.id)
embed.add_field(name="Joined Server", value=user.joined_at.strftime("%Y-%m-%d %H:%M:%S"))
embed.add_field(name="Account Created", value=user.created_at.strftime("%Y-%m-%d %H:%M:%S"))
embed.add_field(name="Roles", value=", ".join([role.name for role in user.roles[1:]]) or "None")
await ctx.respond(embed=embed)
Let's explain these commands:
-
The
hello
command:- Uses the
@discord.slash_command
decorator to create a slash command. - Takes only the
ctx
(context) parameter, which is automatically provided by Discord. - Responds with a greeting using the author's name.
- Uses the
-
The
userinfo
command:- Also uses
@discord.slash_command
to create a slash command. - Takes an optional
user
parameter, which defaults to the command author if not provided. - Creates an embed with various pieces of information about the user.
- Responds with the created embed.
- Also uses
Note
Slash commands are the modern way to create Discord bot commands. They provide better user experience and are easier to discover than traditional prefix-based commands.
Let's add an event listener to our extension to demonstrate how to respond to Discord events. We'll add a simple listener that logs when the bot is ready.
Add the following method to your MyFirstExtension
class in main.py
:
@commands.Cog.listener()
async def on_ready(self):
print(f"Bot is ready! Logged in as {self.bot.user}")
This listener will print a message to the console when the bot has successfully connected to Discord.
Tip
Event listeners are great for performing actions based on Discord events, such as when a member joins a server or when a message is deleted.
Your complete main.py
file should now look like this:
import discord
from discord.ext import commands
from typing import Dict, Any
class MyFirstExtension(commands.Cog):
def __init__(self, bot: discord.Bot):
self.bot = bot
@discord.slash_command(name="hello", description="Say hello to the bot")
async def hello(self, ctx: discord.ApplicationContext):
await ctx.respond(f"Hello, {ctx.author.name}!")
@discord.slash_command(name="userinfo", description="Get information about a user")
async def userinfo(
self,
ctx: discord.ApplicationContext,
user: discord.Option(discord.Member, "The user to get info about", default=None)
):
user = user or ctx.author
embed = discord.Embed(title=f"User Info - {user.name}", color=user.color)
embed.set_thumbnail(url=user.display_avatar.url)
embed.add_field(name="ID", value=user.id)
embed.add_field(name="Joined Server", value=user.joined_at.strftime("%Y-%m-%d %H:%M:%S"))
embed.add_field(name="Account Created", value=user.created_at.strftime("%Y-%m-%d %H:%M:%S"))
embed.add_field(name="Roles", value=", ".join([role.name for role in user.roles[1:]]) or "None")
await ctx.respond(embed=embed)
@commands.Cog.listener()
async def on_ready(self):
print(f"Bot is ready! Logged in as {self.bot.user}")
def setup(bot: discord.Bot):
bot.add_cog(MyFirstExtension(bot))
default = {
"enabled": True
}
Now that we've created our extension, let's run the bot:
- Make sure you're in the root directory of your Botkit project.
- Run the following command:
pdm run start
Important
Ensure your bot token is correctly set in the config.yml
file before
running the bot.
If everything is set up correctly, you should see the "Bot is ready!" message in your console, indicating that your bot is now online and ready to respond to commands.
Congratulations! You've now created your first bot extension using Botkit and Pycord. This extension includes:
- A simple "hello" slash command
- A more complex "userinfo" slash command that creates an embed
- An event listener for the "on_ready" event
Tip
To continue improving your bot, consider adding more commands, implementing additional event listeners, or integrating with external APIs or databases.
Warning
Always be cautious when handling user data and permissions in your bot. Ensure you're following Discord's Terms of Service and Developer Policy.
Remember to always use type hinting in your code. It helps with code readability, catches potential errors early, and provides better autocomplete suggestions in many IDEs.
Happy coding, and enjoy building your Discord bot!