Skip to main content

Bot

The Bot class represents a Discord bot with application command support. This class is a subclass of discord.Client and provides functionality to manage and register application commands (slash commands, user commands, message commands).
import discord

bot = discord.Bot()

@bot.slash_command(description="A simple slash command")
async def hello(ctx):
    await ctx.respond("Hello!")

bot.run('token')

Constructor

Bot

Bot(
    description: str | None = None,
    *,
    debug_guilds: list[int] | None = None,
    auto_sync_commands: bool = True,
    owner_id: int | None = None,
    owner_ids: Collection[int] | None = None,
    default_command_contexts: Collection[InteractionContextType] = {
        InteractionContextType.guild,
        InteractionContextType.bot_dm,
        InteractionContextType.private_channel
    },
    default_command_integration_types: Collection[IntegrationType] = {
        IntegrationType.guild_install
    },
    **options
)
description
str | None
default:"None"
The content prefixed into the default help message.
debug_guilds
list[int] | None
default:"None"
Guild IDs of guilds to use for testing commands. The bot will not create any global commands if debug guild IDs are passed.
auto_sync_commands
bool
default:"True"
Whether to automatically sync slash commands. This will call sync_commands() in on_connect, and in process_application_commands if the command is not found.
owner_id
int | None
default:"None"
The user ID that owns the bot. If this is not set and is then queried via is_owner() then it is fetched automatically.
owner_ids
Collection[int] | None
default:"None"
The user IDs that own the bot. For performance reasons it is recommended to use a set. You cannot set both owner_id and owner_ids.
default_command_contexts
Collection[InteractionContextType]
The default context types that the bot will use for commands.
default_command_integration_types
Collection[IntegrationType]
The default integration types that the bot will use for commands.
**options
Any
Additional options to pass to the Client constructor (intents, max_messages, etc.).

Attributes

description
str
The content prefixed into the default help message.
owner_id
int | None
The user ID that owns the bot.
owner_ids
Collection[int] | None
The user IDs that own the bot.
debug_guilds
list[int] | None
Guild IDs of guilds to use for testing commands.
auto_sync_commands
bool
Whether to automatically sync slash commands.
application_commands
list[ApplicationCommand]
A list of all application commands registered to the bot.
pending_application_commands
list[ApplicationCommand]
A list of commands that have been added but not yet registered (read-only).
commands
list[ApplicationCommand]
Returns all commands (application commands and prefixed commands if using ext.commands).

Command Registration

slash_command

@bot.slash_command(
    name: str = None,
    description: str = None,
    guild_ids: list[int] | None = None,
    **kwargs
)
A decorator for adding a slash command to the bot.
name
str
default:"function name"
The name of the slash command. Defaults to the function name.
description
str
default:"No description provided"
The description of the slash command.
guild_ids
list[int] | None
default:"None"
A list of guild IDs where this command should be registered. If None, it will be a global command.
Example:
@bot.slash_command(description="Sends a greeting")
async def hello(ctx, name: str):
    await ctx.respond(f"Hello {name}!")

user_command

@bot.user_command(
    name: str = None,
    guild_ids: list[int] | None = None,
    **kwargs
)
A decorator for adding a user command (context menu) to the bot.
name
str
default:"function name"
The name of the user command.
guild_ids
list[int] | None
default:"None"
A list of guild IDs where this command should be registered.
Example:
@bot.user_command(name="Get User Info")
async def user_info(ctx, user: discord.User):
    await ctx.respond(f"User: {user.name}")

message_command

@bot.message_command(
    name: str = None,
    guild_ids: list[int] | None = None,
    **kwargs
)
A decorator for adding a message command (context menu) to the bot.
name
str
default:"function name"
The name of the message command.
guild_ids
list[int] | None
default:"None"
A list of guild IDs where this command should be registered.
Example:
@bot.message_command(name="Quote Message")
async def quote(ctx, message: discord.Message):
    await ctx.respond(f"Quote: {message.content}")

application_command

@bot.application_command(
    cls: type[ApplicationCommand] = SlashCommand,
    **kwargs
)
A decorator that converts the provided function into an application command and adds it to the bot.
cls
type[ApplicationCommand]
default:"SlashCommand"
The factory class that will be used to create the command. Should be SlashCommand, MessageCommand, or UserCommand.

command

@bot.command(**kwargs)
An alias for application_command(). This decorator is overridden by discord.ext.commands.Bot.

Command Groups

create_group

