Commands

class twitchio.ext.commands.Command

The TwitchIO commands.Command class.

These are usually not created manually, instead see:

property translator: Translator[Any] | None

Property returning the commands.Translator associated with this command or None if one was not used.

property parameters: mappingproxy[str, inspect.Parameter]

Property returning a copy mapping of name to inspect.Parameter pair, which are the parameters of the callback of this command, minus self (if in a class) and ctx.

Can be used to retrieve the name, annotation, and default value of command parameters.

property signature: str | None

Property returning an easily readable POSIX-like argument signature for the command.

Useful when generating or displaying help.

The format is described below:

  • <arg> is a required argument.

  • [arg] is an optional argument.

  • ...arg is a consume-rest argument.

  • arg... is an argument list.

Example

@commands.command()
async def test(ctx: commands.Context, hello: str, world: int) -> None: ...
    ...

print(test.signature)  # <hello> <world>

@commands.command()
async def test(ctx: commands.Context, arg: str, *, other: str | None = None) -> None: ...
    ...

print(test.signature)  # <arg> [...other]


@commands.command()
async def test(ctx: commands.Context, arg: str, other: str | None = None, *args: str | None = None) -> None: ...
    ...

print(test.signature)  # <arg> [other] [args...]
property help: str

Property returning a str which is the docstring associated with the command callback.

If no docstring is present on the callback of the command, an empty string will be returned instead.

New in version 3.1.

property component: Optional[Component_T]

Property returning the Component associated with this command or None if there is not one.

property parent: Optional[Group[Component_T, P]]

Property returning the Group this sub-command belongs to or None if it is not apart of a group.

property name: str

Property returning the name of this command.

property relative_name: str

Property returning the name of this command relative to it’s direct parent, if it has one.

E.g. Closely equivalent to "{parent.name} {name}".

If this command has no parent, this simply returns the name.

property full_parent_name: str

Property returning the fully qualified name for all the parents for this command.

This takes into account the full parent hierarchy. If this command has no parents, this will be an empty str.

E.g Closely equivalent to "{first_parent.name} {second_parent.name}".

property qualified_name: str

Property returning the fully qualified name for this command.

This takes into account the parent hierarchy. If this command has no parent, this simply returns the name.

E.g. Closely equivalent to "{first_parent.name} {second_parent.name} {name}".

This would be the string you would need to send minus the command prefix to invoke this command.

property aliases: list[str]

Property returning a copy of the list of aliases associated with this command, if it has any set.

Could be an empty list if no aliases have been set.

property extras: mappingproxy[Any, Any]

Property returning the extras stored on this command as MappingProxyType.

Extras is a dict that can contain any information, and is stored on the command object for future retrieval.

property has_error: bool

Property returning a bool, indicating whether this command has any local error handlers.

property guards: list[collections.abc.Callable[..., bool] | collections.abc.Callable[..., collections.abc.Coroutine[Any, Any, bool]]]

Property returning a list of command specific guard()’s added.

property callback: Callable[Concatenate[Component_T, Context[Any], P], Coro] | Callable[Concatenate[Context[Any], P], Coro]

Property returning the coroutine callback used in invocation. E.g. the function you wrap with command().

async run_guards(ctx: Context[BotT], *, with_cooldowns: bool = False) None

This function is a coroutine.

Method which allows a Command to run and check all associated Guards, including any cooldowns, with the provided Context.

This is useful if you would like to verify if a chatter is allowed to run a command without invoking the callback. E.g. for displaying help or a list of available commands to a Chatter.

New in version 3.1.

Parameters
  • ctx (Context) – The Context to run the Guards against.

  • with_cooldowns (bool) – An optional bool which indicates whether any associated cooldowns on this command should also be checked. Since running a cooldown will trigger an update in the Cooldown bucket, this is False by default.

Returns

The Guard checks successfully ran.

Return type

None

Raises

GuardFailure – A Guard failed and would have prevented a user from invoking this command.

error(func: Any) Any

This function is a decorator.

A decorator which adds a local error handler to this command.

Similar to event_command_error() except local to this command.

before_invoke(func: Any) Any

This function is a decorator.

A decorator which adds a local before_invoke callback to this command, similar to before_invoke() except local to this command.

The before_invoke hook is called before the command callback, but after parsing arguments and guards are successfully completed. Could be used to setup state for the command for example.

Example

@commands.command()
async def test(ctx: commands.Context) -> None:
    ...

@test.before_invoke
async def test_before(ctx: commands.Context) -> None:
    # Open a database connection for example
    ...

    ctx.connection = connection
    ...

@test.after_invoke
async def test_after(ctx: commands.Context) -> None:
    # Close a database connection for example
    ...

    await ctx.connection.close()
    ...
after_invoke(func: Any) Any

This function is a decorator.

A decorator which adds a local after_invoke callback to this command, similar to after_invoke() except local to this command.

The after_invoke hook is called after the command callback has completed invocation. Could be used to cleanup state after command invocation.

Note

This hook is always called; even when the Command fails to invoke. However, similar to before_invoke() only if parsing arguments and guards are successfully completed.

Example

@commands.command()
async def test(ctx: commands.Context) -> None:
    ...

@test.before_invoke
async def test_before(ctx: commands.Context) -> None:
    # Open a database connection for example
    ...

    ctx.connection = connection
    ...

@test.after_invoke
async def test_after(ctx: commands.Context) -> None:
    # Close a database connection for example
    ...

    await ctx.connection.close()
    ...
Methods
class twitchio.ext.commands.Group

The TwitchIO commands.Command class.

These are usually not created manually, instead see:

command(name: str | None = None, aliases: list[str] | None = None, extras: dict[Any, Any] | None = None, **kwargs: Any) Any

This function is a decorator.

A decorator which adds a Command as a sub-command to this group.

See: command() for more information on commands

Examples

# When added to a Bot or used in a component you can invoke this group and sub-commands with your prefix, E.g:
# !socials
# !socials discord OR !socials twitch
# When invoke_fallback is True, the parent command will be invoked if a sub-command cannot be found...

@commands.group(name="socials", invoke_fallback=True)
async def socials_group(ctx: commands.Context) -> None:
    await ctx.send("https://discord.gg/YP548eEK3a, https://twitch.tv/chillymosh, ...")

@socials_group.command(name="discord", aliases=["disco"])
async def socials_discord(ctx: commands.Context) -> None:
    await ctx.send("https://discord.gg/YP548eEK3a")

