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

discord.py计数游戏消息校验删除功能TypeError报错修复

Discord计数机器人校验问题修复与优化实现
  • 完全可以实现删除不合规消息的需求,支持「开头为正确计数数字+后续任意备注」的格式规则。

报错根因

你遇到的TypeError: expected string or bytes-like object是因为re.sub方法要求传入字符串类型的待处理内容,但你写的代码里直接把Discord的Message实例、Message对象列表传入了正则方法,类型不匹配直接触发报错。
除此之外原代码还存在几个逻辑问题:

  • 频道判断逻辑重复,同时硬编码ID和按名称匹配,容易出现逻辑冲突
  • 正则替换直接覆盖了原始message对象,后续调用消息删除、作者属性获取等操作都会失效
  • 没有做边界场景兜底:频道第一条消息无前置计数、消息提取不到有效数字、机器人自身消息触发循环等场景都会直接抛错
  • 正则规则有漏洞:用\D替换所有非数字字符,会把1a2这类非法格式识别为12,不符合校验要求

修复后的完整实现代码

import re
import discord

@client.event
async def on_message(message):
    # 拦截机器人自身消息,避免循环触发
    if message.author.bot:
        return

    # 匹配计数频道,直接使用ID匹配稳定性更高,替换为你实际的频道ID即可
    count_channel = discord.utils.get(message.guild.text_channels, id=862353141535325)
    # 非计数频道直接放行,不做校验
    if message.channel != count_channel:
        await client.process_commands(message)
        return

    # 只提取消息开头的连续数字,后续备注内容不做校验
    current_num_match = re.match(r'^(\d+)', message.content.strip())
    # 消息开头无有效数字直接判定违规
    if not current_num_match:
        await message.delete()
        await message.channel.send("Incorrect.", delete_after=1)
        return

    try:
        current_num = int(current_num_match.group(1))
        # 拉取最近频道历史,找到当前消息之前的最新一条非机器人发送的消息作为上一条计数
        history_msgs = await count_channel.history(limit=3).flatten()
        prev_count_msg = None
        for msg in history_msgs:
            if msg.id != message.id and not msg.author.bot:
                prev_count_msg = msg
                break

        # 频道内第一条计数消息,必须从1开始
        if not prev_count_msg:
            if current_num != 1:
                await message.delete()
                await message.channel.send("Incorrect.", delete_after=1)
            return

        # 提取上一条消息的计数数字
        prev_num_match = re.match(r'^(\d+)', prev_count_msg.content.strip())
        prev_num = int(prev_num_match.group(1)) if prev_num_match else 0

        # 校验计数连续性
        if current_num != prev_num + 1:
            await message.delete()
            await message.channel.send("Incorrect.", delete_after=1)
            return

    except Exception as e:
        # 异常兜底,避免机器人因意外场景崩溃
        print(f"计数校验流程异常: {str(e)}")
        await message.delete()
        await message.channel.send("Incorrect.", delete_after=1)
        return

    # 校验通过,正常放行其他指令逻辑
    await client.process_commands(message)

实现优化说明

  • 修正正则入参错误:仅对消息内容message.content字符串做正则匹配,不再直接操作消息实例和列表对象
  • 正则规则更合理:用^(\d+)匹配开头连续数字,天然支持数字后加任意备注的格式,同时避免了全量替换非数字字符导致的非法格式漏判问题
  • 逻辑顺序更高效:优先判断是否需要拦截(机器人消息、非目标频道),不符合校验场景直接返回,减少不必要的接口请求和计算
  • 边界场景全覆盖:处理了频道首条消息、上条消息格式异常、类型转换失败等边缘情况,增加异常兜底避免机器人崩溃
  • 兼容其他指令:增加client.process_commands调用,不会影响机器人后续其他命令功能的正常使用
  • 频道匹配更稳定:统一使用频道ID做匹配,不会因为频道名称修改导致校验逻辑失效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:12:25