discordjs / discord.js

A powerful JavaScript library for interacting with the Discord API
https://discord.js.org
Apache License 2.0
25.24k stars 3.96k forks source link

Bot stops receiving chat messages randomly #2814

Closed RossComputerGuy closed 6 years ago

RossComputerGuy commented 6 years ago

Please describe the problem you are having in as much detail as possible: I found while using my bot's fanart command that after a random amount of times using that command, the bot no longer works in chat so I have to restart it using pm2. This has become a big issue for the server this bot bellongs to since the bot also has moderating features.

Include a reproducible code sample here, if possible:

const argParser = require("yargs-parser");
const API = require("micro-api-client");
const Discord = require("discord.js");
const fs = require("fs");
const _getURLs = require("get-urls");
const Kaori = require("kaori");
const path = require("path");
const youtubeSearch = require("youtube-search");

const client = new Discord.Client();
const kaori = new Kaori();

var channels = {};
var roles = {};

function userHasRole(role,user) {
    return client.guilds.get("471433266247893004").roles.get(roles[role]).members.find("user",user) != null;
}

function getURLs(str) {
    var urls = [];
    var _u = _getURLs(str);
    var keys = _u.keys();
    var val = keys.next();
    while(!val.done) {
        urls.push(val.value);
        val = keys.next();
    }
    return urls;
}

function toUpperCaseV2(str) {
    var splitStr = str.toLowerCase().split(" ");
    for(var i = 0;i < splitStr.length;i++) {
        splitStr[i] = splitStr[i].charAt(0).toUpperCase()+splitStr[i].substring(1);     
    }
    return splitStr.join(" "); 
}

function getConfig() {
    return JSON.parse(fs.readFileSync(path.join(__dirname,"config.json")).toString());
}

function randomBool() {
    return Math.round((Math.random()*1)+0) == 0;
}

function randomItem(arr) {
    return arr[Math.floor(Math.random()*arr.length)];
}

function randomRange(min,max) {
    return Math.floor(Math.random()*(max-min+1))+min;
}

function findChannel(id) {
    return client.channels.get(id);
}

function dbRead(key) {
    try {
        return JSON.parse(fs.readFileSync(path.join(__dirname,"db.json")).toString())[key];
    } catch(ex) {
        fs.writeFileSync(path.join(__dirname,"db.json"),"{\"users\":{},\"slowChannels\":{}}");
        return JSON.parse(fs.readFileSync(path.join(__dirname,"db.json")).toString())[key];
    }
}

function dbWrite(key,value) {
    var db;
    try {
        db = JSON.parse(fs.readFileSync(path.join(__dirname,"db.json")).toString());
    } catch(ex) {
        fs.writeFileSync(path.join(__dirname,"db.json"),"{\"users\":{},\"slowChannels\":{}}");
        db = JSON.parse(fs.readFileSync(path.join(__dirname,"db.json")).toString());
    }
    db[key] = value;
    fs.writeFileSync(path.join(__dirname,"db.json"),JSON.stringify(db));
}

function getUser(user) {
    return dbRead("users")[user.id];
}

function userCheck(user) {
    var users = dbRead("users");
    if(!users[user.id]) users[user.id] = {};
    if(typeof(users[user.id].settings) != "object") users[user.id].settings = {};
    if(typeof(users[user.id].settings.reaction) != "boolean") users[user.id].settings.reaction = false;
    dbWrite("users",users);
}

function findSiteURL(site,id) {
    for(var s in kaori.sites) {
        var st = kaori.sites[s];
        if(site == s || st.aliases.indexOf(site) > -1) {
            var url = "http://"+s;
            return "http://"+s+getConfig()["fanartPath"][s]+id;
        }
    }
}

function youtubeDisplay(result,channel) {
    var embed = new Discord.RichEmbed();
    embed.setTitle(result.title);
    embed.setAuthor(result.channelTitle);
    embed.setURL("https://youtu.be/"+result.id);
    embed.setThumbnail(result.thumbnails.default.url);
    embed.setDescription(result.description);
    embed.setTimestamp(new Date(result.publishedAt));
    channel.send("",embed);
}

