在 Discord 的子文件中要求机器人时遇到问题

Having trouble requiring the bot in a sub file in Discord

我无法让 /cmd/ 中的文件从我的 index.js 中读取正确的函数。我知道我需要在 index.js 中以某种方式使用 module.exports,但我不太确定它的语法。本质上,我希望能够使用在 profile.js 中发送命令的用户的头像和用户名,但是我需要为此要求 Discord.Client,我只是不确定如何这样做。提前致谢。

未捕获的承诺错误: 类型错误:无法读取未定义的 属性 'msg' 在 sql.get.then.row (/home/kosaki/kosaki/cmd/profile.js:13:18) 在

index.js

const chalk = require("chalk");
const config = require("./config.json")
const Discord = require("discord.js");
const express = require("express");
const cheerio = require("cheerio")
const request = require("request")
const sql = require("sqlite");
    sql.open("./scores.sqlite");


const fs = require('fs');
const path = require('path');

// Create saki.
const saki = new Discord.Client();
if (!fs.existsSync(path.join(__dirname, 'config.json'))) {
    saki.err(t + "config.json not found!")
    process.exit()
}

saki.on('ready', () => {
    saki.config = config
    saki.log("Loading modules...")
    saki.commandInit()
    //saki.commandInit()
    saki.user.setAFK(true)
    saki.log(`Logged in as ${saki.user.tag}!`);
});

saki.on('message', (msg) => {

    // Kosaki scores. --------------------------------------------- //

    sql.get(`SELECT * FROM scores WHERE userId ="${msg.author.id}"`).then(row => {
        if (!row) {
            sql.run("INSERT INTO scores (userId, points, level) VALUES (?, ?, ?)", [msg.author.id, 1, 0]);
        } else {
            sql.run(`UPDATE scores SET points = ${row.points + 1} WHERE userId = ${msg.author.id}`);
        }
    }).catch(() => {
        console.error;
        sql.run("CREATE TABLE IF NOT EXISTS scores (userId TEXT, points INTEGER, level INTEGER)").then(() => {
            sql.run("INSERT INTO scores (userId, points, level) VALUES (?, ?, ?)", [msg.author.id, 1, 0]);
        });
    });

    // Kosaki scores. --------------------------------------------- //

    // Ignore if the message doesn't start with our prefix
    if (!msg.content.startsWith(config.prefix)) return

    // Ignore if empty command
    if (msg.content.length === config.prefix.length) return

    // Get all the arguments
    let tmp = msg.content.substring(config.prefix.length, msg.length).split(' ')
    let args = []

    for (let i = 1; i < tmp.length; i++) {
        args.push(tmp[i])
    }

    // Store the command separately
    let cmd = tmp[0]

    if (saki.modules.hasOwnProperty(cmd)) return saki.modules[cmd].run(msg, args)
    //if (config.commandError.sendToModule === true) {
    //return saki.modules[config.commandError.module][config.commandError.function](msg, cmd)
    //}

    return msg.delete()
})

saki.on('disconnect', () => {
    saki.err('Client Kosaki disconnected!')
    process.exit()
})

saki.on('reconnecting', () => {
    saki.log('Client Kosaki reconnecting...', 'done.')
})

saki.log = function(msg) {
    console.log(chalk.green(`[saki] `) + `${msg}`)
}

saki.err = function(msg) {
    console.log(chalk.red(`[saki] `) + `${msg}`)
}

saki.commandInit = function() {
    saki.modules = {}

    // Load up all the modules
    fs.readdirSync('./cmd/').forEach((file) => {
        let name = file.slice(0, -3)

        delete require.cache[require.resolve(`./cmd/${file}`)]

        try {
            saki.modules[name] = require(`./cmd/${file}`)
            if (saki.modules[name].hasOwnProperty('init')) {
                saki.modules[name].init(saki)
            }

            saki.log(`Module '${name}' is ready.`)
        } catch (e) {
            saki.err(`Error in module '${name}':\n${e.stack}`)
        }
    })
}

saki.edit = function(msg, content, timeout = 5000) {
    if (timeout === 0) return msg.edit(content).catch(console.error)

    return msg.edit(content).then(() => {
        setTimeout(() => msg.delete().catch(console.error), timeout)
    })
}

saki.log("Kosaki initialized. Created by vex.")

saki.login(config.token);

process.on('unhandledRejection', err => {
    saki.err(`Uncaught Promise Error:\n${err.stack}`)
})

cmd/profile.js

module.exports.desc = "Shows your profile on the Kosaki leveling system.";

const sql = require("sqlite")
const kosaki = require("./../index.js")

exports.run = function(msg) {

sql.get(`SELECT * FROM scores WHERE userId ="${msg.author.id}"`).then(row => {

msg.channel.send({embed: {
    color: 3447003,
    author: {
      name: kosaki.saki.msg.user.username,
      icon_url: kosaki.saki.msg.user.avatarURL
    },
    title: "Kosaki Profile",
    description: "Your profile on Kosaki.",
    fields: [{
        name: "Points",
        value: `${row.points}`
      },
      {
        name: "Level",
        value: `${row.level}`
      },
      {
        name: "Markdown",
        value: "You can put all the *usual* **__Markdown__** inside of them."
      }
    ],
    timestamp: new Date(),
    footer: {
      icon_url: kosaki.saki.msg.user.avatarURL,
      text: "© Example"
    }
  }
});

});

}

我建议您不要使用 module.exports,因为当您需要 index.js 时,您会再次 运行 它。

您可以设置一个全局变量,这样当index.js 需要profile.js 文件时,它可以使用先前在第一个文件中声明的所有变量。为此,您必须将要使用的变量存储在 global 对象中:例如,如果您想与所有其他文件共享客户端,请设置 global.your_var_name = client。然后,在另一个文件中,您可以键入 your_var_name,就像在您的文件中声明的那样。

//index.js
global.client = saki;

//cmd/profile.js
client.blablabla...

我已经使用这种方法一段时间了,我发现它非常有用,即使有人会告诉你不应该这样做,而且还有更多 "right" 方法可以做到这一点。

希望对您有所帮助,如果您有任何其他问题,请告诉我!