Creating Commands#
You’re using a command handler library so naturally you’ll probably be wanting to make some commands for your bot.
If you haven’t made your first command yet, it is recommended that you read the Getting Started page before continuing.
Note
You should note that the order that the decorators are applied is rather important. The lightbulb.implements
decorator should always be on the bottom of the stack, followed by the lightbulb.command
decorator on top
of it. The bot.command
decorator must always be on the top of the stack if you are using it.
The Implements Decorator#
- lightbulb.decorators.implements(*command_types: Type[Command]) Callable[[CommandCallbackT], CommandCallbackT] [source]
Second order decorator that defines the command types that a given callback function will implement.
- Parameters:
*command_types (Type[
Command
]) – Command types that the function will implement.
This decorator acts as the base for every command you will make using Lightbulb.
It defines the type or multiple types of commands that the decorated callback function will implement.
For example:
import lightbulb
@lightbulb.implements(lightbulb.PrefixCommand)
async def foo(ctx: lightbulb.Context) -> None:
# This command will be invoked using the command prefix(es) that the bot recognises.
...
@lightbulb.implements(lightbulb.SlashCommand)
async def bar(ctx: lightbulb.Context) -> None:
# This command will be created as a slash command.
...
@lightbulb.implements(lightbulb.PrefixCommand, lightbulb.SlashCommand)
async def baz(ctx: lightbulb.Context) -> None:
# This command will be able to be invoked both using the bot's command prefix(es),
# and as a slash command using interactions.
...
The Command Decorator#
- lightbulb.decorators.command(name: str, description: str, *, cls: ~typing.Type[~lightbulb.commands.base.CommandLike] = <class 'lightbulb.commands.base.CommandLike'>, **kwargs: ~typing.Any) Callable[[CommandCallbackT], CommandLike] [source]
Second order decorator that converts the decorated function into a
CommandLike
object.- Parameters:
- Keyword Arguments:
error_handler (Optional[ListenerT]) – The function to register as the command’s error handler. Defaults to
None
. This can also be set with theset_error_handler
decorator.aliases (Sequence[
str
]) – Aliases for the command. This will only affect prefix commands. Defaults to an empty list.guilds (Sequence[
int
]) – The guilds that the command will be created in. This will only affect application commands. Defaults to an empty list.parser (
BaseParser
) – The argument parser to use for prefix commands. Defaults toParser
.auto_defer (
bool
) – Whether to automatically defer the response when the command is invoked. IfTrue
, the bot will send an initial response of typeDEFERRED_MESSAGE_CREATE
for interactions, and for prefix commands, typing will be triggered in the invocation channel.ephemeral (
bool
) – Whether to send responses from the invocation of this command as ephemeral by default. IfTrue
then all responses from the command will use the flaghikari.MessageFlags.EPHEMERAL
. This will not affect prefix commands as responses from prefix commands cannot be ephemeral.hidden (
bool
) – Whether to hide the command from the help command. Defaults toFalse
.inherit_checks (
bool
) – Whether or not the command should inherit checks from the parent group. Only affects subcommands. Defaults toFalse
.pass_options (
bool
) – Whether the command will have its options passed as keyword arguments when invoked.name_localizations (Mapping[Union[
hikari.locales.Locale
,str
],str
]) – A mapping of locale to name localizations for this command. Defaults to an empty dictionary.description_localizations (Mapping[Union[
hikari.locales.Locale
,str
],str
]) – A mapping of locale to description localizations for this command. Defaults to an empty dictionary.nsfw (
bool
) – Whether the command should only be enabled in NSFW channels. For prefix commands, this will add an NSFW-channel only check to the command automatically. For slash commands, this will behave as specified in the Discord documentation.cls (Type[
CommandLike
]) –CommandLike
class to instantiate from this decorator. Defaults toCommandLike
.
New in version 2.1.0:
cls
kwarg.New in version 2.2.1:
pass_options
kwarg.New in version 2.3.0:
name_localizations
anddescription_localizations
kwargs.
This decorator converts the decorated function into a lightbulb.commands.base.CommandLike
object. This object
can be coerced into any of the command classes that Lightbulb supports.
Given the fundamental differences between slash commands and prefix commands, not all kwargs will affect all of the command types that can be created.
For example:
import lightbulb
@lightbulb.command("foo", "test command", aliases=["bar", "baz"])
@lightbulb.implements(lightbulb.PrefixCommand)
async def foo(ctx: lightbulb.Context) -> None:
...
@lightbulb.command("foo", "test slash command", guilds=[123453463456, 34569827369])
@lightbulb.implements(lightbulb.SlashCommand)
async def _foo(ctx: lightbulb.Context) -> None:
...
The Option Decorator#
Basic commands that respond with set messages are cool, but sometimes you might want to take input from the user to allow you to create more complex commands and more complex flows.
Lightbulb provides the lightbulb.decorators.option
decorator for this purpose.
- lightbulb.decorators.option(name: str, description: str, type: ~typing.Any = <class 'str'>, *, required: bool | ~hikari.undefined.UndefinedType = UNDEFINED, choices: ~typing.Sequence[str | int | float | ~hikari.commands.CommandChoice] | None = None, channel_types: ~typing.Sequence[~hikari.channels.ChannelType] | None = None, default: ~typing.Any | ~hikari.undefined.UndefinedType = UNDEFINED, modifier: ~lightbulb.commands.base.OptionModifier = OptionModifier.NONE, min_value: float | int | None = None, max_value: float | int | None = None, min_length: int | None = None, max_length: int | None = None, autocomplete: bool | ~typing.Callable[[~hikari.interactions.command_interactions.CommandInteractionOption, ~hikari.interactions.command_interactions.AutocompleteInteraction], ~typing.Coroutine[~typing.Any, ~typing.Any, str | ~hikari.commands.CommandChoice | ~typing.Sequence[str | ~hikari.commands.CommandChoice]]] = False, cls: ~typing.Type[~lightbulb.commands.base.OptionLike] = <class 'lightbulb.commands.base.OptionLike'>, **kwargs: ~typing.Any) Callable[[CommandLike], CommandLike] [source]
Second order decorator that adds an option to the decorated
CommandLike
object.- Parameters:
- Keyword Arguments:
required (UndefinedOr[
bool
]) – Whether this option is required. This will be inferred from whether a default value for the option was specified if not otherwise specified.choices (Optional[Sequence[Union[
str
,int
,float
,CommandChoice
]]]) – The choices for the option. This will only affect slash commands. Defaults toNone
.channel_types (Optional[Sequence[hikari.channels.ChannelType]]) – The channel types allowed for the option. This will only affect slash commands. Defaults to
None
.default (UndefinedOr[Any]) – The default value for the option. Defaults to
UNDEFINED
.modifier (
OptionModifier
) – Modifier controlling how the option should be parsed. Defaults toOptionModifier.NONE
.min_value (Optional[Union[
float
,int
]]) – The minimum value permitted for this option (inclusive). Only available if the option type is numeric (integer or float). Defaults toNone
.max_value (Optional[Union[
float
,int
]]) – The maximum value permitted for this option (inclusive). Only available if the option type is numeric (integer or float). Defaults toNone
.min_length (Optional[
int
]) – The minimum length permitted for this option. Only available if this option is string type.max_length (Optional[
int
]) – The maximum length permitted for this option. Only available if this option is string type.autocomplete (Union[
bool
, AutocompleteCallbackT]) – Boolean representing whether the option will use autocomplete or the callback to use for autocomplete for this option. This will only affect slash commands. Defaults toFalse
.name_localizations (Mapping[Union[
hikari.locales.Locale
,str
],str
]) – A mapping of locale to name localizations for this option. Defaults to an empty dictionary.description_localizations (Mapping[Union[
hikari.locales.Locale
,str
],str
]) – A mapping of locale to description localizations for this option. Defaults to an empty dictionary.cls (Type[
OptionLike
]) –OptionLike
class to instantiate from this decorator. Defaults toOptionLike
.
New in version 2.1.0:
cls
kwarg.New in version 2.1.3:
min_value
andmax_value
kwargs.New in version 2.3.2:
min_length
andmax_length
kwargs.
For example:
import lightbulb
@lightbulb.option("text", "text to repeat", modifier=lightbulb.OptionModifier.CONSUME_REST)
@lightbulb.command("echo", "repeats the given text")
@lightbulb.implements(lightbulb.PrefixCommand)
async def echo(ctx: lightbulb.Context) -> None:
await ctx.respond(ctx.options.text)
Converters and Slash Command Option Types#
Below is a list of all the acceptable types that you can pass into the type
argument of the option
decorator. On
the left is the type to pass in, the right side is the converter that the type is mapped to, or for slash commands,
the hikari OptionType
that the type is mapped to.
Prefix command converter mapping:
Acceptable primitives: str
, int
, float
hikari.User
-lightbulb.converters.special.UserConverter
hikari.Member
-lightbulb.converters.special.MemberConverter
hikari.GuildChannel
-lightbulb.converters.special.GuildChannelConverter
hikari.TextableGuildChannel
-lightbulb.converters.special.TextableGuildChannelConverter
hikari.TextableChannel
-lightbulb.converters.special.TextableGuildChannelConverter
hikari.GuildCategory
-lightbulb.converters.special.GuildCategoryConverter
hikari.GuildVoiceChannel
-lightbulb.converters.special.GuildVoiceChannelConverter
hikari.Role
-lightbulb.converters.special.RoleConverter
hikari.Emoji
-lightbulb.converters.special.EmojiConverter
hikari.Guild
-lightbulb.converters.special.GuildConverter
hikari.Message
-lightbulb.converters.special.MessageConverter
hikari.Invite
-lightbulb.converters.special.InviteConverter
hikari.Colour
-lightbulb.converters.special.ColourConverter
hikari.Color
-lightbulb.converters.special.ColourConverter
hikari.Snowflake
-lightbulb.converters.special.SnowflakeConverter
datetime.datetime
-lightbulb.converters.special.TimestampConverter
hikari.Attachment
- No converter, attachment will be pulled from the message attachments.
Slash command option type mapping:
str
-hikari.OptionType.STRING
int
-hikari.OptionType.INTEGER
float
-hikari.OptionType.FLOAT
bool
-hikari.OptionType.BOOLEAN
hikari.User
-hikari.OptionType.USER
hikari.Member
-hikari.OptionType.USER
hikari.GuildChannel
-hikari.OptionType.CHANNEL
hikari.TextableGuildChannel
-hikari.OptionType.CHANNEL
hikari.TextableChannel
-hikari.OptionType.CHANNEL
hikari.GuildCategory
-hikari.OptionType.CHANNEL
hikari.GuildVoiceChannel
-hikari.OptionType.CHANNEL
hikari.Role
-hikari.OptionType.ROLE
hikari.Emoji
-hikari.OptionType.STRING
hikari.Guild
-hikari.OptionType.STRING
hikari.Message
-hikari.OptionType.STRING
hikari.Invite
-hikari.OptionType.STRING
hikari.Colour
-hikari.OptionType.STRING
hikari.Color
-hikari.OptionType.STRING
hikari.Snowflake
-hikari.OptionType.STRING
datetime.datetime
-hikari.OptionType.STRING
hikari.Attachment
-hikari.OptionType.ATTACHMENT
Note
Slash command options that resolve to type hikari.OptionType.STRING
will also have the appropriate
converter run upon invocation. If this causes the command to take too long to run then you can
pass auto_defer=True
to the lightbulb.command
decorator. The deferral will be processed prior
to the conversion of options.
Adding Checks to Commands#
Checks prevent commands from being invoked if the user invoking the command does not meet the specified criteria. For example, you can prevent commands from being used in DMs, restrict them to only the owner of the bot, or restrict commands to only users that have specific permissions.
See Checks API Reference for all of the checks that are provided by Lightbulb.
To add checks to a command, you need to use the lightbulb.decorators.add_checks
decorator. The decorator takes
an arbitrary number of lightbulb.checks.Check
objects and will add all of them to the command.
For example:
import lightbulb
@lightbulb.add_checks(lightbulb.owner_only)
@lightbulb.command("foo", "test command")
@lightbulb.implements(lightbulb.PrefixCommand)
async def foo(ctx: lightbulb.Context) -> None:
await ctx.respond("You are the owner of this bot.")
You can also create custom checks by creating your own instance of the lightbulb.checks.Check
class and passing
in your custom check function to the constructor. A check function should take a single argument, which will be the Context
instance for the command that is attempting to be invoked. Your check should either raise an error or return False
on failure and must return True
if it passes. Your check may be a syncronous or asyncronous function.
For example:
import lightbulb
# OPTIONAL: Converting the check function into a Check object
@lightbulb.Check
# Defining the custom check function
def check_author_is_me(context: lightbulb.Context) -> bool:
# Returns True if the author's ID is the same as the given one
return context.author.id == 1455657467
# Adding the check to a command
@lightbulb.add_checks(check_author_is_me)
# Or if you do not use the @lightbulb.Check decorator
@lightbulb.add_checks(lightbulb.Check(check_author_is_me))
Adding Commands to the Bot#
To add commands to the bot, you need to use the lightbulb.app.BotApp.command
method, either as a
decorator, or by calling it with the lightbulb.commands.base.CommandLike
object to add to the bot
as a command.
This method instantiates the different command objects for the given CommandLike
object and registers
them to the correct bot attribute.
For example:
import lightbulb
bot = lightbulb.BotApp(...)
@bot.command # valid
@lightbulb.command("foo", "test command")
@lightbulb.implements(lightbulb.PrefixCommand)
async def foo(ctx: lightbulb.Context) -> None:
...
@bot.command() # also valid
@lightbulb.command("bar", "test command")
@lightbulb.implements(lightbulb.PrefixCommand)
async def bar(ctx: lightbulb.Context) -> None:
...
@lightbulb.command("baz", "test command")
@lightbulb.implements(lightbulb.PrefixCommand)
async def baz(ctx: lightbulb.Context) -> None:
...
bot.command(baz) # also valid