function randomSite() {
    return randomItem(Object.keys(kaori.sites));
}

function kaoriSearch(msg,site,tags,rating,rtf) {
    kaori.search(site,{tags:tags,limit:1+Math.floor(Math.random()*1000),random:true})
        .then(images => {
            var img = images[Math.floor(Math.random()*images.length)];
            if(!rtf) {
                while(img.common.rating == "e") img = images[Math.floor(Math.random()*images.length)];
            } else {
                while(img.common.rating == "s") img = images[Math.floor(Math.random()*images.length)];
            }
            if(rating != null) {
                while(img.common.rating != rating) img = images[Math.floor(Math.random()*images.length)];
            }
            if(img.common.rating == "e" && !msg.channel.nsfw) {
                msg.channel.stopTyping(true);
                return msg.reply("Please use this command in <#471725747262980107>");
            }
            var embed = new Discord.RichEmbed();

            var imageURL = img.common.fileURL || img.common.file_url;
            embed.setTitle(findSiteURL(site,img.id));
            embed.setAuthor(img.uploader_name || img.author || "anonymous");
            embed.setDescription([
                "<:glasses:471458502330548224> Score: "+img.score
            ].join("\n"));
            embed.setImage(imageURL);
            embed.setFooter("Tags: "+(img.tag_string || img.common.tags.join(" ") || "none"));
            embed.setTimestamp(new Date(img.created_at));
            embed.setURL(findSiteURL(site,img.id));
            if(getConfig()["rating"][img.common.rating] != null) embed.setColor(getConfig()["rating"][img.common.rating]);
            else console.log("Unknown rating: "+img.common.rating);

            msg.channel.send("Found an image by "+(img.uploader_name || img.author || "anonymous"),embed);
            msg.channel.stopTyping(true);
        })
        .catch(err => {
            msg.reply(err.toString()+"\nFailed to access: "+site);
            msg.channel.stopTyping(true);
        });
}

client.on("ready",() => {
    if(getConfig()["online"]) findChannel("471433266725912656").send("Super Spiral Engines are online");
    for(var role of client.guilds.get("471433266247893004").roles.array()) roles[role.name] = role.id;
    for(var channel of client.channels.array()) channels[channel.name] = channel;
    client.user.setActivity(getConfig()["prefix"]+"help",{ type: "WATCHING" });
});

client.on("guildMemberAdd",member => {
    if(getConfig()["welcome"]) findChannel("471433266725912656").send("Welcome "+member.toString()+" to the Gurren Lagann Discord server. You can get a character role from <#471927341015367680>.");
    userCheck(member.user);
});

