如何在电报机器人 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
的维护者
我正在尝试 运行 一个代码,它会在某些事件期间自动发送电报投票,并立即分析答案。
我找到了一个可以实现我想要的示例代码,但我想在 运行 执行这段代码后立即执行 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