我的discord.js机器人似乎同时运行了多个实例

4
我想做一个简单的机器人来检测命令。我创建了一个“!test”命令,它会执行一些操作(回复消息,删除消息,然后稍后删除答案,还会在频道中记录命令)。
看起来它工作得很好,但是它会不断地发送答案并执行一系列动作:http://prntscr.com/nkgj8m(每次重新启动机器人时都会增加更多)。
我尝试删除应用程序并重新创建它,这样它就可以正常工作:消息只显示一次,直到我重新启动机器人。
我创建了一个“!stop”命令来销毁客户端,但是它没有按预期工作:机器人已断开连接(在我的控制台中显示“stop”),但几乎立即重新连接到我的服务器上(我不再在本地控制台中看到日志)。
虽然消息计数有点“随机”,但有些机器人消息有时根本不会被删除,并且也不会被记录。

这是我的代码(我以前从未真正使用过js,所以可能会误用一些东西,或者有些东西可能不太优化,对此我很抱歉-我做了一些研究,大多数东西我认为还不错,至少还可以)。

// Require libs
require('dotenv').config()
const Discord = require('discord.js');

// Get discord client
var client = new Discord.Client();
initialize();

// --------------------------------------------------
//      INITIALIZE
// --------------------------------------------------

function initialize() {
    // On ready
    client.on("ready", function() {
        console.log(`Logged in as ${client.user.tag}! Yup, this is the default message.`);
    });

    // On message
    client.on("message", function(input) {
        // server message
        if (input.guild.available) {
            // get the message content
            var command = input.content.toLowerCase();
            // stop command
            if (command.startsWith("!stop")) {
                client.destroy();
                console.log("Stopped");
            }
            // test command
            else if (command.startsWith("!test")) {
                input.reply(`This is my answer to your test !`)
                    .then(function(output) {
                        consumeCommand(input, output, 5000);
                    })
                    .catch(console.error);
            }
        }
    });

    // login bot client
    client.login(process.env.BOT_TOKEN);
}

// --------------------------------------------------
//      CONSULE AND LOG COMMANDS
// --------------------------------------------------

// Log the output of a command, delete the input message and delete the output soon
// input, message, the user message
// output, string, is the bot output
// outputTimeout, int, is the time we should wait until deleting the bot's output
function consumeCommand(input, output, outputTimeout) {
    // delete input
    input.delete(0)
        .then(function() {
            console.log(`Deleted message ${input.content}`)
        })
        .catch(console.error);
    // log
    var logChannel = input.guild.channels.find(channel => channel.name === 'guiguibot-commands');
    if (logChannel != null) {
        logCommand(input, output, logChannel);
    } else {
        console.log("Trying to log bot command but there's no guiguibot-commands channel");
    }
    // delete output later if not null
    if (output != null && outputTimeout != null) {
    }
}

// Log the output of a command
// input, message, the user message
// msg, message, the user message
// output, string, is the bot output
function logCommand(input, output, logChannel) {
    // has output
    if (output != null) {
        logChannel.send(`@${input.author.username} sent a command`, {
          embed: {
            fields: [
              {
                name: ":keyboard: Input :",
                value: `\`${input.content}\``
              },
              {
                name: ":robot: Output :",
                value: `\`${output.content}\``
              }
            ]
          }
        })
            .then(() => console.log('Logged user action'))
            .catch(console.error);
    }
    // no ouput
    else {
        logChannel.send(`@${input.author.id} sent a command (no output was found)`, {
          embed: {
            fields: [
              {
                name: ":keyboard: Input :",
                value: `\`${input.content}\``
              }
            ]
          }
        })
            .then(function() {
                console.log('Logged user action')
            })
            .catch(console.error);
    }
}

所以,我的问题是:如何确保我的代码只运行一个实例?(如果我正确地推断了问题)。任何帮助都将不胜感激。谢谢!

你是使用Heroku或其他服务来托管机器人,还是从你的电脑上运行Node? - slothiful
@slothiful 我在我的电脑上运行了“npm run start”(其中start运行“node index.js”)。 - GuillaumeVDN
2个回答

2
你不需要创建一个initialize()方法,只需要按照以下方式操作即可:

无需创建initialize()方法,只需按照以下方式操作:

// Require libs
require('dotenv').config()
const Discord = require('discord.js');

// Get discord client
var client = new Discord.Client();

// On ready
client.on("ready", function() {
    console.log('Logged in as ${client.user.tag}! Yup, this is the default message.');
});

// On message
client.on("message", function(input) {
    // server message
    if (input.guild.available) {
        // get the message content
        var command = input.content.toLowerCase();
        // stop command
        if (command.startsWith("!stop")) {
            client.destroy();
            console.log("Stopped");
        }
        // test command
        else if (command.startsWith("!test")) {
            input.reply('This is my answer to your test !')
                .then(function(output) {
                    consumeCommand(input, output, 5000);
                })
                .catch(console.error);
        }
    }
});

// --- CONSOLE AND LOG COMMANDs go here ---

// login bot client
client.login(process.env.BOT_TOKEN);

是的,我知道,只是因为我想使用一个函数,因为我更习惯于Java,所以这让我感到不安。它是否会影响性能或其他什么? - GuillaumeVDN
@GuillaumeVDN 我只是不习惯按照你的方式去做,我以为这是你的问题...但如果它仍然执行onready和onmessage,那应该没问题吧。 - SomeCoder

0

根据@slothiful的建议,我简单地将它托管在Heroku上解决了这个问题!我猜想我的脚本一直被重启,导致与Discord服务器的连接倍增?不太确定。事实是现在它运行良好,只有一个实例在处理我的命令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接