@socials_group.command(name="twitch")
async def socials_twitch(ctx: commands.Context) -> None:
    await ctx.send("https://twitch.tv/chillymosh")
Parameters
  • name (str | None) – An optional custom name to use for this sub-command. If this is None or not passed, the coroutine function name will be used instead.

  • aliases (list[str] | None) – An optional list of aliases to use for this command.

  • extras (dict) – A dict of any data which is stored on this command object. Can be used anywhere you have access to the command object, E.g. in a before or after hook.

  • guards_after_parsing (bool) – An optional bool, indicating whether to run guards after argument parsing has completed. Defaults to False, which means guards will be checked before command arguments are parsed and available.

  • cooldowns_before_guards (bool) – An optional bool, indicating whether to run cooldown guards after all other guards succeed. Defaults to False, which means cooldowns will be checked after all guards have successfully completed.

  • bypass_global_guards (bool) – An optional bool, indicating whether the command should bypass the global_guard(). Defaults to False.

group(name: str | None = None, aliases: list[str] | None = None, extras: dict[Any, Any] | None = None, **kwargs: Any) Any

This function is a decorator.

A decorator which adds a Group as a sub-group to this group.

Examples

# When added to a Bot or used in a component you can invoke this group and sub-commands with your prefix, E.g:
# !socials
# !socials discord OR !socials twitch
# !socials discord one OR !socials discord two
# When invoke_fallback is True, the parent command will be invoked if a sub-command cannot be found...

@commands.group(name="socials", invoke_fallback=True)
async def socials_group(ctx: commands.Context) -> None:
    await ctx.send("https://discord.gg/YP548eEK3a, https://twitch.tv/chillymosh, ...")

@socials_group.command(name="twitch")
async def socials_twitch(ctx: commands.Context) -> None:
    await ctx.send("https://twitch.tv/chillymosh")

# Add a group to our parent group which further separates the commands...
@socials_group.group(name="discord", aliases=["disco"], invoke_fallback=True)
async def socials_discord(ctx: commands.Context) -> None:
    await ctx.send("https://discord.gg/YP548eEK3a, https://discord.gg/...")

@socials_discord.command(name="one", aliases=["1"])
async def socials_discord_one(ctx: commands.Context) -> None:
    await ctx.send("https://discord.gg/YP548eEK3a")

@socials_discord.command(name="two", aliases=["2"])
async def socials_discord_two(ctx: commands.Context) -> None:
    await ctx.send("https://discord.gg/...")
Parameters
  • name (str | None) – An optional custom name to use for this group. If this is None or not passed, the coroutine function name will be used instead.

  • aliases (list[str] | None) – An optional list of aliases to use for this group.

  • extras (dict) – A dict of any data which is stored on this command object. Can be used anywhere you have access to the command object, E.g. in a before or after hook.

  • invoke_fallback (bool) – An optional bool which tells the parent to be invoked as a fallback when no sub-command can be found. Defaults to False.

  • apply_cooldowns (bool) – An optional bool indicating whether the cooldowns on this group are checked before invoking any sub commands. Defaults to True.

  • apply_guards (bool) – An optional bool indicating whether the guards on this group should be ran before invoking any sub commands. Defaults to True.

Reward Commands

class twitchio.ext.commands.RewardCommand

Represents the RewardCommand class.

Reward commands are commands invoked from Channel Point Redemptions instead of the usual invocation via messages.

See the reward_command() decorator for more information.

These are usually not created manually, instead see:

property parent: Optional[Group[Component_T, P]]

RewardCommand does not implement Groups or Sub-Commands.

This property always returns None.

property reward_id: str

Property returning the reward id that this command belongs to.

property name: str

RewardCommand do not allow custom names, and such the name of the command is always a uniquely generated string based on the reward_id and invoke_when properties.

property relative_name: str

RewardCommand does not implement Groups or Sub-Commands.

This property always returns name

property full_parent_name: str

RewardCommand does not implement Groups or Sub-Commands.

This property always returns name

property qualified_name: str

RewardCommand does not implement Groups or Sub-Commands.

This property always returns name

property aliases: list[str]

RewardCommand do not allow aliases.

This property always returns an empty list.

property invoke_when: RewardStatus

Property returning the RewardStatus this command will invoke under.

after_invoke(func: Any) Any

This function is a decorator.

A decorator which adds a local after_invoke callback to this command, similar to after_invoke() except local to this command.

The after_invoke hook is called after the command callback has completed invocation. Could be used to cleanup state after command invocation.

Note

This hook is always called; even when the Command fails to invoke. However, similar to before_invoke() only if parsing arguments and guards are successfully completed.

Example

@commands.command()
async def test(ctx: commands.Context) -> None:
    ...

@test.before_invoke
async def test_before(ctx: commands.Context) -> None:
    # Open a database connection for example
    ...

    ctx.connection = connection
    ...

@test.after_invoke
async def test_after(ctx: commands.Context) -> None:
    # Close a database connection for example
    ...

    await ctx.connection.close()
    ...
before_invoke(func: Any) Any

This function is a decorator.

A decorator which adds a local before_invoke callback to this command, similar to before_invoke() except local to this command.

The before_invoke hook is called before the command callback, but after parsing arguments and guards are successfully completed. Could be used to setup state for the command for example.

Example

@commands.command()
async def test(ctx: commands.Context) -> None:
    ...

@test.before_invoke
async def test_before(ctx: commands.Context) -> None:
    # Open a database connection for example
    ...

    ctx.connection = connection
    ...

@test.after_invoke
async def test_after(ctx: commands.Context) -> None:
    # Close a database connection for example
    ...

    await ctx.connection.close()
    ...
property callback: Callable[Concatenate[Component_T, Context[Any], P], Coro] | Callable[Concatenate[Context[Any], P], Coro]

Property returning the coroutine callback used in invocation. E.g. the function you wrap with command().

property component: Optional[Component_T]

Property returning the Component associated with this command or None if there is not one.

error(func: Any) Any

This function is a decorator.

A decorator which adds a local error handler to this command.

Similar to event_command_error() except local to this command.

property extras: mappingproxy[Any, Any]

Property returning the extras stored on this command as MappingProxyType.

Extras is a dict that can contain any information, and is stored on the command object for future retrieval.

property guards: list[collections.abc.Callable[..., bool] | collections.abc.Callable[..., collections.abc.Coroutine[Any, Any, bool]]]

