#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