bot.create_group(
    name: str,
    description: str | None = None,
    guild_ids: list[int] | None = None,
    **kwargs
) -> SlashCommandGroup
Creates a slash command group with no subcommands and adds it to the bot.
name
str
required
The name of the group to create.
description
str | None
default:"No description provided"
The description of the group to create.
guild_ids
list[int] | None
default:"None"
A list of the IDs of each guild this group should be added to.
Returns: The slash command group that was created.Example:
grp = bot.create_group("config", "Configuration commands")

@grp.command()
async def set_prefix(ctx, prefix: str):
    await ctx.respond(f"Prefix set to {prefix}")

group

@bot.group(
    name: str | None = None,
    description: str | None = None,
    guild_ids: list[int] | None = None
)
class MyGroup(discord.SlashCommandGroup):
    pass
A decorator that initializes the provided subclass of SlashCommandGroup and adds it to the bot.
name
str | None
default:"class name"
The name of the group to create. Defaults to the decorated class name.
description
str | None
default:"class docstring"
The description of the group to create.
guild_ids
list[int] | None
default:"None"
A list of the IDs of each guild this group should be added to.
Example:
@bot.group()
class Settings(discord.SlashCommandGroup):
    """Bot settings commands"""

    @discord.slash_command()
    async def view(self, ctx):
        await ctx.respond("Current settings...")

Command Management

add_application_command

bot.add_application_command(command: ApplicationCommand) -> None
Adds an ApplicationCommand into the internal list of commands.
command
ApplicationCommand
required
The command to add.

remove_application_command

bot.remove_application_command(
    command: ApplicationCommand
) -> ApplicationCommand | None
Removes an ApplicationCommand from the internal list of commands.
command
ApplicationCommand
required
The command to remove.
Returns: The command that was removed, or None if not found.

get_application_command

bot.get_application_command(
    name: str,
    guild_ids: list[int] | None = None,
    type: type[ApplicationCommand] = ApplicationCommand
) -> ApplicationCommand | None
Gets an ApplicationCommand from the internal list of commands.
name
str
required
The qualified name of the command to get.
guild_ids
list[int] | None
default:"None"
The guild ids associated to the command to get.
type
type[ApplicationCommand]
default:"ApplicationCommand"
The type of the command to get.
Returns: The command that was requested, or None if not found.

walk_application_commands

bot.walk_application_commands() -> Generator[ApplicationCommand]
An iterator that recursively walks through all application commands and subcommands.Yields: ApplicationCommand - An application command from the internal list.

Command Syncing

sync_commands

await bot.sync_commands(
    commands: list[ApplicationCommand] | None = None,
    method: Literal["individual", "bulk", "auto"] = "bulk",
    force: bool = False,
    guild_ids: list[int] | None = None,
    register_guild_commands: bool = True,
    check_guilds: list[int] | None = None,
    delete_existing: bool = True
) -> None
Registers all commands that have been added through add_application_command(). This method syncs commands with Discord’s API.
commands
list[ApplicationCommand] | None
default:"None"
A list of commands to register. If None, all commands will be registered.
method
Literal['individual', 'bulk', 'auto']
default:"bulk"
The method to use when registering commands. bulk registers all at once, individual registers one at a time, auto determines automatically.
force
bool
default:"False"
Registers the commands regardless of the state of the command on Discord.
guild_ids
list[int] | None
default:"None"
A list of guild ids to register the commands for.
register_guild_commands
bool
default:"True"
Whether to register guild commands.
check_guilds
list[int] | None
default:"None"
A list of guild ids to check for commands to unregister.
delete_existing
bool
default:"True"
Whether to delete existing commands that are not in the list of commands to register.
By default, this coroutine is called inside the on_connect event. If you override on_connect, you should invoke this coroutine manually.
Example:
@bot.event
async def on_connect():
    if bot.auto_sync_commands:
        await bot.sync_commands()
    print(f"{bot.user.name} connected.")

register_commands

await bot.register_commands(
    commands: list[ApplicationCommand] | None = None,
    guild_id: int | None = None,
    method: Literal["individual", "bulk", "auto"] = "bulk",
    force: bool = False,
    delete_existing: bool = True
) -> list[ApplicationCommand]
Registers a list of commands.
commands
list[ApplicationCommand] | None
default:"None"
A list of commands to register. If None, all commands will be registered.
guild_id
int | None
default:"None"
If set, the commands will be registered as guild commands for this guild.
method
Literal['individual', 'bulk', 'auto']
default:"bulk"
The method to use when registering the commands.
force
bool
default:"False"
Registers the commands regardless of their state on Discord.
delete_existing
bool
default:"True"
Whether to delete existing commands that are not in the list.
Returns: The list of registered commands.