Property returning a list of command specific guard()’s added.

property has_error: bool

Property returning a bool, indicating whether this command has any local error handlers.

property help: str

Property returning a str which is the docstring associated with the command callback.

If no docstring is present on the callback of the command, an empty string will be returned instead.

New in version 3.1.

property parameters: mappingproxy[str, inspect.Parameter]

Property returning a copy mapping of name to inspect.Parameter pair, which are the parameters of the callback of this command, minus self (if in a class) and ctx.

Can be used to retrieve the name, annotation, and default value of command parameters.

async run_guards(ctx: Context[BotT], *, with_cooldowns: bool = False) None

This function is a coroutine.

Method which allows a Command to run and check all associated Guards, including any cooldowns, with the provided Context.

This is useful if you would like to verify if a chatter is allowed to run a command without invoking the callback. E.g. for displaying help or a list of available commands to a Chatter.

New in version 3.1.

Parameters
  • ctx (Context) – The Context to run the Guards against.

  • with_cooldowns (bool) – An optional bool which indicates whether any associated cooldowns on this command should also be checked. Since running a cooldown will trigger an update in the Cooldown bucket, this is False by default.

Returns

The Guard checks successfully ran.

Return type

None

Raises

GuardFailure – A Guard failed and would have prevented a user from invoking this command.

property signature: str | None

Property returning an easily readable POSIX-like argument signature for the command.

Useful when generating or displaying help.

The format is described below:

  • <arg> is a required argument.

  • [arg] is an optional argument.

  • ...arg is a consume-rest argument.

  • arg... is an argument list.

Example

@commands.command()
async def test(ctx: commands.Context, hello: str, world: int) -> None: ...
    ...

print(test.signature)  # <hello> <world>

@commands.command()
async def test(ctx: commands.Context, arg: str, *, other: str | None = None) -> None: ...
    ...

print(test.signature)  # <arg> [...other]


@commands.command()
async def test(ctx: commands.Context, arg: str, other: str | None = None, *args: str | None = None) -> None: ...
    ...

print(test.signature)  # <arg> [other] [args...]
property translator: Translator[Any] | None

Property returning the commands.Translator associated with this command or None if one was not used.

class twitchio.ext.commands.RewardStatus

Enum provided to reward_command() representing when the RewardCommand should be invoked.

unfulfilled

Used to invoke a RewardCommand when the redemption is set to "unfulfilled". An unfulfilled redemption is one still waiting to be approved or denied in the redemption queue.

Type

Literal[“unfulfilled”]

fulfilled

Used to invoke a RewardCommand when the redemption is set to "fulfilled". A fulfilled redemption is one that has been approved, either from the redemption queue, automatically or via a bot.

Type

Literal[“fulfilled”]

canceled

Used to invoke a RewardCommand when the redemption is set to "canceled". A canceled redemption is one that has been denied, either from the redemption queue, or via a bot.

Type

Literal[“canceled”]

all

Used to invoke a RewardCommand on any status.

Type

Literal[“all”]

Context

class twitchio.ext.commands.Context(payload: twitchio.models.eventsub_.ChatMessage | twitchio.models.eventsub_.ChannelPointsRedemptionAdd | twitchio.models.eventsub_.ChannelPointsRedemptionUpdate, *, bot: BotT)

The Context class constructed when a message or reward redemption in the respective events is received and processed in a Bot.

This object is available in all Command’s, RewardCommand’s, Group’s and associated sub-commands and all command related events. It is also included in various areas relating to command invocation, including, guard()’s and before and after hooks.

The Context class is a useful tool which provides information surrounding the command invocation, the broadcaster and chatter involved and provides many useful methods and properties for ease of us.

Usually you wouldn’t construct this class this yourself, however it could be subclassed and used with get_context() to implement custom functionality.

Parameters
property message: twitchio.models.eventsub_.ChatMessage | None

Property returning the ChatMessage that this Context was created from. This could be None if type is REWARD.

property redemption: twitchio.models.eventsub_.ChannelPointsRedemptionAdd | twitchio.models.eventsub_.ChannelPointsRedemptionUpdate | None

Property returning the ChannelPointsRedemptionAdd or ChannelPointsRedemptionUpdate that this Context was created from. This could be None if type is MESSAGE.

property payload: twitchio.models.eventsub_.ChatMessage | twitchio.models.eventsub_.ChannelPointsRedemptionAdd | twitchio.models.eventsub_.ChannelPointsRedemptionUpdate

Property returning the ChatMessage or either ChannelPointsRedemptionAdd or ChannelPointsRedemptionUpdate associated with this Context.

Unlike message and redemption this will always return a value.

property component: Component | None

Property returning the Component that this context was used in, if the Command belongs to it. This is only set once a Command has been found and invoked.

property command: Command[Any, ...] | RewardCommand[Any, ...] | None

Property returning the Command or RewardCommand associated with this context, if found.

This is only set when a command begins invocation. Could be None if the command has not started invocation, or one was not found.

property invoked_subcommand: Command[Any, ...] | None

Property returning the subcommand associated with this context if their is one.

Returns None when a standard command without a parent Group is invoked.

property invoked_with: str | None

Property returning the string the context used to attempt to find a valid Command.

If type is REWARD this will return the ID of the reward.

Could be None if a command has not been invoked from this context yet.

property chatter: Chatter | PartialUser

Property returning a Chatter if type is MESSAGE; E.g. when invoked from a ChatMessage.

When type is REWARD, this will return a twitchio.PartialUser, which is the user who redeemed the reward.

property author: Chatter | PartialUser

Property returning a Chatter if type is MESSAGE; E.g. when invoked from a ChatMessage.

When type is REWARD, this will return a twitchio.PartialUser, which is the user who redeemed the reward.

property broadcaster: PartialUser

Property returning the twitchio.PartialUser who is the broadcaster of the channel associated with this context.

property source_broadcaster: PartialUser | None

Property returning the twitchio.PartialUser who is the broadcaster of the channel associated with the original ChatMessage.

This will usually always be None as the default behaviour is to ignore shared messages when invoking commands.

This will always be None when type is REWARD.

property channel: PartialUser

An alias to broadcaster.

property bot: BotT

Property returning the Bot object.

property prefix: str | None

Property returning the prefix associated with this context or None.

This will only return a prefix after the context has been prepared, which occurs during invocation of a command, and after a valid prefix found.

This will always be None when type is REWARD.

property content: str

