You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在discord.py中实现支持多时间单位的提醒命令?

问题拆解与实现思路

一、多时间单位参数解析(解决ValueError和BadArgument报错)

你遇到的两个报错根源很明确:

  • discord.ext.commands.errors.BadArgument:命令定义里time参数的类型设成了int,但用户输入的是带单位的字符串(比如5s),类型不匹配导致转换失败。
  • ValueError: invalid literal for int() with base 10: '5s':你尝试直接把带单位的字符串转成整数,自然会失败,必须先提取纯数字部分。

实现思路:

  1. 修改命令参数类型:把time参数从int改成str,或者用discord.py的自定义参数转换器,让框架自动帮你把输入字符串转成总秒数。
  2. 正则提取时间片段:用正则表达式匹配所有数字+单位的组合,比如r'(\d+)([hms])',用re.findall()可以一次性提取所有符合格式的片段(比如输入1h30m10s会得到[('1','h'), ('30','m'), ('10','s')])。
  3. 换算总秒数:对每个片段,把数字转成整数后按单位换算:1h=3600s,1m=60s,1s=1s,最后累加得到总时长。

参考方向:

  • 查阅discord.py官方文档里的「自定义参数转换器」章节,了解如何自定义参数解析逻辑。
  • 测试正则表达式的匹配效果,确保能覆盖用户可能的输入格式(比如空格分隔的1h 30m或者连写的1h30m)。

二、MySQL在长时提醒场景中的作用

用asyncio.sleep()做长时提醒的核心问题:

  • 机器人重启后,所有未执行的提醒直接丢失,无法恢复。
  • 大量长时提醒会占用大量协程,虽然协程轻量,但数量过多会增加内存占用和调度负担。
  • 无法对提醒进行管理(比如修改、删除、查看列表),因为数据只存在内存里。

MySQL的作用就是解决这些痛点:

  1. 持久化存储:把每个提醒的关键信息(用户ID、频道ID、提醒内容、触发时间戳、是否已触发)存在数据库里,机器人重启后可以重新加载未完成的提醒。
  2. 定时触发机制:不需要一直挂着协程等待,而是用后台循环任务(比如discord.py的tasks.loop)定期查询数据库,找出当前时间已到触发点的提醒,执行发送后标记为已触发。
  3. 功能扩展:后续要加提醒修改、删除、列表查询等功能,直接操作数据库即可,不需要复杂的内存数据管理。

入门方向:

  • 先学MySQL基础:创建数据库、设计提醒表(字段建议:主键ID、用户ID、频道ID、提醒内容、触发时间戳、触发状态)。
  • 用Python的MySQL驱动(比如mysql-connector-python或pymysql)实现数据库的增删改查操作。
  • 结合discord.py的tasks.loop装饰器,写一个定时任务,每隔几秒检查一次待触发的提醒。

三、分步实现建议

  1. 先搞定多时间参数解析:确保能正确解析各种带单位的输入,测试短时间提醒正常工作,解决当前的报错问题。
  2. 学习MySQL基础,搭建本地数据库,设计好提醒表结构。
  3. 重构提醒逻辑:收到命令时,计算触发时间戳,把提醒信息存入数据库,而不是直接用asyncio.sleep()。
  4. 实现后台触发任务:定期查询数据库,处理到期的提醒,发送消息后更新触发状态。
  5. 处理重启恢复:机器人启动时,查询所有未触发的提醒,确保重启后不会丢失。

内容的提问来源于stack exchange,提问作者Had

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:10:28