Command Processing

process_application_commands

await bot.process_application_commands(
    interaction: Interaction,
    auto_sync: bool | None = None
) -> None
Processes the commands that have been registered to the bot. Without this coroutine, none of the commands will be triggered.
interaction
Interaction
required
The interaction to process.
auto_sync
bool | None
default:"None"
Whether to automatically sync and unregister the command if it is not found. Defaults to bot.auto_sync_commands.
By default, this coroutine is called inside the on_interaction event. If you override on_interaction, you should invoke this coroutine.

invoke_application_command

await bot.invoke_application_command(ctx: ApplicationContext) -> None
Invokes the application command given under the invocation context and handles all the internal event dispatch mechanisms.
ctx
ApplicationContext
required
The invocation context to invoke.

get_application_context

await bot.get_application_context(
    interaction: Interaction,
    cls: Any = ApplicationContext
) -> ApplicationContext
Returns the invocation context from the interaction.
interaction
Interaction
required
The interaction to get the invocation context from.
cls
Any
default:"ApplicationContext"
The factory class that will be used to create the context.
Returns: The invocation context.

Checks and Hooks

check

@bot.check
def check_commands(ctx):
    return True
A decorator that adds a global check to the bot. A global check is applied to every command the bot has.Example:
@bot.check
def check_commands(ctx):
    return ctx.command.qualified_name in allowed_commands

add_check

bot.add_check(func, *, call_once: bool = False) -> None
Adds a global check to the bot. This is the non-decorator interface to check() and check_once().
func
Callable
required
The function that was used as a global check.
call_once
bool
default:"False"
If the function should only be called once per invoke call.

remove_check

bot.remove_check(func, *, call_once: bool = False) -> None
Removes a global check from the bot.
func
Callable
required
The function to remove from the global checks.
call_once
bool
default:"False"
If the function was added with call_once=True.

before_invoke

@bot.before_invoke
async def before_any_command(ctx):
    # Setup code
    pass
A decorator that registers a coroutine as a pre-invoke hook. Called directly before the command is called.

after_invoke

@bot.after_invoke
async def after_any_command(ctx):
    # Cleanup code
    pass
A decorator that registers a coroutine as a post-invoke hook. Called directly after the command is called.

Owner Check

is_owner

await bot.is_owner(user: User | Member) -> bool
Checks if a User or Member is the owner of this bot.
user
User | Member
required
The user to check for.
Returns: bool - Whether the user is the owner.

Error Handling

on_application_command_error

@bot.event
async def on_application_command_error(
    context: ApplicationContext,
    exception: DiscordException
) -> None
The default command error handler provided by the bot. By default, this prints to sys.stderr, however it could be overridden.
context
ApplicationContext
required
The ApplicationContext associated to the command that has an error.
exception
DiscordException
required
The DiscordException associated to the error.
Example:
@bot.event
async def on_application_command_error(ctx, error):
    if isinstance(error, commands.CommandOnCooldown):
        await ctx.respond(f"Command on cooldown. Try again in {error.retry_after:.2f}s")
    else:
        raise error

AutoShardedBot

The AutoShardedBot class is similar to Bot except that it automatically handles sharding for large bots. It is inherited from discord.AutoShardedClient instead of discord.Client.
import discord

bot = discord.AutoShardedBot()

@bot.slash_command()
async def hello(ctx):
    await ctx.respond(f"Hello from shard {ctx.bot.shard_id}!")

bot.run('token')

Constructor

AutoShardedBot

AutoShardedBot(
    description: str | None = None,
    *,
    debug_guilds: list[int] | None = None,
    auto_sync_commands: bool = True,
    shard_count: int | None = None,
    **options
)
All parameters from Bot are supported, plus sharding-specific parameters from AutoShardedClient.
shard_count
int | None
default:"None"
The number of shards to use. If None, Discord will determine the count automatically.

Features

The AutoShardedBot has all the same methods and attributes as Bot, but automatically distributes guilds across multiple shards for better performance with large bots.
Use AutoShardedBot when your bot is in 2,500+ guilds, or when you want to prepare for growth. Discord requires sharding once your bot reaches 2,500 guilds.

Build docs developers (and LLMs) love