Property returning the raw content of the message associated with this context.

If type is REWARD, this will be the user_input of the reward, if provided by the user.

property type: ContextType

Property returning the commands.ContextType associated with this commands.Context.

This will be MESSAGE when the context is invoked from a ChatMessage.

Otherwise when invoked from a Channel Points Redemption this will be REWARD.

property translator: Translator[Any] | None

Property returning the commands.Translator assigned to the commands.Command if found or None. This property will always return None if no valid command or prefix is associated with this Context.

property args: list[Any]

A list of arguments processed and passed to the Command callback.

This is only set after the command begins invocation.

property kwargs: dict[str, Any]

A dict of keyword-arguments processed and passed to the Command callback.

This is only set after the command begins invocation.

property failed: bool

Property indicating whether the context failed to invoke the associated command.

is_owner() bool

Method which returns whether the chatter associated with this context is the owner of the bot.

Warning

You must have set the owner_id correctly first, otherwise this method will return False.

Returns

Whether the chatter that this context is associated with is the owner of this bot.

Return type

bool

is_valid() bool

Method which indicates whether this context is valid. E.g. has a valid command prefix.

If type is REWARD this will return True if a valid command is found.

async fetch_command() Command[Any, ...] | RewardCommand[Any, ...] | None

This function is a coroutine.

Method which validates the prefix and finds and returns the command that would be invoked or None if no valid command can be found.

If no valid prefix is found this method will always return None.

Note

Unlike prepare() this method resets the state of the internal string-view used to find the prefix, command and arguments and can be safely used at anytime.

New in version 3.1.

Returns

The twitchio.ext.commands.Command or twitchio.ext.commands.RewardCommand if found alongside a valid prefix, otherwise None.

Return type

twitchio.ext.commands.Command | twitchio.ext.commands.RewardCommand | None

async prepare() None

This function is a coroutine.

Method called before invocation, used to retrieve a valid prefix and valid command.

This coroutine is called automatically in invoke() before anything else.

Could be overriden to add extra setup before command invocation.

Note

If this method is overriden you should call await super().prepare() to ensure correct setup of the context.

async invoke() bool | None

This function is a coroutine.

Invoke and process the command associated with this message or redemption context if it is valid.

This method first prepares the context for invocation, and checks whether the context has a valid command with a valid prefix.

Warning

Usually you wouldn’t use this method yourself, as it handled by TwitchIO interanally when process_commands() is called in various events.

Important

Due to the way this method works, the only error raised will be CommandNotFound. All other errors that occur will be sent to the twitchio.event_command_error() event.

Returns

  • bool – If this method explicitly returns False the context is not valid. E.g. has no valid command prefix. When True the command successfully completed invocation without error.

  • None – Returned when the command is found and begins to process. This does not indicate the command was completed successfully. See also twitchio.event_command_completed() for an event fired when a command successfully completes the invocation process.

Raises

CommandNotFound – The Command trying to be invoked could not be found.

async send(content: str, *, me: bool = False) SentMessage

This function is a coroutine.

Send a chat message to the channel associated with this context.

Important

You must have the user:write:chat scope. If an app access token is used, then additionally requires the user:bot scope on the bot, and either channel:bot scope from the broadcaster or moderator status.

Parameters
  • content (str) – The content of the message you would like to send. This cannot exceed 500 characters. Additionally the content parameter will be stripped of all leading and trailing whitespace.

  • me (bool) – An optional bool indicating whether you would like to send this message with the /me chat command.

Returns

The payload received by Twitch after sending this message.

Return type

SentMessage

Raises
  • HTTPException – Twitch failed to process the message, could be 400, 401, 403, 422 or any 5xx status code.

  • MessageRejectedError – Twitch rejected the message from various checks.

async send_translated(content: str, *, me: bool = False, langcode: str | None = None) SentMessage

This function is a coroutine.

Send a translated chat message to the channel associated with this context.

You must have added a commands.Translator to your commands.Command in order to effectively use this method. If no commands.Translator is found, this method acts identical to send().

If this method can not find a valid language code, E.g. both commands.Translator.get_langcode() and the parameter langcode return None, this method acts identical to send().

See the following documentation for more details on translators:

Important

You must have the user:write:chat scope. If an app access token is used, then additionally requires the user:bot scope on the bot, and either channel:bot scope from the broadcaster or moderator status.

Parameters
  • content (str) – The content of the message you would like to translate and then send. This and the translated version of this content cannot exceed 500 characters. Additionally the content parameter will be stripped of all leading and trailing whitespace.

  • me (bool) – An optional bool indicating whether you would like to send this message with the /me chat command.

  • langcode (str | None) – An optional langcode to override the langcode returned from commands.Translator.get_langcode(). This should only be provided if you do custom language code lookups outside of your commands.Translator. Defaults to None.

Returns

The payload received by Twitch after sending this message.

Return type

SentMessage

Raises
  • HTTPException – Twitch failed to process the message, could be 400, 401, 403, 422 or any 5xx status code.

  • MessageRejectedError – Twitch rejected the message from various checks.

  • TranslatorError – An error occurred during translation.

async reply(content: str, *, me: bool = False) SentMessage

This function is a coroutine.

Send a chat message as a reply to the user who this message is associated with and to the channel associated with this context.

Warning

You cannot use this method in Reward based context. E.g. if type is REWARD.

Important

You must have the user:write:chat scope. If an app access token is used, then additionally requires the user:bot scope on the bot, and either channel:bot scope from the broadcaster or moderator status.

Parameters
  • content (str) – The content of the message you would like to send. This cannot exceed 500 characters. Additionally the content parameter will be stripped of all leading and trailing whitespace.

  • me (bool) – An optional bool indicating whether you would like to send this message with the /me chat command.

Returns

The payload received by Twitch after sending this message.

Return type

SentMessage

Raises
  • HTTPException – Twitch failed to process the message, could be 400, 401, 403, 422 or any 5xx status code.

  • MessageRejectedError – Twitch rejected the message from various checks.

  • TypeError – Cannot reply in a Reward based Context.

async reply_translated(content: str, *, me: bool = False, langcode: str | None = None) SentMessage

This function is a coroutine.

Send a translated chat message as a reply to the user who this message is associated with and to the channel associated with this context.

You must have added a commands.Translator to your commands.Command in order to effectively use this method. If no commands.Translator is found, this method acts identical to reply().

