如何在异步 python-telegram-bot 中处理 CustomContext 进行身份验证

问题描述 投票:0回答:1

我正在尝试为每个与我的 Telegram 机器人对话的用户实现一种识别(如身份验证)方法。

在旧版本的 python-telegram-bot 中,我能够使用 CustomContext 很好地完成它。

以前是这样的。

def get_user(update):

    user_id = update.effective_user.id

    try:
        user_telegram = UserTelegram.objects.get(chat_id=user_id)
    except UserTelegram.DoesNotExist: 
        first_name = update.effective_user.first_name
        last_name = update.effective_user.last_name
        user_telegram = UserTelegram.objects.create(chat_id=user_id, first_name=first_name, last_name=last_name) 

    if not user_telegram.active:        
        text="Not allowed."
        update.message.reply_text(text=text)
    
    return user_telegram



class CustomContext(CallbackContext[ExtBot, dict, dict, dict]):
    
    @classmethod
    def from_update(
        cls,
        update: object,
        application: "Application",
    ) -> "CustomContext":
            
        context = super().from_update(update, application)
        context.user_telegram = get_user(update)
        
        
        return context

我现在的问题是 python-telegram-bot 20.4 的异步控件。我的 get_user 函数应该在异步模式下工作。但我找不到一种方法来使请求起作用。

我做了以下事情:

from asgiref.sync import async_to_sync, sync_to_async

@sync_to_async
def get_user(update):

    user_id = update.effective_user.id
    try:
        user_telegram = UserTelegram.objects.get(chat_id=user_id)
    ...

但这需要“from_update”是异步的。

    @classmethod
    async def from_update(
        cls,
        update: object,
        application: "Application",
    ) -> "CustomContext":
        context = super().from_update(update, application)
        context.user_telegram = await get_user(update)

    ...

这给了我以下错误:

File "/usr/local/lib/python3.10/site-packages/telegram/ext/_application.py", line 1156, in process_update
    await context.refresh_data()
AttributeError: 'coroutine' object has no attribute 'refresh_data'

如果我从“from_update”中删除异步等待,则请求完成,但数据库查询未结束 - 它返回协程。

如何管理我的用户状态?

我知道我们有装饰器可以帮助我对某些命令强制执行身份验证。但我一直在寻找一些默认值,它还可以从数据库向我提供用户对象,该对象将作为上下文传递给命令。

我正在使用 Django==4.2.3,因此我不使用正在运行的任务。数据库是 Postgres。 python-telegram-bot==20.4

顺便说一句:也欢迎不同的方法。

python authentication telegram python-telegram-bot
1个回答
0
投票

在检查哪些处理程序应实际处理更新的同一过程中为每个传入更新创建

context
对象。如果该进程向 API 发出请求(这可能需要一些时间,可能会失败等),这可能会严重影响并发处理的方式并延迟更新的整体处理。因此,
from_update
并不是被设计为协程函数。

现在,要在每次更新时运行一些基于 I/O 的逻辑(例如对 Bot API 的请求)并使数据可供所有后续处理程序使用,我建议在低

TypeHandler
中使用
group
。另请查看这个 wiki 页面,它详细描述了这个概念。


免责声明:我目前是

python-telegram-bot
的维护者。

© www.soinside.com 2019 - 2024. All rights reserved.