在 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" 方法可以做到这一点。
希望对您有所帮助,如果您有任何其他问题,请告诉我!
我无法让 /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" 方法可以做到这一点。
希望对您有所帮助,如果您有任何其他问题,请告诉我!