If this method can not find a valid language code, E.g. both commands.Translator.get_langcode() and the parameter langcode return None, this method acts identical to reply().

See the following documentation for more details on translators:

Warning

You cannot use this method in Reward based context. E.g. if type is REWARD.

Important

You must have the user:write:chat scope. If an app access token is used, then additionally requires the user:bot scope on the bot, and either channel:bot scope from the broadcaster or moderator status.

Parameters
  • content (str) – The content of the message you would like to translate and then send. This and the translated version of this content cannot exceed 500 characters. Additionally the content parameter will be stripped of all leading and trailing whitespace.

  • me (bool) – An optional bool indicating whether you would like to send this message with the /me chat command.

  • langcode (str | None) – An optional langcode to override the langcode returned from commands.Translator.get_langcode(). This should only be provided if you do custom language code lookups outside of your commands.Translator. Defaults to None.

Returns

The payload received by Twitch after sending this message.

Return type

SentMessage

Raises
  • HTTPException – Twitch failed to process the message, could be 400, 401, 403, 422 or any 5xx status code.

  • MessageRejectedError – Twitch rejected the message from various checks.

  • TranslatorError – An error occurred during translation.

async send_announcement(content: str, *, color: Optional[Literal['blue', 'green', 'orange', 'purple', 'primary']] = None) None

This function is a coroutine.

Send an announcement to the channel associated with this channel as the bot.

Important

The broadcaster of the associated channel must have granted your bot the moderator:manage:announcements scope.

Parameters
  • content (str) – The content of the announcement to send. This cannot exceed 500 characters. Announcements longer than 500 characters will be truncated instead by Twitch.

  • color (Literal["blue", "green", "orange", "purple", "primary"] | None) – An optional colour to use for the announcement. If set to "primary” or None the channels accent colour will be used instead. Defaults to None.

Return type

None

Raises

HTTPException – Sending the announcement failed. Could be 400, 401 or any 5xx status code.

async delete_message() None

This function is a coroutine.

Delete the message associated with this context.

Warning

You cannot use this method in Reward based context. E.g. if type is REWARD.

Important

The broadcaster of the associated channel must have granted your bot the moderator:manage:chat_messages scope.

Note

You cannot delete messages from the broadcaster or any moderator, and the message must not be more than 6 hours old.

Raises
  • HTTPException – Twitch failed to remove the message. Could be 400, 401, 403, 404 or any 5xx status code.

  • TypeError – Cannot delete the message of a Reward based Context.

async clear_messages() None

This function is a coroutine.

Clear all the chat messages from chat for the channel associated with this context.

Important

The broadcaster of the associated channel must have granted your bot the moderator:manage:chat_messages scope.

Raises

HTTPException – Twitch failed to remove the message. Could be 400, 401, 403, 404 or any 5xx status code.

Attributes
class twitchio.ext.commands.ContextType

Enum representing the type of type of a Context object.

The type represents how the Context was constructed and how it will behave.

MESSAGE

When type is MESSAGE, the Context was constructed with a ChatMessage. This Context only works with Command’s and has the broader functionality.

REWARD

When type is REWARD, the Context was constructed with a ChannelPointsRedemptionAdd. This Context only works with RewardCommand’s and has limited functionality in comparison to MESSAGE.

Notable limitations include not having access to a Chatter and some guard()’s will not be available.

Decorators

twitchio.ext.commands.command(name: str | None = None, aliases: list[str] | None = None, extras: dict[Any, Any] | None = None, **kwargs: Any) Any

This function is a decorator.

A decorator which turns a coroutine into a Command which can be used in Component’s or added to a Bot.

Commands are powerful tools which enable bots to process messages and convert the content into mangeable arguments and Context which is parsed to the wrapped callback coroutine.

Commands also benefit to such things as guard()’s and the before and after hooks on both, Component and Bot.

Command callbacks should take in at minimum one parameter, which is Context and is always passed.

Parameters
  • name (str | None) – An optional custom name to use for this command. If this is None or not passed, the coroutine function name will be used instead.

  • aliases (list[str] | None) – An optional list of aliases to use for this command.

  • extras (dict) – A dict of any data which is stored on this command object. Can be used anywhere you have access to the command object, E.g. in a before or after hook.

  • guards_after_parsing (bool) – An optional bool, indicating whether to run guards after argument parsing has completed. Defaults to False, which means guards will be checked before command arguments are parsed and available.

  • cooldowns_before_guards (bool) – An optional bool, indicating whether to run cooldown guards after all other guards succeed. Defaults to False, which means cooldowns will be checked after all guards have successfully completed.

  • bypass_global_guards (bool) – An optional bool, indicating whether the command should bypass the Bot.global_guard(). Defaults to False.

Examples

# When added to a Bot or used in a component you can invoke this command with your prefix, E.g:
# !hi or !howdy

@commands.command(name="hi", aliases=["hello", "howdy"])
async def hi_command(ctx: commands.Context) -> None:
    ...
Raises
  • ValueError – The callback being wrapped is already a command.

  • TypeError – The callback must be a coroutine function.

twitchio.ext.commands.group(name: str | None = None, aliases: list[str] | None = None, extras: dict[Any, Any] | None = None, **kwargs: Any) Any

This function is a decorator.

A decorator which turns a coroutine into a Group which can be used in Component’s or added to a Bot.

Group commands act as parents to other commands (sub-commands).

See: command() for more information on commands.

Group commands are a powerful way of grouping similar sub-commands into a more user friendly interface.

Group callbacks should take in at minimum one parameter, which is Context and is always passed.

Parameters
  • name (str | None) – An optional custom name to use for this group. If this is None or not passed, the coroutine function name will be used instead.

  • aliases (list[str] | None) – An optional list of aliases to use for this group.

  • extras (dict) – A dict of any data which is stored on this command object. Can be used anywhere you have access to the command object, E.g. in a before or after hook.

  • invoke_fallback (bool) – An optional bool which tells the parent to be invoked as a fallback when no sub-command can be found. Defaults to False.

  • apply_cooldowns (bool) – An optional bool indicating whether the cooldowns on this group are checked before invoking any sub commands. Defaults to True.

  • apply_guards (bool) – An optional bool indicating whether the guards on this group should be ran before invoking any sub commands. Defaults to True.

Examples

# When added to a Bot or used in a component you can invoke this group and sub-commands with your prefix, E.g:
# !socials
# !socials discord OR !socials twitch
# When invoke_fallback is True, the parent command will be invoked if a sub-command cannot be found...

