使用作业队列时无法访问 user_data
Cannot access user_data when using job queue
我有一个函数,我需要既能通过发送命令执行又能使用 job queue 自动执行。在那个函数中,我需要访问 user_data
来存储特定于每个用户的数据。现在的问题是,当我尝试通过作业队列执行它时,user_data
是 None
,因此不可用。我该如何解决?
这是我目前的简化方式:
import datetime
from settings import TEST_TOKEN, BACKUP_USER
from telegram.ext import Updater, CommandHandler, CallbackContext
from pytz import timezone
def job_daily(context: CallbackContext):
job(BACKUP_USER, context)
def job_command(update, context):
job(update.message.chat_id, context)
def job(chat_id, context):
print(context.user_data)
def main():
updater = Updater(TEST_TOKEN, use_context=True)
dispatcher = updater.dispatcher
job_queue = updater.job_queue
# To run it automatically
tehran = timezone("Asia/Tehran")
due = datetime.time(15, 3, tzinfo=tehran)
job_queue.run_daily(job_daily, due)
# To run it via command
dispatcher.add_handler(CommandHandler("job", job_command))
updater.start_polling()
updater.idle()
if __name__ == "__main__":
main()
现在,当我发送命令 /job
并因此执行 job_command
时,job
函数打印 {}
,这意味着我可以访问 user_data
。但是当执行 job_daily
函数时, job
函数打印 None
意味着我无权访问 user_data
。 chat_data
.
也是如此
在python-telegram-bot
的回调函数中,context.user_data
和context.chat_data
依赖于update
。更准确地说,PTB 接受 update.effective_user/chat.id
并提供相应的 user/chat_data
。作业回调不是由 update
触发(而是基于时间的触发器),因此没有合理的方法来提供 context.user_data
.
当从处理程序回调中安排作业时,可以做的是将其作为 context
参数传递,其中 user_data
可用工作:
context.job_queue.run_*(..., context=context.user_data)
然后在作业回调中,您可以将其检索为 user_data = context.job.context
在您的情况下,您将作业安排在 main
中,这不是处理程序回调,因此您没有 context.user_data
(甚至没有 context
)。如果你有一个特定的用户 ID,你想为其传递 user_data
,你可以将 user_data
作为 user_data = updater.dispatcher.user_data[user_id]
,这是与 context.user_data
相同的对象(用于来自该特定用户的更新)。
免责声明:我目前是 python-telegram-bot
.
的维护者
我有一个函数,我需要既能通过发送命令执行又能使用 job queue 自动执行。在那个函数中,我需要访问 user_data
来存储特定于每个用户的数据。现在的问题是,当我尝试通过作业队列执行它时,user_data
是 None
,因此不可用。我该如何解决?
这是我目前的简化方式:
import datetime
from settings import TEST_TOKEN, BACKUP_USER
from telegram.ext import Updater, CommandHandler, CallbackContext
from pytz import timezone
def job_daily(context: CallbackContext):
job(BACKUP_USER, context)
def job_command(update, context):
job(update.message.chat_id, context)
def job(chat_id, context):
print(context.user_data)
def main():
updater = Updater(TEST_TOKEN, use_context=True)
dispatcher = updater.dispatcher
job_queue = updater.job_queue
# To run it automatically
tehran = timezone("Asia/Tehran")
due = datetime.time(15, 3, tzinfo=tehran)
job_queue.run_daily(job_daily, due)
# To run it via command
dispatcher.add_handler(CommandHandler("job", job_command))
updater.start_polling()
updater.idle()
if __name__ == "__main__":
main()
现在,当我发送命令 /job
并因此执行 job_command
时,job
函数打印 {}
,这意味着我可以访问 user_data
。但是当执行 job_daily
函数时, job
函数打印 None
意味着我无权访问 user_data
。 chat_data
.
在python-telegram-bot
的回调函数中,context.user_data
和context.chat_data
依赖于update
。更准确地说,PTB 接受 update.effective_user/chat.id
并提供相应的 user/chat_data
。作业回调不是由 update
触发(而是基于时间的触发器),因此没有合理的方法来提供 context.user_data
.
当从处理程序回调中安排作业时,可以做的是将其作为 context
参数传递,其中 user_data
可用工作:
context.job_queue.run_*(..., context=context.user_data)
然后在作业回调中,您可以将其检索为 user_data = context.job.context
在您的情况下,您将作业安排在 main
中,这不是处理程序回调,因此您没有 context.user_data
(甚至没有 context
)。如果你有一个特定的用户 ID,你想为其传递 user_data
,你可以将 user_data
作为 user_data = updater.dispatcher.user_data[user_id]
,这是与 context.user_data
相同的对象(用于来自该特定用户的更新)。
免责声明:我目前是 python-telegram-bot
.