Skip to content

What it is

discord.py is a Python library for interacting with the Discord API. It allows developers to create bots that can interact with Discord servers, send and receive messages, manage roles, and respond to events programmatically.

The library allows you to create bots that respond to messages, commands, reactions, and events. It supports creating commands with decorators, listening to events, handling permissions, and integrating with Discord servers seamlessly.

Installation

pip install discord.py

Getting started

The smallest useful thing you can do with it, and what each part means.

Simple bot responding to messages
import discord
from discord.ext import commands

TOKEN = 'YOUR_BOT_TOKEN'
bot = commands.Bot(command_prefix='!')

@bot.event
async def on_ready():
    print(f'Logged in as {bot.user}')

@bot.command()
async def hello(ctx):
    await ctx.send('Hello! I am your bot.')

bot.run(TOKEN)
Creates a bot that responds to the command `!hello` with a greeting message.
Sending a message to a channel
channel = bot.get_channel(CHANNEL_ID)
await channel.send('Hello, Discord!')
Sends a message to a specific channel using the bot instance.

Advanced usage

Where the library earns its place over a simpler alternative.

Handling reactions
@bot.event
async def on_reaction_add(reaction, user):
    if user != bot.user:
        await reaction.message.channel.send(f'{user} reacted with {reaction.emoji}')
Replies with the reaction added by users, ignoring the bot’s own reactions.
Creating embeds
from discord import Embed
embed = Embed(title='Sample Embed', description='This is an embed', color=0x00ff00)
await ctx.send(embed=embed)
Creates a rich embedded message with title, description, and color.
Listening to events
@bot.event
async def on_member_join(member):
    await member.send('Welcome to the server!')
Sends a private welcome message to users when they join the server.
Cog example for modular commands
from discord.ext import commands

class MyCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def ping(self, ctx):
        await ctx.send('Pong!')

bot.add_cog(MyCog(bot))
Organizes bot commands in a class (Cog) for modularity and clean code structure.
Using asynchronous tasks
import asyncio

@bot.event
async def on_ready():
    while True:
        print('Bot is running')
        await asyncio.sleep(60)
Runs a repeating asynchronous task every 60 seconds when the bot is ready.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

discord.errors.LoginFailure
Check that your bot token is correct and valid.
discord.errors.Forbidden
Ensure the bot has the necessary permissions to perform the action.
discord.errors.HTTPException
Handle network errors, invalid requests, or API limitations.

Best practices

  • Use cogs to organize commands and events for larger bots.
  • Handle exceptions in events and commands to prevent bot crashes.
  • Use asynchronous programming to avoid blocking operations.
  • Keep bot tokens secure using environment variables.
  • Respect Discord rate limits to avoid being banned.

Background

Why it exists, and what it was reacting to.

discord.py was created by Rapptz to provide a Pythonic interface to the Discord API. It abstracts HTTP requests and WebSocket connections, allowing developers to focus on bot logic and automation. It supports both synchronous and asynchronous programming, enabling scalable and responsive bots.