python - 如何在电报机器人python代码中立即执行轮询功能?
问题描述
我正在尝试运行一个代码,该代码将在某些事件期间自动发送电报投票,并立即分析答案。
我找到了一个可以实现我想要的示例代码,但我想在运行这段代码时立即执行 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()
解决方案
poll
是一个处理程序回调,即它需要一个传入update
和context
与该更新相关联的工作。更准确地说,您的poll
函数使用 中chat_id
包含的向 Telegramupdate
发送消息、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
推荐阅读
- python - 如何在 Django 框架的 HTML 页面中显示图像?
- asterisk - 如何添加事件监听器来调用挂断 PHP AGI?
- java - UsernamePasswordAuthenticationFilter 跳过成功处理程序
- c++ - 如何使用递归在 .txt 中编写多行?
- javascript - 如何在反应循环中设置动态复选框的状态?
- java - 无法在 Java 中找到确切日期匹配的 Mongodb 文档
- c - 计算总数 文件中的关键字
- c++ - 如何使用 asn1c 生成的代码解码 MAP Invoke 消息
- javascript - 如何使用 Firebase 云功能向多个设备令牌发送通知
- flutter - 任务 ':app:compileDebugJavaWithJavac' 执行失败。扑