Как сразу выполнить функцию опроса в коде python бота telegram?

#python #telegram #telegram-bot #python-telegram-bot

Вопрос:

Я пытаюсь запустить код, который автоматически отправит опрос в telegram во время определенных событий и немедленно проанализирует ответы.

Я нашел пример кода, который может достичь того, чего я хочу, но я хотел бы выполнить self.poll() сразу после запуска этого фрагмента кода, вместо того, чтобы ждать, пока пользователь введет «/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()
 

Ответ №1:

poll является обработчиком обратного вызова, т. Е. Для работы ему требуется входящее update и context связанное с этим обновление. Точнее, ваша poll функция использует chat_id информацию, содержащуюся в update , для отправки сообщения, context.bot_data хранения данных и context.bot отправки запроса в Telegram. Что вы можете сделать, так это разложить 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 .)

Затем вы можете вызвать poll свою run функцию как

 self.poll(some_chat_id, dispatcher.bot_data)
 

Обратите внимание , что context.bot_data это всегда те же объекты dispatcher.bot_data , что и, вот почему это работает.


Отказ от ответственности: В настоящее время я являюсь сопровождающим python-telegram-bot