Pyrogram Telegram Bot小纸条(三)

老房东老房东
1 min read

与Telegram Bot打交道的一个最多的方式就是使用命令,在官方的文档里命有专门的介绍默认的情况下命令是由/开头的字符串。如果在对话中有多个Bot,你可以使用/command@botname来向指定的Bot发出问题。在继续之前,你应该已经读完小纸条一小纸条二,并建立好了你的启动bot.py文件,并使用plugins来加载我们的插件。接下来,我们大多数的都是一个个plugin的方式来开发。

处理Bot Commands

如果我们要接收一个Command,需要做的事有三步:

  • 使用装饰器标识出过滤我们指定的命令的规则
  • 使用函数参数接收当前运行时态的client以及用户发来的message
  • 处理并决定如何回复这个Command

简单的/info

我们写一个最简单的示例来完成这个功能:

from pyrogram import Client, filters
from pyrogram.types import Message


@Client.on_message(filters.command(["info", "i"]) & filters.private)
async def start_command(client: Client, message: Message):
    await message.reply(str(message), quote=True)

这个示例非常忠实的完成了上面所说的三步,第三步使用回复你发出的命令方式把你发出的消息的真实内容都告诉了你:

image.png

如果你想要继续Telegram相关的开发,强烈建议你通过这个方法仔细看看一个Message里有什么。

解析发出的消息

我喜欢的/info命令应该还能够通过回复一条消息,来得到另一条消息的Message内容。例如:

image.png

我可以通过发出一条回复消息(第二条消息),将被回复的消息(第一条包含有一首歌的消息)Message信息显示出来。通过Message的属性文档我们可以知道,当收的消息是另一条消息的回复时,就会出现reply_to_message_id属性,所以我们使用这个特性来更新我们的程序了:

from pyrogram import Client, filters
from pyrogram.types import Message


@Client.on_message(filters.command(["info", "i"]) & filters.private)
async def start_command(client: Client, message: Message):
    if message.reply_to_message_id:
        await message.reply(str(message.reply_to_message), quote=True)
    else:
        await message.reply(str(message), quote=True)

这样,这条命令就是一个非常独特的info功能了,当你只发/info给bot时,它会把自己的Message体告诉你,如果你使用/info命令回复一个消息时,它会告诉你另一条消息的Message信息。

为Command加入参数

有朋友告诉我,在回复一条消息的/info命令时,我也想看看Command消息的信息,怎么做呢?你可以再写一个命令,这里我们使用一个参数来解决这个问题。如果我使用/info回复一个消息时,我们就显示它回复的消息的信息,如果使用/info org,哪么就显示命令本身的信息。这时,/info就是命令,而org就是一个参数了。这个可以使用Message的command属性来帮我们解析:

from pyrogram import Client, filters
from pyrogram.types import Message


@Client.on_message(filters.command(["info", "i"]) & filters.private)
async def start_command(client: Client, message: Message):
    if message.reply_to_message_id and (not "org" in message.command):
        await message.reply(str(message.reply_to_message)[:4096], quote=True)
    else:
        await message.reply(str(message)[:4096], quote=True)

不过这个代码写的并不是原意,这个代码是当发现/info回复了一条消息时(message.reply_to_message_id)并且command里没有包括org参数(not "org" in message.command)。但是达到目的就好了嘛。

声明和提示Commands

接收一个Command非常容易,但是如何向用户提示我们的Bot有哪些Command可以使用呢?BotCommand就是给用户声明的一个方式,你可以使用set_bot_commands来设置你给用户提示的BotCommand们。我希望在Bot启动时设置,所以我们再次修改一下bot.py:

from pyrogram import Client, idle
from pyrogram.types import (BotCommand, BotCommandScopeAllGroupChats,
                            BotCommandScopeAllPrivateChats)

plugins = dict(root="plugins")
app = Client("hdcola",  plugins=plugins)

async def main():
    async with app:
        await app.set_bot_commands([
            BotCommand("help", "帮助"),
            BotCommand("start", "开始")
        ], scope=BotCommandScopeAllGroupChats())
        await app.set_bot_commands([
            BotCommand("info", "显示消息信息,你可以通过回复一个消息来得到另一条消息的信息"),
            BotCommand("help", "帮助"),
            BotCommand("start", "开始")
        ], scope=BotCommandScopeAllPrivateChats())
        print(f"Starting {app.me.username} {app.me.id} ...")
        await idle()
        await app.stop()


app.run(main())

当你把Bot启动后,就会在Bot对话时看到输入框左侧有一个按钮,按下它会告诉你Bot支持的Command列表:

image.png

image.png

如果你在输入框中输入一个/也会得到提示:

image.png

是不是非常方便呢?

1
Subscribe to my newsletter

Read articles from 老房东 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

老房东
老房东