如何让Slash Command中的Embed每10秒自动更新?
解决Embed消息每10秒自动更新的问题
你的问题核心是没把定时更新逻辑和Slash Command的回复绑定,而且更新时没有获取最新的播放数据。下面是完整的可实现方案:
核心步骤
- 发送初始Embed时保存消息引用,方便后续编辑
- 每次更新都重新拉取最新的队列、播放进度等动态数据
- 用
setInterval定时触发更新,同时做好定时器的清理逻辑
完整代码示例
// 在Slash Command的处理函数内执行 const initialEmbed = new EmbedBuilder() .setAuthor({ name: track.title, iconURL: client.user.displayAvatarURL({ size: 1024, dynamic: true }) }) .setThumbnail(track.thumbnail) .addFields( { name: "音量", value: `**${queue.volume}**` }, { name: "时长", value: `**${trackDuration}**` }, { name: "播放进度", value: `**${progress}**` }, { name: "重复模式", value: `**${methods[queue.repeatMode]}**` }, { name: "点歌人", value: `**${track.requestedBy.tag}**` } ) .setFooter({ text: inter.user.username, iconURL: inter.user.displayAvatarURL({ dynamic: true }) }) .setColor("#ff0000") .setTimestamp(); // 发送初始回复并获取消息实例,必须加fetchReply: true const replyMessage = await inter.reply({ embeds: [initialEmbed], fetchReply: true }); // 定义更新函数 const updateEmbed = async () => { // 重新获取最新的队列数据,避免使用初始的静态变量 const latestQueue = client.distube.getQueue(inter.guildId); if (!latestQueue || !latestQueue.current) { // 播放结束或队列不存在,清理定时器并更新提示 clearInterval(updateInterval); await replyMessage.edit({ embeds: [new EmbedBuilder().setTitle("播放已结束").setColor("#ff0000")] }); return; } const latestTrack = latestQueue.current; // 这里用Distube内置的格式化时间,你也可以用自己的progress计算逻辑 const latestProgress = latestQueue.formattedCurrentTime; const latestDuration = latestTrack.formattedDuration; // 生成最新的Embed const updatedEmbed = new EmbedBuilder() .setAuthor({ name: latestTrack.title, iconURL: client.user.displayAvatarURL({ size: 1024, dynamic: true }) }) .setThumbnail(latestTrack.thumbnail) .addFields( { name: "音量", value: `**${latestQueue.volume}**` }, { name: "时长", value: `**${latestDuration}**` }, { name: "播放进度", value: `**${latestProgress}**` }, { name: "重复模式", value: `**${methods[latestQueue.repeatMode]}**` }, { name: "点歌人", value: `**${latestTrack.requestedBy.tag}**` } ) .setFooter({ text: inter.user.username, iconURL: inter.user.displayAvatarURL({ dynamic: true }) }) .setColor("#ff0000") .setTimestamp(); // 编辑原有消息 await replyMessage.edit({ embeds: [updatedEmbed] }); }; // 设置10秒定时更新 const updateInterval = setInterval(updateEmbed, 10000); // 监听播放结束事件,自动清理定时器 client.distube.on("finish", (queue) => { if (queue.guild.id === inter.guildId) { clearInterval(updateInterval); } });
你之前失败的常见原因
- 没有保存消息引用:直接用
inter.editReply多次调用可能因上下文失效报错,必须保存fetchReply返回的消息实例 - 使用静态数据:初始的
trackDuration、progress是固定值,更新时没重新拉取最新播放状态 - 未清理定时器:播放结束后定时器仍在运行,会因队列不存在抛出错误
- 权限缺失:确保机器人拥有编辑消息的权限
内容的提问来源于stack exchange,提问作者samba
相关产品推荐
相关产品推荐

