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

Discord.js实现messageDelete事件Embed批量聚合发送方法

批量聚合发送删除日志实现方案

核心思路是用模块级缓存队列暂存窗口期内生成的日志Embed,通过单一定时器控制等待窗口,凑够阈值或者窗口超时就批量发送,避免每条消息单独开定时器、单独发消息。

实现逻辑拆解

  • 在事件文件模块顶层定义3个缓存变量,模块加载时仅初始化一次,不会随事件触发重置:
    • logQueue:数组类型,暂存待发送的删除日志Embed
    • waitTimer:存当前等待窗口的定时器ID,避免重复创建定时器
    • cachedWebhook:缓存获取到的日志频道webhook,避免每次触发事件都重复请求接口拉取webhook列表
  • 保留原有前置校验、单条Embed生成逻辑,生成完Embed后不直接创建延迟发送任务,而是将Embed推入logQueue队列
  • 每次入队后做判断:
    • 如果队列长度累计达到5条:立刻清除当前等待定时器,取出队列内所有Embed批量发送,发送完成后清空队列、重置定时器和webhook缓存标记
    • 如果当前没有运行中的等待定时器:启动5秒等待定时器,定时器到期后不管队列里剩几条日志,都一次性批量发送,发送完成后清空队列、重置相关标记
  • 修正原有代码的权限判断bug:permissions.has传多个权限时需要用数组包裹,否则只会校验第一个传入的权限
  • Discord单条消息最多支持携带10个Embed,攒5条批量发送完全符合接口限制,不会触发接口报错

修改后完整代码

const Discord = require('discord.js')
// 模块级缓存,仅在模块加载时初始化一次
const logQueue = [];
let waitTimer = null;
let cachedWebhook = null;

module.exports = {
    name: 'messageDelete',
    async execute(client, message) {
        if (message.channel.type === 'DM') return;
        if (message.author == client) return;
        if (!message.author) return;
        if(message.embeds.length > 0) return;
        if(message.attachments.size) return;

        let Channel = client.channels.cache.get("CHANNEL-ID")
        if (!Channel){
            return;
          } else if (Channel.type !== 'GUILD_TEXT') {
            return;
          } else if (!data.Mod.Logs.isEnabled){
            return;
          } else if(!Channel.guild.me.permissions.has(["EMBED_LINKS", "VIEW_CHANNEL", "READ_MESSAGE_HISTORY", "VIEW_AUDIT_LOG", "SEND_MESSAGES"])) {
            return;
          }

        const timestamp = Math.floor(Date.now() / 1000)
        const Msg = message.toString().substr(0, 500);
        const DeletedLog = new Discord.MessageEmbed()
        .setAuthor({ name: message.author.username, iconURL: message.author.displayAvatarURL({dynamic: true, size: 2048}) })
        .setTitle(`<a:Down:853495989796470815> Deleted Message`)
        .setDescription(`<a:iNFO:853495450111967253>  **Member**: \`${message.author.tag}\` (${message.author.id})\n<:pp198:853494893439352842> **In**: ${message.channel}\n• **At**: <t:${timestamp}>\n\n<a:Right:877975111846731847> **Content**: \`\`\`\n${Msg || '❌ | Unkown message!'}\n\`\`\``)
        .setColor('RED')
        .setFooter({ text: message.guild.name, iconURL: message.guild.iconURL({dynamic: true}) })
        .setTimestamp()
        .setThumbnail(message.author.displayAvatarURL({dynamic: true}))

        // 新日志入队
        logQueue.push(DeletedLog);

        // 批量发送公共方法
        const sendBatchLogs = async () => {
            try {
                if (waitTimer) {
                    clearTimeout(waitTimer);
                    waitTimer = null;
                }
                if (logQueue.length === 0) return;
                
                // 无缓存webhook时拉取并缓存
                if (!cachedWebhook) {
                    const webhooks = await Channel.fetchWebhooks();
                    cachedWebhook = webhooks.filter((w)=>w.type === "Incoming" && w.token).first();
                    const botname = client.user.username;
                    if(!cachedWebhook){
                        cachedWebhook = await Channel.createWebhook(botname, {avatar: client.user.displayAvatarURL({ format: 'png', dynamic: true, size: 128 })})
                    }
                }

                // 批量发送队列内所有embed
                await cachedWebhook.send({embeds: [...logQueue]}).catch(() => {});
                // 发送完成清空队列
                logQueue.length = 0;
            } catch (err) {
                // 异常时重置缓存和队列,避免阻塞后续日志
                logQueue.length = 0;
                cachedWebhook = null;
            }
        }

        // 凑够5条立刻触发批量发送
        if (logQueue.length >= 5) {
            sendBatchLogs();
        } 
        // 无运行中定时器时启动5秒等待窗口
        else if (!waitTimer) {
            waitTimer = setTimeout(() => {
                sendBatchLogs();
            }, 5000);
        }

        return;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:54:32