如何用Discord.py实现消息后2小时发消息并重置计时器?
实现Discord机器人消息超时提醒功能(带计时器重置)
核心思路
用字典存储每个频道的计时器任务,当新消息出现时,取消对应频道的旧计时器,重新创建2小时的新计时器;计时器触发时发送预设提醒消息。
代码实现(基于discord.py v2.x)
先确保安装依赖:
pip install discord.py
核心代码示例:
import discord from discord.ext import commands import asyncio # 配置机器人权限 intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) # 存储频道与对应计时器任务的映射,键为频道ID,值为asyncio.Task对象 channel_timers = {} async def send_timeout_reminder(channel): """计时器到期后执行的提醒逻辑""" try: await channel.send("已经2小时没人发言啦!") except discord.Forbidden: print(f"无法在频道 {channel.name} 发送消息:权限不足") finally: # 任务完成后清理字典中的记录 if channel.id in channel_timers: del channel_timers[channel.id] @bot.event async def on_message(message): # 忽略机器人自身发送的消息,避免无限循环 if message.author.bot: return channel_id = message.channel.id # 若该频道已有计时器,先取消旧任务 if channel_id in channel_timers: channel_timers[channel_id].cancel() # 创建新的2小时计时器(7200秒) new_timer = asyncio.create_task(send_timeout_reminder(message.channel)) channel_timers[channel_id] = new_timer # 处理其他命令(如果有) await bot.process_commands(message) @bot.event async def on_ready(): print(f"已登录:{bot.user} (ID: {bot.user.id})") print("------") # 替换为你的机器人Token bot.run("YOUR_BOT_TOKEN")
避免崩溃的关键细节
- 过滤机器人消息:必须判断
message.author.bot,否则机器人自己的提醒消息会触发计时器重置,陷入死循环。 - 安全取消任务:使用
Task.cancel()取消旧计时器,asyncio会自动捕获CancelledError,不会导致程序崩溃。 - 异常捕获:在发送提醒消息时加入
try-except,处理权限不足等异常,避免任务失败导致程序报错。 - 清理过期任务:计时器触发后从字典中移除对应记录,防止内存冗余。
- 权限配置:在Discord开发者平台开启
message_content意图,否则机器人无法读取消息内容,无法触发on_message事件。
扩展优化
- 若需为不同频道设置不同超时时间,可将字典值改为包含超时时长和任务的元组。
- 如需重启机器人后保留计时器状态,可将各频道最后消息时间存入SQLite等数据库,重启后计算剩余超时时间并重建计时器。
内容的提问来源于stack exchange,提问作者AdmiralG8
相关产品推荐
相关产品推荐

