Introduction to Commands¶
Defining Commands¶
To define a command, simply use the telegrampy.ext.commands.Bot.command()
decorator on a coroutine. The coroutine’s name will be the command’s name.
Alternatively, you can define a command with the telegrampy.ext.commands.command()
decorator and add it to the bot with the telegrampy.ext.commands.Bot.add_command() method.
import telegrampy
from telegrampy.ext import commands
bot = commands.Bot("token here")
@bot.command()
async def hi(ctx):
await ctx.send("Hello!")
bot.run()
With the above code, a user would invoke the command with /hi,
and the bot would respond with Hello!.
Each command must have at least one parameter, ctx,
which is a telegrampy.ext.commands.Context object.
In the case that the command name must be different from the coroutine name,
you can use the name kwarg in telegrampy.ext.commands.command().
For a full list of parameters, see telegrampy.ext.commands.Command.
Using Arguments¶
If you need to collect input from the user, you’ll want to use arguments.
Positional Arguments¶
@bot.command()
async def test(ctx, arg):
await ctx.send(arg)
How does this translate in Telegram?
User: /test hi
Bot : hi
Quite simply, the bot repeats the first word after the command.
Warning
Please note that you will only get the first word using this method, as shown below.
User: /test hi there
Bot : hi
Because of the way python works, you can have as many positional arguments as you want.
For example:
@bot.command()
async def test(ctx, arg1, arg2):
await ctx.send(f"Arg1 is {arg1} and arg2 is {arg2}.")
Keyword Arguments¶
Description and an example for keyword arguments, or “consume rest”.
@bot.command()
async def test(ctx, *, arg):
await ctx.send(arg)
In Telegram:
User: /test hello there
Bot: hello there
Extras¶
Extras will include a list of args, like *args.
@bot.command()
async def test(ctx, *args):
await ctx.send(str(args))
In Telegram:
User: /test hello there
Bot: ('hello', 'there')
Using Converters¶
Converters can be usefull if you need to convert an argument to an object.
For example you may have a command that needs to take an argument as a telegrampy.User.
Basic Converters¶
A basic converterer is a callable that takes an argument and returns an object or variable. For example, if you wanted to make a command that added two numbers you could use the integer converter.
@bot.command()
async def add(ctx, a: int, b: int):
await ctx.send(a+b)
Since any callable can be used as a converter, you can make your own converter with a function.
def codeblock(arg):
return f"`{arg}`"
@bot.command(name="codeblock")
async def codeblock_command(ctx, code: codeblock):
await ctx.send(code)
Advanced and Custom Converters¶
Sometimes basic converters may not work for our needs. For example, We may need to get more context on the command invocation or do something async.
That’s what a telegrampy.ext.commands.Converter is for.
We can use a builtin telegrampy.ext.commands.Converter like this. Telegram.py will see that user should be passed in as a user object and then use the telegrampy.ext.commands.UserConverter to convert it.
@bot.command()
async def dm(ctx, user: telegrampy.User):
await user.send("Hello!")
If we want to make a custom converter we can do this.
class CommandConverter(commands.Converter):
async def convert(self, ctx, arg):
command = ctx.get_command(arg)
if not command:
raise commands.BadArgument(arg, commands.Command, f"Could not find a command named '{arg}'")
return command
@bot.command(name="info", description="Get info on a command")
async def info(ctx, command: CommandConverter):
await ctx.send(f"{command.name}: {command.description}")