Telethon实现自动回复tg bot菜单消息

Telethon实现自动回复tg bot菜单消息

最近在tg上遇到一种场景,需要自动回复bot返回的菜单消息。网上没有相关教程,自行研究了一下。

tg bot消息类型

要实现bot菜单消息的自动回复,就需要知道bot有哪些消息类型。参考:

https://telegrambots.github.io/book/2/reply-markup.html

Telegram 提供两种类型的回复标记:自定义键盘内联键盘

每当您的机器人发送消息时,它都可以传递带有预定义回复选项的特殊键盘。常规键盘由对象表示ReplyKeyboardMarkup。您可以使用或发送民意调查向用户请求联系人或位置信息KeyboardButton。常规按钮将向聊天发送预定义文本。

键盘是按钮行的数组,每个按钮行由一个KeyboardButton对象数组表示。KeyboardButton支持文本和表情符号。菜单消息就属于自定义键盘类型。

案例分析

以某个bot为例,通过点击提供的菜单按钮实现特定的功能。但是点击之后回复的还是按钮消息让继续选择。然后回复一个数字下载特定的文件,最后需要遍历回复所有的数字,从消息中提取链接和密码内容。整个过程如何实现自动化呢?

telethon实现菜单消息回复

from utils import *
from telethon import TelegramClient,connection,errors,events,functions
import csv
import re

client = TelegramClient('Apitest', api_id, api_hash,proxy=tg_proxy,connection=connection.tcpabridged.ConnectionTcpAbridged)
bot_username = 'xxxxx' # 需要自动回复的bot名字
current_number = 6  # 开始的编号

@client.on(events.NewMessage)
async def handler(event):
    global current_number
    if event.sender_id == (await client.get_entity(bot_username)).id:
        print(f"Received message from {event.sender_id}: {event.text}")
        if event.message.reply_markup and hasattr(event.message.reply_markup, 'rows'):
            print("Reply markup found, checking buttons...")
            for row in event.message.reply_markup.rows:
                for button in row.buttons:
                    print(f"Button text: {button.text}")  # 打印每个按钮的文本
                    if button.text == 'Archive by number':
                        print("Triggering button press for 'Archive by number'")
                        try:
                            await client(functions.messages.GetBotCallbackAnswerRequest(
                                peer=event.sender_id,
                                msg_id=event.message.id,
                                data=button.data
                            ))
                            print("Button 'Archive by number' triggered")
                        except Exception as e:
                            print(f"Error triggering button: {e}")
                        # 发送档案编号
                        await client.send_message(event.sender_id, str(current_number))
                        print("Sent archive number")

            # 等待回应链接和密码
        if "Link is valid for 1 hour" in event.text:
            link = re.search(r'https://[^\s]+', event.text)
            password = re.search(r'Password: (\S+)', event.text)
            if link and password:
                link = link.group(0)
                password = password.group(1)
                print(f"Downloading file {current_number}: {link}")

                # 将链接和密码写入到 CSV
                with open('./links_and_passwords.csv', 'a', newline='') as csvfile:
                    csvwriter = csv.writer(csvfile)
                    csvwriter.writerow([current_number, link, password])

            if current_number < 1588:
                current_number += 1
                await asyncio.sleep(20)
                await client.send_message(event.sender_id, '📂 Download logs')

async def main():
    await client.start()
    bot_entity = await client.get_entity(bot_username)
    print(f"Bot entity: {bot_entity.username}")
    await client.send_message(bot_entity, '📂 Download logs')  # 初始触发

with client:
    client.loop.run_until_complete(main())
    client.run_until_disconnected()

代码关键点解析。

1、判断消息是否来自目标bot

if event.sender_id == (await client.get_entity(bot_username)).id:

2、判断消息类型是否为reply_markup并且包含行

if event.message.reply_markup and hasattr(event.message.reply_markup, 'rows'):

3、对每一行的button按钮进行遍历

for row in event.message.reply_markup.rows:
    for button in row.buttons:

4、判断当前按钮的内容并点击回复

if button.text == 'Archive by number':
    await client(functions.messages.GetBotCallbackAnswerRequest(
    peer=event.sender_id,
    msg_id=event.message.id,
    data=button.data
))

5、判断bot回复消息中是否包含特定关键字

if "Link is valid for 1 hour" in event.text:

如果是我们需要的消息才进一步处理。无关的消息内容直接忽略。

最终效果如上,自动化回复tg bot的消息。

赞赏

微信赞赏支付宝赞赏

Zgao

愿有一日,安全圈的师傅们都能用上Zgao写的工具。

发表评论