如何为Discord机器人实现带消息收集的问答式申请功能?
Discord机器人
>dm [user] apply命令优化方案 一、解决日志记录机器人自身消息的问题
在on_message事件里加个判断,直接跳过机器人自己发送的消息即可:
@bot.event async def on_message(message): # 跳过机器人自身消息,只记录用户的DM内容 if message.author.bot: await bot.process_commands(message) return if isinstance(message.channel, discord.DMChannel): channel = bot.get_channel(CHANNELID) # 替换成你的日志频道ID await channel.send(f"{message.author} 发送了:\n```{message.content}```") await bot.process_commands(message)
二、实现递进式提问与回答存储
要实现递进提问,需要临时跟踪用户的问答进度,这里用全局字典存储状态,配合wait_for监听用户回复。具体步骤:
- 定义提问列表和临时存储用户数据的字典
- 触发
apply命令时初始化用户的问答状态 - 逐个发送问题,收集用户回答
- 所有问题完成后,整合回答生成Embed发送到日志频道
完整示例代码
import discord import asyncio from discord.ext import commands # 替换成你的机器人前缀和TOKEN bot = commands.Bot(command_prefix=">", intents=discord.Intents.all()) CHANNELID = 1234567890 # 替换成你的日志频道ID # 临时存储用户申请进度:键为用户ID,值为{"answers": 已答内容列表} application_data = {} # 定义递进式提问列表 questions = [ "你的Discord用户名是什么?", "你的年龄是多少?", "你申请的理由是什么?" ] @bot.command() async def dmme(ctx, user: discord.User, *, message=None): if not message: await ctx.send('正确格式:`>dm [user] [消息内容]/apply`') return if message == "apply": # 检查用户是否正在进行申请 if user.id in application_data: await ctx.send(f"{user.mention} 当前正在进行申请,请完成后再发起") return # 初始化用户申请数据 application_data[user.id] = {"answers": []} await user.send(questions[0]) await ctx.send(f"已向 {user.mention} 发送申请提问") # 循环收集所有回答 for i in range(len(questions)): try: # 等待用户DM回复,超时时间5分钟 response = await bot.wait_for( "message", check=lambda m: isinstance(m.channel, discord.DMChannel) and m.author.id == user.id, timeout=300 ) except asyncio.TimeoutError: await user.send("申请超时,请重新发起") del application_data[user.id] await ctx.send(f"{user.mention} 申请超时") return # 存储当前回答 application_data[user.id]["answers"].append(response.content) # 发送下一个问题(如果不是最后一个) if i < len(questions) - 1: await user.send(questions[i+1]) # 所有问题回答完成,生成Embed user_answers = application_data[user.id]["answers"] embed = discord.Embed(title=f"{user.name} 的申请信息", color=0x5bcdee) for q, a in zip(questions, user_answers): embed.add_field(name=q, value=a, inline=False) # 发送到日志频道 log_channel = bot.get_channel(CHANNELID) await log_channel.send(embed=embed) await user.send("申请已提交,感谢你的参与!") # 清除临时数据 del application_data[user.id] else: # 原有普通消息发送逻辑 await user.send(message) await ctx.channel.purge(limit=1) log_channel = bot.get_channel(CHANNELID) embed = discord.Embed(title="普通DM消息记录", color=0x5bcdee) embed.add_field(name="发送内容", value=message, inline=False) embed.add_field(name="接收用户", value=user.mention, inline=False) await log_channel.send(embed=embed) print(f'"{message}" 发送给了 {user}') @bot.event async def on_message(message): # 跳过机器人自身消息 if message.author.bot: await bot.process_commands(message) return if isinstance(message.channel, discord.DMChannel): log_channel = bot.get_channel(CHANNELID) await log_channel.send(f"{message.author} 发送了:\n```{message.content}```") await bot.process_commands(message) # 替换成你的机器人TOKEN bot.run("YOUR_BOT_TOKEN")
代码说明
application_data字典用来隔离不同用户的申请数据,避免多用户同时申请时数据混乱wait_for监听用户的DM回复,设置5分钟超时,防止用户长期不回复占用资源- 问答完成后自动将问题与回答对应生成Embed,清晰展示申请信息
- 日志事件通过
message.author.bot判断,只记录真实用户的消息
内容的提问来源于stack exchange,提问作者exult1on
相关产品推荐
相关产品推荐