@commands.group(name="socials", invoke_fallback=True)
async def socials_group(ctx: commands.Context) -> None:
    await ctx.send("https://discord.gg/YP548eEK3a, https://twitch.tv/chillymosh, ...")

@socials_group.command(name="discord", aliases=["disco"])
async def socials_discord(ctx: commands.Context) -> None:
    await ctx.send("https://discord.gg/YP548eEK3a")

@socials_group.command(name="twitch")
async def socials_twitch(ctx: commands.Context) -> None:
    await ctx.send("https://twitch.tv/chillymosh")
Raises
  • ValueError – The callback being wrapped is already a command or group.

  • TypeError – The callback must be a coroutine function.

twitchio.ext.commands.reward_command(id: str, invoke_when: RewardStatus = RewardStatus.fulfilled, extras: dict[Any, Any] | None = None, **kwargs: Any) Any

This function is a decorator.

A decorator which turns a coroutine into a RewardCommand which can be used in Component’s or added to a Bot.

Reward commands are powerful tools which enable bots to process channel point redemptions and convert them into mangeable arguments and Context which are parsed and sent to the wrapped callback coroutine.

Similar to standard commands, reward commands benefit from guard()’s and the before and after hooks on both, Component and Bot. However some functionality may be limited or missing due to Twitch limitations on the data provided around the user.

A best effort has been made to document features that will be limited by Reward Commands; usually with a warning, however you should take into consideration that you will not receive a full Chatter object when using a RewardCommand.

Reward command callbacks should take in at minimum one parameter, which is Context and is always passed.

By default, Reward Commands are only invoked when a channel point redemption is set to "fulfilled". This behaviour can be changed by providing the invoke_when parameter.

RewardCommand’s use the Reward id and invoke_when parameters to generate a unique name. This means that you can only have one RewardCommand per id and invoke_when pair. If all is used this command will act as a catch all, rendering other commands with the same id unusable.

To be able to use RewardCommand’s you must subscribe to the relevant events:

Parameters
  • id (str) – The ID of the reward you wish to invoke this command for. This is always required.

  • invoke_when (RewardStatus) – Indicates under which redemption status this command should invoke. Defaults to fulfilled

  • extras (dict) – A dict of any data which is stored on this command object. Can be used anywhere you have access to the command object, E.g. in a before or after hook.

  • guards_after_parsing (bool) – An optional bool, indicating whether to run guards after argument parsing has completed. Defaults to False, which means guards will be checked before command arguments are parsed and available.

  • cooldowns_before_guards (bool) – An optional bool, indicating whether to run cooldown guards after all other guards succeed. Defaults to False, which means cooldowns will be checked after all guards have successfully completed.

  • bypass_global_guards (bool) – An optional bool, indicating whether the command should bypass the Bot.global_guard(). Defaults to False.

Examples

@commands.reward_command(id="29fde826-1bd6-4cb3-82f1-bb990ea9f04c", invoke_when=commands.RewardStatus.fulfilled)
async def reward_test(self, ctx: commands.Context, *, user_input: str) -> None:
    assert ctx.redemption
    await ctx.send(f"{ctx.author} redeemed {ctx.redemption.reward.title} and said {user_input}")
twitchio.ext.commands.cooldown(*, base: BaseCooldown, rate: int, per: float, key: Callable[[Any], Hashable] | Callable[[Any], Coroutine[Any, Any, Hashable]] | BucketType, **kwargs: Any)

This function is a decorator.

A decorator which adds a Cooldown to a Command.

The parameters of this decorator may change depending on the class passed to the base parameter. The parameters needed for the default built-in classes are listed instead.

When a command is on cooldown or ratelimited, the CommandOnCooldown exception is raised and propagated to all error handlers.

Parameters
  • base (BaseCooldown) –

    Optional base class to use to construct the cooldown. By default this is the Cooldown class, which implements a Token Bucket Algorithm. Another option is the GCRACooldown class which implements the Generic Cell Rate Algorithm, which can be thought of as similar to a continuous state leaky-bucket algorithm, but instead of updating internal state, calculates a Theoretical Arrival Time (TAT), making it more performant, and dissallowing short bursts of requests. However before choosing a class, consider reading more information on the differences between the Token Bucket and GCRA.

    A custom class which inherits from BaseCooldown could also be used. All keyword-arguments passed to this decorator, minus base and key will also be passed to the constructor of the cooldown base class.

    Useful if you would like to implement your own ratelimiting algorithm.

  • key (Callable[[Any], Hashable] | Callable[[Any], Coroutine[Any, Any, Hashable]] | BucketType) –

    A regular or coroutine function, or BucketType which must return a typing.Hashable used to determine the keys for the cooldown.

    The BucketType implements some default strategies. If your function returns None the cooldown will be bypassed. See below for some examples. By default the key is chatter.

  • rate (int) – An int indicating how many times a command should be allowed per x amount of time. Note the relevance and effects of both rate and per change slightly between algorithms.

  • per (float | datetime.timedelta) –

    A float or datetime.timedelta indicating the length of the time (as seconds) a cooldown window is open.

    E.g. if rate is 2 and per is 60.0, using the default Cooldown class, you will only be able to send two commands per 60 seconds, with the window starting when you send the first command.

Examples

Using the default Cooldown to allow the command to be ran twice by an individual chatter, every 10 seconds.

@commands.command()
@commands.cooldown(rate=2, per=10, key=commands.BucketType.chatter)
async def hello(ctx: commands.Context) -> None:
    ...

Using a custom key to bypass cooldowns for certain users.

def bypass_cool(ctx: commands.Context) -> typing.Hashable | None:
    # Returning None will bypass the cooldown

    if ctx.chatter.name.startswith("cool"):
        return None

    # For everyone else, return and call the default chatter strategy
    # This strategy returns a tuple of (channel/broadcaster.id, chatter.id) to use as the unique key
    return commands.BucketType.chatter(ctx)

@commands.command()
@commands.cooldown(rate=2, per=10, key=bypass_cool)
async def hello(ctx: commands.Context) -> None:
    ...

Using a custom function to implement dynamic keys.

async def custom_key(ctx: commands.Context) -> typing.Hashable | None:
    # As an example, get some user info from a database with the chatter...
    # This is just to showcase a use for an async version of a custom key...
    ...

    # Example column in database...
    if row["should_bypass_cooldown"]:
        return None

    # Note: Returing chatter.id is equivalent to commands.BucketType.user NOT commands.BucketType.chatter
    # which uses the channel ID and User ID together as the key...
    return ctx.chatter.id

