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

自制Discord音乐机器人在线但无法接收命令,求排查原因

Discord音乐机器人无法接收命令的问题排查

问题描述

我没有使用现成的机器人,而是自行开发了一款Discord音乐机器人,运行脚本后机器人已在Discord上线,但无法接收命令,测试发现消息处理函数未生效。以下是我的代码:

const Discord = require('discord.js');
const {
        prefix,
        token,
} = require('./config.json');
const ytdl = require('ytdl-core');
const { CLient, GatewayIntentBits } = require('discord.js')
const client = new Discord.Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent,
        GatewayIntentBits.GuildMembers,
    ],
});
const queue = new Map();

client.once('ready', () => {
        console.log('Ready!');
});

client.once('reconnecting', () => {
        console.log('Reconnecting!');
});

client.once('disconnect', () => {
        console.log('Disconnect!');
});

client.on('message', async message => {
        console.log('Message recieved')
        if (message.author.bot) return;
        if (!message.content.startsWith(prefix)) return;

        const serverQueue = queue.get(message.guild.id);

        if (message.content.startsWith(`!play`)) {
                execute(message, serverQueue);
                return;
        } else if (message.content.startsWith(`!skip`)) {
                skip(message, serverQueue);
                return;
        } else if (message.content.startsWith(`!stop`)) {
                stop(message, serverQueue);
                return;
        } else {
                message.channel.send('You need to enter a valid command!')
        }
});

async function execute(message, serverQueue) {
        const args = message.content.split(' ');

        const voiceChannel = message.member.voiceChannel;
        if (!voiceChannel) return message.channel.send('You need to be in a voice channel to play music!');
        const permissions = voiceChannel.permissionsFor(message.client.user);
        if (!permissions.has('CONNECT') || !permissions.has('SPEAK')) {
                return message.channel.send('I need the permissions to join and speak in your voice channel!');
        }

        const songInfo = await ytdl.getInfo(args[1]);
        const song = {
                title: songInfo.title,
                url: songInfo.video_url,
        };

        if (!serverQueue) {
                const queueContruct = {
                        textChannel: message.channel,
                        voiceChannel: voiceChannel,
                        connection: null,
                        songs: [],
                        volume: 5,
                        playing: true,
                };

                queue.set(message.guild.id, queueContruct);

                queueContruct.songs.push(song);

                try {
                        var connection = await voiceChannel.join();
                        queueContruct.connection = connection;
                        play(message.guild, queueContruct.songs[0]);
                } catch (err) {
                        console.log(err);
                        queue.delete(message.guild.id);
                        return message.channel.send(err);
                }
        } else {
                serverQueue.songs.push(song);
                console.log(serverQueue.songs);
                return message.channel.send(`${song.title} has been added to the queue!`);
        }

}

function skip(message, serverQueue) {
        if (!message.member.voiceChannel) return message.channel.send('You have to be in a voice channel to stop the music!');
        if (!serverQueue) return message.channel.send('There is no song that I could skip!');
        serverQueue.connection.dispatcher.end();
}

function stop(message, serverQueue) {
        if (!message.member.voiceChannel) return message.channel.send('You have to be in a voice channel to stop the music!');
        serverQueue.songs = [];
        serverQueue.connection.dispatcher.end();
}

function play(guild, song) {
        const serverQueue = queue.get(guild.id);

        if (!song) {
                serverQueue.voiceChannel.leave();
                queue.delete(guild.id);
                return;
        }

        const dispatcher = serverQueue.connection.playStream(ytdl(song.url))
                .on('end', () => {
                        console.log('Music ended!');
                        serverQueue.songs.shift();
                        play(guild, serverQueue.songs[0]);
                })
                .on('error', error => {
                        console.error(error);
                });
        dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
}

client.login(token);

我的config.json文件中仅包含token和prefix变量,目前未使用prefix变量,命令前缀为“!”。请问问题可能出在哪里?


问题原因及解决方法

  • 核心问题:事件名称错误
    Discord.js v14及以上版本已弃用message事件,改用messageCreate事件。你当前代码里的client.on('message', ...)无法监听新消息,把事件名改成messageCreate即可:

    client.on('messageCreate', async message => {
        // 原逻辑代码不变
    });
    
  • 前缀检查拦截命令
    代码里写了if (!message.content.startsWith(prefix)) return;,但你提到config里的prefix变量未按!配置。如果config.json里的prefix不是!,所有!开头的命令都会被这个判断拦截。解决方法二选一:

    1. 把config.json里的prefix值设为"!";
    2. 直接将代码中的prefix替换为"!",比如改成if (!message.content.startsWith('!')) return;。
  • 拼写错误隐患
    代码里存在一处变量拼写错误:const { CLient, GatewayIntentBits } = require('discord.js')里的CLient应为Client(首字母是小写L)。虽然当前用Discord.Client初始化客户端暂时不影响,但建议修正避免后续问题。

  • 后续潜在适配问题
    即使消息事件正常触发,代码还存在Discord.js v14的API适配问题:

    • message.member.voiceChannel已改为message.member.voice.channel;
    • connection.playStream()已改为connection.play()。
      这些会导致!play命令执行时出错,建议同步适配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 13:37:05