Discord.py 动态命令选项:无需重启实时更新数据库内容

admin 百科 13

Discord.py 动态命令选项:无需重启实时更新数据库内容

本教程旨在解决 discord.py 机器人中动态命令选项无法实时更新的问题。文章将深入探讨 `app_commands.choices` 的局限性,并详细介绍如何利用 `app_commands.transformer` 结合异步数据库操作和高效缓存机制,实现命令选项的实时、动态更新。通过示例代码,您将学会如何构建一个响应迅速、数据一致的 discord 机器人,确保用户始终能访问到最新的数据。

引言:Discord.py 动态命令选项的挑战

在开发 Discord 机器人时,我们经常需要为斜杠命令提供一系列选项供用户选择。例如,一个管理课程的机器人可能需要用户选择一个课程标题。当这些选项来源于一个频繁更新的数据库时,传统的 @app_commands.choices 装饰器就显得力不从心。因为它在机器人启动时只评估一次,导致数据库中的新数据无法实时反映到命令选项中,除非重启机器人。这对于需要高实时性的应用来说是不可接受的。

静态选择的局限性

让我们首先审视 @app_commands.choices 的工作方式。以下是一个典型的使用场景:

import discord
from discord import app_commands, Interaction
from typing import List

# 假设 LessonRepository 是一个与数据库交互的类
class LessonRepository:
    @staticmethod
    def get_all_lessons():
        # 模拟从数据库获取所有课程
        # 实际上这里会进行数据库查询
        class LessonDTO:
            def __init__(self, title):
                self.title = title
        return [LessonDTO("数学"), LessonDTO("物理"), LessonDTO("化学")]

def lesson_choices() -> List[app_commands.Choice[str]]:
    """从数据库获取课程列表并转换为 Choices"""
    return [
        app_commands.Choice(name=lesson.title, value=lesson.title)
        for lesson in LessonRepository.get_all_lessons()
    ]

class SomeCog(discord.ext.commands.Cog):
    def __init__(self, bot: discord.ext.commands.Bot):
        self.bot = bot

    @app_commands.command(name="create_or_update_mark")
    @app_commands.default_permissions(administrator=True)
    @app_commands.choices(lesson=lesson_choices()) # 这里的 choices 在机器人启动时确定
    async def create_or_update_mark(self, interaction: Interaction,
                                    student: discord.Member,
                                    lesson: app_commands.Choice[str],
                                    logiks: app_commands.Range[int, 0, 8]):
        # ... 处理逻辑 ...
        await interaction.response.send_message(f"已更新 {student.display_name} 的 {lesson.value} 成绩。", ephemeral=True)

# 机器人启动代码
# bot = commands.Bot(command_prefix="!", intents=discord.Intents.all())
# async def setup():
#     await bot.add_cog(SomeCog(bot))
#     await bot.tree.sync()
# bot.run("YOUR_TOKEN")

登录后复制

如上述代码所示,@app_commands.choices(lesson=lesson_choices()) 这一行在机器人启动时,会调用 lesson_choices() 函数一次,并将其返回的结果作为该命令参数的固定选项。如果 LessonRepository.get_all_lessons() 返回的数据在机器人运行期间发生变化(例如,添加了新课程),命令选项列表不会自动更新。

初探自动补全 (Autocomplete) 及其不足

为了解决上述问题,很多开发者会尝试使用 Discord.py 提供的 autocomplete 功能。autocomplete 允许机器人根据用户的输入实时提供建议。以下是一个初步尝试的 autocomplete 实现:

Discord.py 动态命令选项:无需重启实时更新数据库内容-第2张图片-佛山资讯网

标签: python git 计算机 app 回调函数 工具 ai 标准库

发布评论 0条评论)

还木有评论哦,快来抢沙发吧~