Nextcord动态获取选项:如何将用户ID传入fetch_choices函数?
解决Nextcord斜杠命令动态获取用户物品选项的问题
你原来的写法行不通,因为SlashOption的choices参数是在命令注册阶段就会执行计算的,这时候还没有用户触发交互,根本拿不到user_id。正确的做法是用Nextcord的**自动补全(Autocomplete)**功能,在用户开始输入选项时动态获取用户ID并查询物品。
步骤1:修改斜杠命令定义
去掉choices参数,改为设置autocomplete=True:
async def duel(interaction: nextcord.Interaction, item: str = nextcord.SlashOption("item", autocomplete=True), quantity: int = 1, side: str = "h"): # 这里写你的命令逻辑,比如处理决斗操作 await interaction.response.send_message(f"已选择物品:{item},数量:{quantity}")
步骤2:编写自动补全回调函数
这个函数会在用户输入选项时触发,此时可以通过interaction拿到用户ID,再查询数据库生成选项:
import asyncio async def item_autocomplete(interaction: nextcord.Interaction, current: str): # 获取当前发起命令的用户ID user_id = interaction.user.id # 用asyncio.to_thread执行同步数据库操作,避免阻塞机器人事件循环 item_list = await asyncio.to_thread(get_user_items, user_id) # 过滤出包含用户当前输入内容的选项(可选,提升用户体验) matched_items = [item for item in item_list if current.lower() in item.lower()] # 转换为Discord要求的选项格式,最多返回25个(Discord限制) return [nextcord.SelectOption(label=item, value=item) for item in matched_items][:25] # 重构你的数据库查询函数,只负责同步获取物品列表 def get_user_items(user_id): c.execute("SELECT * FROM items WHERE user_id=?", (user_id,)) rows = c.fetchall() # 提取物品名称返回 return [row[1] for row in rows]
步骤3:绑定自动补全函数到命令
有两种方式绑定:
方式一:用装饰器
@bot.slash_command(name="duel", description="发起决斗") @nextcord.autocomplete(item=item_autocomplete) async def duel(interaction: nextcord.Interaction, item: str = nextcord.SlashOption("item", autocomplete=True), quantity: int = 1, side: str = "h"): await interaction.response.send_message(f"已选择物品:{item},数量:{quantity}")
方式二:事后绑定
@bot.slash_command(name="duel", description="发起决斗") async def duel(interaction: nextcord.Interaction, item: str = nextcord.SlashOption("item", autocomplete=True), quantity: int = 1, side: str = "h"): await interaction.response.send_message(f"已选择物品:{item},数量:{quantity}") # 给item参数绑定自动补全函数 duel.autocomplete("item")(item_autocomplete)
关键说明
- 自动补全是在用户触发命令并开始输入选项时才执行,此时能拿到完整的
interaction对象,自然可以获取用户ID。 - 同步数据库操作必须放到
asyncio.to_thread中执行,否则会阻塞机器人的事件循环,导致机器人无法响应其他指令。 - Discord限制自动补全最多返回25个选项,所以最后要做切片处理。
内容的提问来源于stack exchange,提问作者Brody Critchlow
相关产品推荐
相关产品推荐

