如何在电报机器人 python 代码中立即执行轮询功能?

How to execute poll function right away in telegram bot python code?

我正在尝试 运行 一个代码,它会在某些事件期间自动发送电报投票,并立即分析答案。

我找到了一个可以实现我想要的示例代码,但我想在 运行 执行这段代码后立即执行 self.poll() 而不是等待用户输入 ' /轮询'。 我还不熟悉这种编码风格,似乎找不到这样做的方法...有人可以帮我吗?

问题主要在代码的第83行。 (见那部分的评论)

from telegram import (
    Poll,
    ParseMode,
    KeyboardButton,
    KeyboardButtonPollType,
    ReplyKeyboardMarkup,
    ReplyKeyboardRemove,
    Update,
)
from telegram.ext import (
    Updater,
    CommandHandler,
    PollAnswerHandler,
    PollHandler,
    MessageHandler,
    Filters,
    CallbackContext,
)
from telegram import Bot
import time

class TelegramBot:
    def __init__(self, api_key, chat_id):
        self.api_key = api_key
        self.chat_id = chat_id
        self.options = ['0', '1', '2']

    def send_message(self, message):
        self.tel = Bot(token=self.api_key)
        self.tel.sendMessage(self.chat_id, message)

    def poll(self, update: Update , context: CallbackContext) -> None:
        """Sends a predefined poll"""
        options = self.options
        message = context.bot.send_poll(
            update.effective_chat.id,
            "What is the number?",
            options,
            is_anonymous=False,
            allows_multiple_answers=False
        )

        # Save some info about the poll the bot_data for later use in receive_poll_answer
        payload = {
            message.poll.id: {
                "options": options,
                "message_id": message.message_id,
                "chat_id": update.effective_chat.id,
                "answers": 0,
            }
        }
        context.bot_data.update(payload)

    def receive_poll_answer(self, update: Update, context: CallbackContext) -> None:
        """Summarize a users poll vote"""
        answer = update.poll_answer
        poll_id = answer.poll_id
        try:
            options = context.bot_data[poll_id]["options"]
        # this means this poll answer update is from an old poll, we can't do our answering then
        except KeyError:
            return
        selected_options = answer.option_ids
        answer_string = ""
        for option_id in selected_options:
            if option_id != selected_options[-1]:
                answer_string += options[option_id] + " and "
            else:
                answer_string += options[option_id]

        context.bot_data[poll_id]["answers"] += 1
        # Close poll after 50 participants voted
        if context.bot_data[poll_id]["answers"] == 50:
            context.bot.stop_poll(
                context.bot_data[poll_id]["chat_id"], context.bot_data[poll_id]["message_id"]
            )

    def run(self) -> None:
        """Run bot."""
        # Create the Updater and pass it your bot's token.
        updater = Updater(self.api_key)
        dispatcher = updater.dispatcher
        dispatcher.add_handler(CommandHandler('poll', self.poll)) # <---- I want to run self.poll right here when I execute this whole function run(). Currently it's only possible to trigger it by user input command '/poll'
        dispatcher.add_handler(PollAnswerHandler(self.receive_poll_answer))
        # Start the Bot
        updater.start_polling()
        updater.idle()

telegram_bot = TelegramBot('api_key', 'chat_id')
telegram_bot.send_message('/poll') # I tried sending /poll using the bot itself before executing run(), but it does not seem to register bot messages
telegram_bot.run()

poll 是处理程序回调,即它需要传入的 update 和与该更新关联的 context 才能工作。更准确地说,您的 poll 函数使用 update 中包含的 chat_id 将消息发送到, context.bot_data 存储数据, context.bot 发出请求电报。您可以做的是将 update- 和 context 相关的逻辑分解到另一个函数中,例如


def poll(self, chat_id, bot, bot_data):
    # what `poll` currently does but replace `update.effective_chat.id` with `chat_id`
   # and `context.{bot_data, bot}` with `bot_data`/`bot`

def poll_callback(self, update, context):
    self.poll(update.effective_chat.id, context.bot, context.bot_data)

(请注意,如果您将 self.bot = updater.bot 存储在 run 中会更容易 - 那么您不需要将 bot 传递给 poll 但可以只需使用 self.bot.)

然后您可以在 run 函数中调用 poll 作为

self.poll(some_chat_id, dispatcher.bot_data)

请注意 context.bot_data 总是与 dispatcher.bot_data 相同的对象,这就是它起作用的原因。


免责声明:我目前是 python-telegram-bot

的维护者