client.on("message",msg => {
    client.user.setActivity(getConfig()["prefix"]+"help",{ type: "WATCHING" });
    userCheck(msg.author);
    if(getConfig()["automod"]) {
        var slowChannels = dbRead("slowChannels") || {};
        if(typeof(slowChannels[msg.channel.name]) != "undefined" && !msg.author.bot) {
            channels[msg.channel.name].fetchMessage(slowChannels[msg.channel.name].lastMessage).then(message => {
                var timestamp = new Date(msg.createdAt-message.createdAt);
                if((timestamp.getTime()/1000) <= slowChannels[msg.channel.name].speed) msg.delete();
                else {
                    slowChannels[msg.channel.name].lastMessage = msg.id;
                    dbWrite("slowChannels",slowChannels);
                }
            }).catch(err => msg.channel.send(err.toString()));
        }
    }
    var urls = getURLs(msg.content);
    if(urls.length > 0) {
        for(var url of urls) {
            if(getConfig()["automod"]) {
                if(url.startsWith("https://discord.gg/")) {
                    if(msg.channel.name != "affiliated-servers") {
                        return msg.delete().then(message => message.reply("Please no invite links"))
                            .catch(err => msg.reply(err.toString()));
                    }
                }
            }
        }
    }
    if(msg.content.startsWith(getConfig()["prefix"])) {
        var cmd = argParser(msg.content.substr(getConfig()["prefix"].length));
        switch(cmd["_"][0]) {
            case "fanart":
                msg.channel.startTyping(20);
                cmd["_"].shift();
                if(cmd["_"].length == 0) cmd["_"].push("tengen_toppa_gurren_lagann");
                var site = cmd["site"] || randomSite();
                while(site == "gelbooru.com/index.php") site = randomSite();
                kaoriSearch(msg,site,cmd["_"],cmd["rating"] || "s",false);
                break;
            case "hack": msg.reply("https://www.youtube.com/watch?v=iY2JzfLU8Ds");
                break;
            case "help":
                var helpembed = new Discord.RichEmbed();
                helpembed.setTitle("Lordgenome bot (version "+getConfig()["version"]+") help");
                helpembed.setColor("GREEN");
                helpembed.setDescription([
                    "I am Lordgenome, also known as the Spiral King.",
                    "",
                    "Here's a list of the commands:",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"fanart\tFetches a piece of fanart",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"hack\tStart hacking",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"help\tThis message",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"lazengann-overload\tLazengann Overload!!!",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"quote\tQuotes a character from GL",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"r34\tRule 34 (**NSFW**)",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"restart\tRestarts the bot, use this if the bot is acting up.",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"settings <name> <value>\tSets a settings value",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"slow\tToggles raid prevention on the current channel (**Moderators Only**)",
                    "<:glasses:471458502330548224> "+getConfig()["prefix"]+"youtube\tSearches YouTube",
                    "",
                    "**Note**: This is a work in progress version, expect some bugs or unimplemented features",
                    "Version "+getConfig()["version"],
                    "Fan bot made by Spaceboy Ross (https://youtube.com/c/SpaceboyRoss)"
                ].join("\n"));
                msg.channel.send("",helpembed);
                break;
            case "lazengann-overload": msg.reply("https://www.youtube.com/watch?v=9ybOFxNKkzc");
                break;
            case "quote":
                var character = (cmd["_"][1] || randomItem(Object.keys(getConfig()["quotes"])));
                var quotes = getConfig()["quotes"][character];
                if(quotes == null) return msg.reply("There is no character called "+character+".");
                msg.reply("\""+randomItem(quotes)+"\" - "+character);
                break;
            case "r34":
                findChannel("471725747262980107").startTyping(20);
                cmd["_"].shift();
                if(cmd["_"].length == 0) cmd["_"].push("tengen_toppa_gurren_lagann");
                kaoriSearch(msg,cmd["site"] || "danbooru",cmd["_"],"e",true);
                break;
            case "restart":
                process.exit(1);
                break;
            case "settings":
                var users = dbRead("users");
                switch(cmd["_"][1] || null) {
                    case "reaction":
                        switch(cmd["_"][2] || null) {
                            case "true":
                                users[msg.author.id].settings.reaction = true;
                                msg.reply("Reactions are enabled");
                                break;
                            case "false":
                                users[msg.author.id].settings.reaction = false;
                                msg.reply("Reactions are disabled");
                                break;
                            case null:
                                users[msg.author.id].settings.reaction = !users[msg.author.id].settings.reaction;
                                if(users[msg.author.id].settings.reaction) msg.reply("Reactions are enabled");
                                else msg.reply("Reactions are disabled");
                                break;
                            default:
                                msg.reply("Setting value can be: `true` or `false`");
                                break;
                        }
                        break;
                    case null:
                    default:
                        msg.reply("Setting key can be: `reaction`");
                        break;
                }
                dbWrite("users",users);
                break;
            case "slow":
                if(getConfig()["automod"]) return msg.reply("Auto moderating is disabled, please ask Spaceboy Ross#4175 to enable it.");
                if(!userHasRole("Anti-Spirals",msg.author) && !userHasRole("Spirals",msg.author)) return msg.reply("Invalid permission");
                var slowChannels = dbRead("slowChannels") || {};
                if(typeof(slowChannels[msg.channel.name]) == "undefined") {
                    slowChannels[msg.channel.name] = {
                        lastMessage: msg.id,
                        speed: parseInt(cmd["speed"]) || getConfig()["slowSpeed"]
                    };
                    msg.reply("Slow channel mode has been enabled with a "+slowChannels[msg.channel.name].speed+" second delay.");
                } else {
                    delete slowChannels[msg.channel.name];
                    msg.reply("Slow channel mode has been disabled");
                }
                dbWrite("slowChannels",slowChannels);
                break;
            case "youtube":
                cmd["_"].shift();
                youtubeSearch(cmd["_"],{
                    key: getConfig()["youtube"]["key"],
                    maxResults: cmd["max"] || getConfig()["youtube"]["maxResults"],
                    type: "video"
                },(err,results) => {
                    if(err) return msg.reply(err.toString());

                    var result;
                    if(typeof(cmd["random"]) != "undefined") {
                        if(typeof(cmd["index"]) == "undefined" && cmd["random"]) result = randomItem(results);
                        if(typeof(cmd["index"]) == "undefined" && !cmd["random"]) result = results[0];
                    }
                    if(typeof(cmd["index"]) != "undefined") result = results[parseInt(cmd["index"])];
                    if(typeof(cmd["index"]) == "undefined" && typeof(cmd["random"]) == "undefined") {
                        for(var i = 0;i < results.length;i++) youtubeDisplay(results[i],msg.channel);
                    } else {
                        if(result == null) return msg.reply("No video was found");
                        youtubeDisplay(result,msg.channel);
                    }
                });
                break;
            default: msg.reply("Invalid command");
        }
    }
    if(dbRead("users")[msg.author.id].settings.reaction) {
        if((msg.content.toLowerCase().includes("row") && msg.content.toLowerCase().includes("fight the pow"))
            || (msg.content.toLowerCase().includes("libera me") && msg.content.toLowerCase().includes("from hel"))) {
            msg.react(msg.guild.emojis.get("471932491171758083"));
        }
        if(msg.content.toLowerCase().includes("simon")) msg.react(msg.guild.emojis.get("472091924656947200"));
        if(msg.content.toLowerCase().includes("kamina")) msg.react(msg.guild.emojis.get("471776302383366145"));
        if(msg.content.toLowerCase().includes("nia")) msg.react(msg.guild.emojis.get("472612536722915337"));
        if(msg.content.toLowerCase().includes("yoko")) msg.react(msg.guild.emojis.get("471728630108651520"));
        if(msg.content.toLowerCase().includes("anti") && msg.content.toLowerCase().includes("spiral")) msg.react(msg.guild.emojis.get("472091966339940394"));
        if(msg.content.toLowerCase().includes("watermelon")) msg.react("🍉");
    }
    if(msg.content.includes("alot") || msg.content.includes("alotta") || msg.content.includes("a lotta")) msg.reply("You spelled a lot wrong");
});

Further details:

PLASMAchicken commented 6 years ago

You are 1 Version behind You commited API Abuse by running a bot on a user account And you did not add the commit hash of the master version where u tried it Then lets not forget that this is just too much code please include something where you only use d.js to reproduce this issue or as small modules as possible

kevinbioj commented 6 years ago

⬆️ and ➡️ The issue tracker is only for bug reports and enhancement suggestions. If you have a question, please ask it in the Discord server instead of opening an issue – you will get redirected there anyway.

RossComputerGuy commented 6 years ago

Oh, wait that said user account. I misread it.

PLASMAchicken commented 6 years ago

Could u please edit the issue with easier reproduceable code and without ticking random Checkboxes / close it

RossComputerGuy commented 6 years ago

I fixed it by updating to the latest version