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

Discord.js插件开发问题:如何移除多上传中的不合规附件?

问题分析与解决方案

核心问题

Discord.js 中,已发送消息的附件集合是只读的——你无法通过 message.attachments.delete() 移除单个不合规附件。消息一旦发送,附件就与消息绑定,无法拆分修改,这是你当前代码无效的根本原因。

另外原代码还有两个逻辑问题:

  • 使用 forEach(async ...) 会导致异步逻辑混乱,循环内的 await 不会按顺序执行,后续代码可能在异步操作完成前就触发
  • 重复执行删除消息的逻辑,且前面的删除附件操作本身就不生效

可行解决方案

针对你的需求,有两种可选方案:

方案1:存在不合规附件则删除整条消息

适合要求严格的场景,只要有不合规文件就直接移除整条消息:

  1. 遍历所有附件,标记不合规项
  2. 若存在不合规附件,删除原消息并发送警告

方案2:保留合规附件,重新发送后删除原消息

如果需要保留合规内容,可提取合规附件重新发送,再删除原消息:

  1. 分离合规与不合规附件
  2. 发送警告告知用户
  3. 若有合规附件,重新发送到频道
  4. 删除原消息

修正后的代码(方案2示例)

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 *  |  [ Image / Link Checker ]  |
 *  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
const allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'mp4'];
const util = require('util');

// 将数据库查询转换为Promise形式(避免回调嵌套)
const dbQuery = util.promisify(db.query.bind(db));

try {
  // 数据库查询
  const [res] = await dbQuery(
    'SELECT imageChannel, warnChannel FROM config WHERE server = ?',
    [message.guild.id]
  );
  const warnChannel = res[0]['warnChannel'];
  const imageChannel = [res[0]['imageChannel']];

  if (imageChannel.includes(message.channel.id)) {
    const attachments = message.attachments;
    if (attachments.size > 0) {
      const validAttachments = [];
      const invalidAttachments = [];

      // 用for...of遍历,避免异步forEach的顺序问题
      for (const attachment of attachments.values()) {
        // 提取文件扩展名(兼容无扩展名的情况)
        const fileParts = attachment.name.toLowerCase().split('.');
        const fileExtension = fileParts.length > 1 ? fileParts.pop() : '';
        
        if (allowedExtensions.includes(fileExtension)) {
          validAttachments.push(attachment);
        } else {
          invalidAttachments.push(attachment);
        }
      }

      if (invalidAttachments.length > 0) {
        // 发送警告消息
        const warnChannelObj = message.guild.channels.cache.get(warnChannel);
        if (warnChannelObj) {
          warnChannelObj.send(`${message.author}, 你上传了不符合要求的文件,仅支持图片(png/jpg/jpeg/gif)和视频(mp4)格式。`);
        }

        // 重新发送合规附件
        if (validAttachments.length > 0) {
          await message.channel.send({
            content: `${message.author} 上传的合规文件:`,
            files: validAttachments.map(att => ({
              attachment: att.url,
              name: att.name
            }))
          });
        }

        // 删除原消息
        await message.delete();
        console.log(`删除包含不合规附件的消息,原作者:${message.author.tag}`);
      }
    }
  }
} catch (err) {
  console.error('数据库查询错误:', err);
}

关键优化点

  • 用 for...of 替代 forEach(async ...),确保异步操作按顺序执行
  • 简化文件扩展名提取逻辑,兼容无扩展名的异常情况
  • 将数据库查询改为Promise形式,避免回调地狱
  • 通过「重新发送合规附件 + 删除原消息」的方式实现需求,绕开Discord无法修改已发送消息附件的限制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:15:13