@commands.command()
@commands.cooldown(rate=1, per=300, key=custom_key)
async def hello(ctx: commands.Context) -> None:
    ...
twitchio.ext.commands.translator(cls: Translator[Any] | type[Translator[Any]]) Any

This function is a decorator.

Decorator which adds a commands.Translator to a commands.Command.

You can provide the class or instance of your implemented commands.Translator to this decorator.

See the commands.Translator documentation for more information on translators.

Note

You can only have one commands.Translator per command.

Guards

twitchio.ext.commands.guard(predicate: Callable[..., bool] | Callable[..., Coroutine[Any, Any, bool]])

A function which takes in a predicate as a either a standard function or coroutine function which should return either True or False, and adds it to your Command as a guard.

The predicate function should take in one parameter, commands.Context, the context used in command invocation.

If the predicate function returns False, the chatter will not be able to invoke the command and an error will be raised. If the predicate function returns True the chatter will be able to invoke the command, assuming all the other guards also pass their predicate checks.

Guards can also raise custom exceptions, however your exception should inherit from GuardFailure which will allow your exception to propagate successfully to error handlers.

Any number of guards can be used on a Command and all must pass for the command to be successfully invoked.

All guards are executed in the specific order displayed below:

Note

Guards are checked and ran after all command arguments have been parsed and converted, but before any before_invoke hooks are ran.

It is easy to create simple decorator guards for your commands, see the examples below.

Some built-in helper guards have been premade, and are listed below:

Example

def is_cool():
    def predicate(ctx: commands.Context) -> bool:
        return ctx.chatter.name.startswith("cool")

    return commands.guard(predicate)

@is_cool()
@commands.command()
async def cool(self, ctx: commands.Context) -> None:
    await ctx.reply("You are cool...!")
Raises

GuardFailure – The guard predicate returned False and prevented the chatter from using the command.

twitchio.ext.commands.is_owner() Any

This function is a decorator.

A decorator which adds a guard() to a Command.

This guards adds a predicate which prevents any chatter from using a command who does is not the owner of this bot. You can set the owner of the bot via owner_id.

Raises

GuardFailure – The guard predicate returned False and prevented the chatter from using the command.

twitchio.ext.commands.is_staff() Any

This function is a decorator.

A decorator which adds a guard() to a Command.

This guards adds a predicate which prevents any chatter from using a command who does not possess the Twitch Staff badge.

Warning

Due to Twitch limitations, you cannot use this Guard on a commands.RewardCommand. If you do, it will always fail.

Raises

GuardFailure – The guard predicate returned False and prevented the chatter from using the command.

twitchio.ext.commands.is_broadcaster() Any

This function is a decorator.

A decorator which adds a guard() to a Command.

This guards adds a predicate which prevents any chatter from using a command who does not possess the Broadcaster badge.

See also, is_elevated() for a guard to allow the broadcaster, any moderator or VIP chatter to use the command.

Raises

GuardFailure – The guard predicate returned False and prevented the chatter from using the command.

twitchio.ext.commands.is_lead_moderator() Any

This function is a decorator.

A decorator which adds a guard() to a Command.

This guards adds a predicate which prevents any chatter from using a command who does not possess the Lead Moderator badge.

See also, is_elevated() for a guard to allow the broadcaster, any moderator or VIP chatter to use the command.

Warning

Due to Twitch limitations, you cannot use this Guard on a commands.RewardCommand. If you do, it will always fail.

Raises

GuardFailure – The guard predicate returned False and prevented the chatter from using the command.

twitchio.ext.commands.is_moderator() Any

This function is a decorator.

A decorator which adds a guard() to a Command.

This guards adds a predicate which prevents any chatter from using a command who does not possess the Moderator badge.

See also, is_elevated() for a guard to allow the broadcaster, any moderator or VIP chatter to use the command.

Warning

Due to Twitch limitations, you cannot use this Guard on a commands.RewardCommand. If you do, it will always fail.

Raises

GuardFailure – The guard predicate returned False and prevented the chatter from using the command.

twitchio.ext.commands.is_vip() Any

This function is a decorator.

A decorator which adds a guard() to a Command.

This guards adds a predicate which prevents any chatter from using a command who does not possess the VIP badge.

Note

Due to a Twitch limitation, moderators and broadcasters can not be VIPs, another guard has been made to help aid in allowing these members to also be seen as VIP, see: is_elevated().

Warning

Due to Twitch limitations, you cannot use this Guard on a commands.RewardCommand. If you do, it will always fail.

Raises

GuardFailure – The guard predicate returned False and prevented the chatter from using the command.

twitchio.ext.commands.is_elevated() Any

This function is a decorator.

A decorator which adds a guard() to a Command.

This guards adds a predicate which prevents any chatter from using a command who does not posses one or more of the folowing badges: broadcaster, moderator or VIP.

Important

The chatter only needs 1 of the badges to pass the guard.

Warning

Due to Twitch limitations, you cannot use this Guard on a commands.RewardCommand. If you do, it will always fail.

Example

# This command can be run by anyone with broadcaster, moderator OR VIP status...

@commands.is_elevated()
@commands.command()
async def test(self, ctx: commands.Context) -> None:
    await ctx.reply("You are allowed to use this command!")
Raises

GuardFailure – The guard predicate returned False and prevented the chatter from using the command.

Cooldowns

class twitchio.ext.commands.BaseCooldown

Base class used to implement your own cooldown algorithm for use with cooldown().

Some built-in cooldown algorithms already exist:

Note

Every base method must be implemented in this base class.

abstract reset() None

Base method which should be implemented to reset the cooldown.

abstract update(*args: Any, **kwargs: Any) float | None

Base method which should be implemented to update the cooldown/ratelimit.

This is where your algorithm logic should be contained.

Important

This method should always return a float or None. If None is returned by this method, the cooldown will be considered bypassed.

Returns

  • float – The time needed to wait before you are off cooldown.

  • None – Bypasses the cooldown.

abstract copy() Self

Base method which should be implemented to return a copy of this class in it’s original state.

abstract is_ratelimited(*args: Any, **kwargs: Any) bool

Base method which should be implemented which returns a bool indicating whether the cooldown is ratelimited.

Returns

A bool indicating whether this cooldown is currently ratelimited.

