如何将message参数从messageCreate事件传入discord-music-player事件
实现方案
核心思路
discord-music-player的事件回调本身支持读取队列绑定的自定义数据,你可以通过两种方式将message实例传递到事件回调中:
- 闭包访问:在
messageCreate事件的作用域内绑定音乐播放器的事件监听,回调可以直接读取当前作用域的message对象,适合单次临时事件 - 队列挂载:将
message实例写入队列的自定义数据字段,全局绑定的播放器事件可以从队列参数中直接读取,适合多服务器通用的全局事件
代码示例
// 提前初始化discord-music-player实例,此处省略初始化逻辑 const { Player } = require('discord-music-player'); const player = new Player(client, { leaveOnEmpty: false, }); // 全局绑定的播放器事件,适合所有服务器共用的逻辑 player.on('songStart', (queue, song) => { // 从队列的自定义数据中拿到之前存入的message实例 const message = queue.data.message; message.channel.send(`当前正在播放:*${song.name}*,由 ${song.requestedBy.tag} 点播`); }); client.on('messageCreate', async (message) => { // 常规消息过滤逻辑 if (message.author.bot || !message.guild || !message.member.voice.channel) return; // 匹配播放命令 if (message.content.startsWith('!play')) { const searchContent = message.content.slice(5).trim(); if (!searchContent) return message.reply('请输入要搜索的歌曲名称'); // 创建队列时把message实例存入自定义data字段 const queue = player.createQueue(message.guild.id, { data: { message: message } }); // 加入语音频道逻辑 try { if (!queue.connection) await queue.connect(message.member.voice.channel); } catch (err) { player.deleteQueue(message.guild.id); return message.reply('无法加入你所在的语音频道,请检查权限配置'); } // 搜索歌曲并播放 const searchResult = await player.search(searchContent, { requestedBy: message.author }); const targetSong = searchResult.tracks[0]; if (!targetSong) return message.reply('未找到匹配的歌曲资源'); queue.play(targetSong); } // 作用域内绑定临时事件示例,只会在当前message触发的播放流程生效 player.once('songAdd', (queue, song) => { message.reply(`已成功将 *${song.name}* 添加到播放队列`); }); });
注意事项
- 不要全局存储单个
message实例,多服务器并发触发播放指令时会出现实例串用的问题 - 全局绑定的事件不要写在
messageCreate事件内部,否则每次收到消息都会重复绑定事件,导致同个事件触发多次回调 - 临时事件可以用
once方法绑定,触发后会自动销毁监听,不会造成内存泄漏
内容的提问来源于stack exchange,提问作者Eclipse Game18
相关产品推荐
相关产品推荐

