discord.js中如何每隔3秒刷新embed实现音乐机器人进度条实时更新
discord.js音乐机器人nowplaying消息自动刷新实现方案
核心实现逻辑
- 首次执行
nowplaying命令时发送初始embed消息,拿到该消息的实例对象 - 启动间隔3秒的定时器,每次拉取最新的播放队列数据,重新生成embed后编辑已有消息
- 每次更新前校验终止条件,满足任意条件则直接清除定时器停止更新:
- 当前服务器无正在播放的音乐队列
- 正在播放的歌曲已不是触发命令时的对应歌曲(用户切歌、歌曲播放完毕)
- 机器人/触发命令的用户不在语音频道,或二者不在同一个语音频道
完整修改后的代码
module.exports = { name: 'nowplaying', aliases: ['np'], category: 'Music', utilisation: '{prefix}nowplaying', // 增加async标识处理异步操作 async execute(client, message) { if (!message.member.voice.channel) return message.channel.send(`${client.emotes.error} - You're not in a voice channel !`); if (message.guild.me.voice.channel && message.member.voice.channel.id !== message.guild.me.voice.channel.id) return message.channel.send(`${client.emotes.error} - You are not in the same voice channel !`); if (!client.player.getQueue(message)) return message.channel.send(`${client.emotes.error} - No music currently playing !`); const getCurrentEmbed = () => { // 抽离embed生成逻辑,避免重复写代码 const track = client.player.nowPlaying(message); const filters = []; Object.keys(client.player.getQueue(message).filters).forEach((filterName) => client.player.getQueue(message).filters[filterName]) ? filters.push(filterName) : false; return { color: 'RED', author: { name: track.title }, footer: { text: 'Developed by Haruke#6969' }, fields: [ { name: 'Channel', value: track.author, inline: true }, { name: 'Requested by', value: track.requestedBy.username, inline: true }, { name: 'From playlist', value: track.fromPlaylist ? 'Yes' : 'No', inline: true }, { name: 'Views', value: track.views, inline: true }, { name: 'Duration', value: track.duration, inline: true }, { name: 'Filters activated', value: filters.length + '/' + client.filters.length, inline: true }, { name: 'Volume', value: client.player.getQueue(message).volume, inline: true }, { name: 'Repeat mode', value: client.player.getQueue(message).repeatMode ? 'Yes' : 'No', inline: true }, { name: 'Currently paused', value: client.player.getQueue(message).paused ? 'Yes' : 'No', inline: true }, { name: 'Progress bar', value: client.player.createProgressBar(message, { timecodes: true }), inline: true } ], thumbnail: { url: track.thumbnail }, timestamp: new Date(), } } // 发送首次消息,拿到消息实例 const npMessage = await message.channel.send({ embed: getCurrentEmbed() }); // 存储当前歌曲ID,用于后续校验是否切歌 const originTrackId = client.player.nowPlaying(message).id; // 启动3秒刷新定时器 const updateInterval = setInterval(async () => { try { // 校验终止条件 const queue = client.player.getQueue(message); if ( !queue || !queue.playing || !message.member.voice.channel || !message.guild.me.voice.channel || message.member.voice.channel.id !== message.guild.me.voice.channel.id || queue.nowPlaying(message).id !== originTrackId ) { clearInterval(updateInterval); return; } // 更新embed await npMessage.edit({ embed: getCurrentEmbed() }); } catch (err) { // 捕获消息被删除等异常,直接清除定时器 clearInterval(updateInterval); } }, 3000) }, };
注意事项
- 若你使用的discord-player版本中
track.id字段不存在,可以替换为track.url作为歌曲唯一标识 - 刷新间隔可根据需求调整,不建议设置低于1秒,避免触发Discord接口频率限制
- 代码中已包含异常捕获逻辑,若用户手动删除了nowplaying消息,定时器会自动停止不会报错
内容的提问来源于stack exchange,提问作者Haruke Sensei
相关产品推荐
相关产品推荐