Return type

bool

abstract is_dead(*args: Any, **kwargs: Any) bool

Base method which should be implemented to indicate whether the cooldown should be considered stale and allowed to be removed from the bucket: cooldown mapping.

Returns

A bool indicating whether this cooldown is stale/old.

Return type

bool

class twitchio.ext.commands.Cooldown(*, rate: int, per: float | datetime.timedelta)

Default cooldown algorithm for cooldown(), which implements a Token Bucket Algorithm.

See: cooldown() for more documentation.

class twitchio.ext.commands.GCRACooldown(*, rate: int, per: float | datetime.timedelta)

GCRA cooldown algorithm for cooldown(), which implements the GCRA ratelimiting algorithm.

See: cooldown() for more documentation.

class twitchio.ext.commands.BucketType

Enum representing default implementations for the key argument in cooldown().

default

The cooldown will be considered a global cooldown shared across every channel and user.

user

The cooldown will apply per user, accross all channels.

channel

The cooldown will apply to every user/chatter in the channel.

chatter

The cooldown will apply per user, per channel.

Converters

class twitchio.ext.commands.Converter

Base class used to create custom argument converters in Command’s.

To create a custom converter and do conversion logic on an argument you must override the convert() method. convert() must be a coroutine.

Examples

class LowerCaseConverter(commands.Converter[str]):

    async def convert(self, ctx: commands.Context, arg: str) -> str:
        return arg.lower()

@commands.command()
async def test(ctx: commands.Context, arg: LowerCaseConverter) -> None: ...

New in version 3.1.

async convert(ctx: Context[Any], arg: str) T_co

This function is a coroutine.

Method used on converters to implement conversion logic.

Parameters
  • ctx (Context) – The context provided to the converter after command invocation has started.

  • arg (str) – The argument received in raw form as a str and passed to the converter to do conversion logic on.

class twitchio.ext.commands.UserConverter

The converter used to convert command arguments to a twitchio.User.

This is a default converter which can be used in commands by annotating arguments with the twitchio.User type.

Note

This converter uses an API call to attempt to fetch a valid twitchio.User.

Example

@commands.command()
async def test(ctx: commands.Context, *, user: twitchio.User) -> None: ...
async convert(ctx: Context[Any], arg: str) User

This function is a coroutine.

Method used on converters to implement conversion logic.

Parameters
  • ctx (Context) – The context provided to the converter after command invocation has started.

  • arg (str) – The argument received in raw form as a str and passed to the converter to do conversion logic on.

class twitchio.ext.commands.ColourConverter

The converter used to convert command arguments to a Colour object.

This is a default converter which can be used in commands by annotating arguments with the twitchio.utils.Colour type.

This converter, attempts to convert hex and int type values only in the following formats:

  • “#FFDD00”

  • “FFDD00”

  • “0xFFDD00”

  • 16768256

hex values are attempted first, followed by int.

Note

There is an alias to this converter named ColorConverter.

Example

@commands.command()
async def test(ctx: commands.Context, *, colour: twitchio.utils.Colour) -> None: ...

New in version 3.1.

async convert(ctx: Context[Any], arg: str) Colour

This function is a coroutine.

Method used on converters to implement conversion logic.

Parameters
  • ctx (Context) – The context provided to the converter after command invocation has started.

  • arg (str) – The argument received in raw form as a str and passed to the converter to do conversion logic on.

Translators

class twitchio.ext.commands.Translator

Abstract Base Class for command translators.

This class allows you to implement logic to translate messages sent via the commands.Context.send_translated() method in commands or anywhere commands.Context is available.

You should pass your implemented class to the commands.translator() decorator on top of a Command.

Important

You must implement every method of this ABC.

abstract get_langcode(ctx: Context[Any], name: str) T | None

Method which is called when commands.Context.send_translated() is used on a commands.Command which has an associated Translator, to determine the langcode which should be passed to translate() or None if the content should not be translated.

By default the lowercase name or alias used to invoke the command is passed alongside commands.Context to aid in determining the langcode you should use.

You can use any format or type for the language codes. We recommend using a recognized system such as the ISO 639 language code format as a str.

Parameters
  • ctx (commands.Context) – The context surrounding the command invocation.

  • name (str) – The name or alias used to invoke the command. This does not include the prefix, however if you need to retrieve the prefix see: commands.Context.prefix.

Returns

  • Any – The language code to pass to translate().

  • None – No translation attempt should be made with translate().

Example

# For example purposes only the "get_langcode" method is shown in this example...
# The "translate" method must also be implemented...

class HelloTranslator(commands.Translator[str]):
    def __init__(self) -> None:
        self.code_mapping = {"hello": "en", "bonjour": "fr"}

   def get_langcode(self, ctx: commands.Context, name: str) -> str | None:
       # Return a default of "en". Could also be ``None`` to prevent `translate` being called and to
       # send the default message...
       return self.code_mapping.get(name, "en")

@commands.command(name="hello", aliases=["bonjour"])
@commands.translator(HelloTranslator)
async def hello_command(ctx: commands.Context) -> None:
    await ctx.send_translated("Hello!")
abstract async translate(ctx: Context[Any], text: str, langcode: T) str

This function is a coroutine.

Method used to translate the content passed to commands.Context.send_translated() with the language code returned from get_langcode(). If None is returned from get_langcode(), this method will not be called and the default content provided to send_translated() will be sent instead.

You could use this method to call a local or external translation API, retrieve translations from a database or local mapping etc.

This method must return a str.

Parameters
  • ctx (commands.Context) – The context surrounding the command invocation.

  • text (str) – The content passed to send_translated() which should be translated.

  • langcode (Any) – The language code returned via get_langcode(), which can be used to determine the language the text should be translated to.

Returns

The translated text which should be sent. This should not exceed 500 characters.

Return type

str

Example

# For example purposes only the "translate" method is shown in this example...
# The "get_langcode" method must also be implemented...

class HelloTranslator(commands.Translator[str]):

    async def translate(self, ctx: commands.Context, text: str, langcode: str) -> str:
        # Usually you would call an API, or retrieve from a database or dict or some other solution...
        # This is just for an example...

        if langcode == "en":
            return text

        elif langcode == "fr":
            return "Bonjour!"

@commands.command(name="hello", aliases=["bonjour"])
@commands.translator(HelloTranslator)
async def hello_command(ctx: commands.Context) -> None:
    await ctx.send_translated("Hello!")