
在构建discord机器人时,我们经常需要与用户进行多轮交互,例如发起投票、进行问卷调查或收集特定信息。传统的命令模式通常只能处理单次请求,而交互式投票则需要机器人能够“等待”用户的回复。discord.py库提供了bot.wait_for这一强大功能,允许机器人在特定条件下暂停执行,直到接收到符合条件的消息或事件。
本教程将聚焦于如何利用bot.wait_for来构建一个简单的投票系统,该系统能够:
要实现多轮投票,关键在于正确使用bot.wait_for并从接收到的消息对象中提取用户回复的文本内容。
首先,我们需要初始化一个Discord Bot实例,并定义要向用户提出的问题列表。请注意,为了让Bot能够读取用户的消息内容,必须在Intents中显式启用message_content。
import asyncio
import discord
from discord.ext import commands
# 初始化 Bot,设置命令前缀和必要的 Intents
# discord.Intents.default() 包含了 guilds, messages 等基础 Intents
# 必须显式启用 message_content Intent 才能读取用户的消息内容
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='+', intents=intents)
# 定义要提出的问题列表
questions = [
"你对这次活动的总体满意度如何?(1-5分)",
"你最喜欢活动中的哪个环节?",
"你有什么改进建议吗?"
]
@bot.event
async def on_ready():
"""Bot上线时触发的事件"""
print(f'{bot.user.name} 已经上线!')
# 替换为你的 Bot Token
# bot.run('YOUR_BOT_TOKEN')接下来,我们将创建一个poll命令。当用户触发此命令时,Bot将循环遍历questions列表,逐一发送问题,并使用bot.wait_for等待用户的回复。
bot.wait_for的关键参数:
捕获用户回复为字符串:当bot.wait_for成功接收到消息后,它会返回一个discord.Message对象。这个对象的content属性包含了用户发送的原始文本内容,即我们需要的字符串形式的答案。我们只需将message.content添加到答案列表中即可。
@bot.command()
async def poll(ctx):
"""
发起一个多轮交互式投票。
Bot会逐一提出问题,并收集用户的文本回复。
"""
answers = [] # 用于存储所有问题的答案
await ctx.send("你好!我们将开始一个简短的投票。请在30秒内回答每个问题。")
for i, question in enumerate(questions):
await ctx.send(f"问题 {i+1}/{len(questions)}: {question}")
try:
# 等待用户在当前频道回复消息
message = await bot.wait_for(
'message',
check=lambda m: m.channel == ctx.channel and m.author == ctx.author,
timeout=30 # 30秒内未回复则超时
)
# 将用户回复的内容(字符串形式)添加到答案列表中
answers.append(message.content)
await ctx.send(f"收到你的回答:'{message.content}'")
except asyncio.TimeoutError:
# 如果用户在规定时间内未回复,则触发超时
await ctx.send(f"问题 '{question}' 回复超时。投票已中断。")
break # 中断整个投票过程
# 投票结束后,根据收集到的答案数量判断投票状态
if len(questions) != len(answers):
await ctx.send("投票未完成。你未能回答所有问题。")
else:
await ctx.send("恭喜!你已完成所有问题的投票。")
# 在这里可以对收集到的答案进行进一步处理
print(f"收集到的答案:{answers}")
# 示例:将答案发送到另一个频道,或保存到数据库
# await process_poll_results(answers, ctx)在上述代码中,我们已经包含了超时处理逻辑。当asyncio.TimeoutError被捕获时,Bot会发送一条超时消息并中断投票循环。
投票结束后,我们可以通过比较questions列表的长度和answers列表的长度来判断用户是否完成了所有问题。
以下是整合了所有功能的完整Discord投票机器人代码示例:
import asyncio
import discord
from discord.ext import commands
# --- Bot 初始化 ---
intents = discord.Intents.default()
intents.message_content = True # 必须启用此 Intent 才能读取消息内容
bot = commands.Bot(command_prefix='+', intents=intents)
# --- 问题列表 ---
questions = [
"你对这次活动的总体满意度如何?(1-5分)",
"你最喜欢活动中的哪个环节?",
"你有什么改进建议吗?",
"你希望未来举办哪些类型的活动?"
]
# --- Bot 事件监听 ---
@bot.event
async def on_ready():
"""Bot上线时触发的事件"""
print(f'{bot.user.name} 已经上线并准备就绪!')
print(f'使用命令前缀: {bot.command_prefix}')
# --- 投票命令 ---
@bot.command()
async def poll(ctx):
"""
发起一个多轮交互式投票。
Bot会逐一提出问题,并收集用户的文本回复。
"""
answers = [] # 用于存储所有问题的答案
await ctx.send(f"你好 {ctx.author.mention}!我们将开始一个简短的投票。请在**30秒内**回答每个问题。")
for i, question in enumerate(questions):
await ctx.send(f"**问题 {i+1}/{len(questions)}:** {question}")
try:
# 等待用户在当前频道回复消息
# check 函数确保消息来自发起命令的用户,并且在当前频道
message = await bot.wait_for(
'message',
check=lambda m: m.channel == ctx.channel and m.author == ctx.author,
timeout=30 # 30秒内未回复则超时
)
# 将用户回复的内容(字符串形式)添加到答案列表中
answers.append(message.content)
await ctx.send(f"✅ 收到你的回答:'{message.content}'")
except asyncio.TimeoutError:
# 如果用户在规定时间内未回复,则触发超时
await ctx.send(f"❌ 问题 '{question}' 回复超时。投票已中断。")
break # 中断整个投票过程
# 投票结束后,根据收集到的答案数量判断投票状态
if len(questions) != len(answers):
await ctx.send("⚠️ 投票未完成。你未能回答所有问题。")
else:
await ctx.send("? 恭喜!你已完成所有问题的投票。")
# --- 后续处理示例 ---
await ctx.send("以下是你提交的所有答案:")
for j, answer_text in enumerate(answers):
await ctx.send(f"**问题 {j+1}:** {questions[j]}\n**你的回答:** {answer_text}")
# 实际应用中,你可能需要将这些答案保存到数据库、文件或发送给管理员
print(f"用户 {ctx.author} 完成了投票。收集到的答案:{answers}")
# 示例:将答案保存到日志文件
with open("poll_results.log", "a", encoding="utf-8") as f:
f.write(f"用户: {ctx.author} ({ctx.author.id})\n")
for k, ans in enumerate(answers):
f.write(f" 问题 {k+1}: {questions[k]}\n")
f.write(f" 回答: {ans}\n")
f.write("-" * 30 + "\n")
await ctx.send("投票结果已记录。感谢你的参与!")
# --- 运行 Bot ---
# 请将 'YOUR_BOT_TOKEN' 替换为你的 Discord Bot Token
# bot.run('YOUR_BOT_TOKEN')通过discord.py的bot.wait_for功能,我们可以轻松构建出交互式的Discord投票机器人。核心在于理解如何设置check函数来筛选目标消息,以及如何通过message.content提取用户回复的字符串。结合适当的错误处理和用户体验设计,你的Bot将能够高效地收集用户的反馈和意见。
以上就是构建Discord投票机器人:高效收集用户文本答案的指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号