#javascript #node.js #json #discord.js
Вопрос:
Всякий раз , когда кто-то отправляет !setmainchannel
, моя программа выходит из строя. Я использую Node.js вместе с пакетом discord.js. Это единственная проблема, которая у меня есть. Я не понимаю и не могу понять, в чем дело, и я был бы чрезвычайно признателен, если бы кто-нибудь мог мне помочь.
bot.js
:
let Discord = require("discord.js");
let client = new Discord.Client();
let fs = require('fs');
let help = require("./helpembed.json");
var jsonRead = function(filePath){
fs.readFile(filePath, 'utf-8', (err, returnJson) => {
if(err){
console.log(err);
}
else{
let ret = JSON.parse(returnJson);
return ret;
}
})
}
var jsonWrite = function(filePath, objIn){
fs.writeFile(filePath, JSON.stringify(objIn), err => {
if(err){
console.log(err);
}
})
}
client.on("message", msg => {
let time = new Date();
let cstTimeStamp = `${time.getMonth() 1}/${time.getDate()}/${time.getFullYear()} ${time.getHours() 1}:${time.getMinutes()}:${time.getSeconds()}`
if(msg.content == "!setmainchannel"){
let mainChannel = msg.mentions.channels.first();
if(!mainChannel){
console.log(`${cstTimeStamp} @${msg.author.tag} requested to set a main channel but didn't provide a channeln`);
msg.channel.send("There's no channel to set the main to");
}
else{
let currentSettings = jsonRead("./main-channel.json");
currentSettings.channel = mainChannel;
jsonWrite("./main-channel.json", currentSettings);
console.log(`${cstTimeStamp} @${msg.author.tag} set the main channel as ${currentSettings.channel}n`);
msg.channel.send(`Set the main channel as ${currentSettings.channel}`);
}
}
})
client.once('ready', () => {
console.log('Bot is onlinen');
});
client.login('Token hidden for safety reasons');
main-channel.json
:
{
"channel":null
}
Комментарии:
1. Какие-нибудь сообщения об ошибках?
2. @SuperStormer Сообщений об ошибках не возникает, но теперь я понял, что программа просто ничего не делает и продолжает принимать любые другие команды
Ответ №1:
Во-первых, ваш бот ничего не делает, потому что он только реагирует if (msg.content == "!setmainchannel")
. Если вы предоставите аргумент, например channel ( !setmainchannel #ch-name
), он не будет запущен, поскольку содержимое сообщения не является префиксом и командой.
Сначала тебе нужно это исправить. Удалив префикс и отключив аргументы, вы можете получить саму команду и проверить, используется ли именно эта команда. (Опять же, вы не должны проверять все целиком message.content
)
Во-вторых, вы не ждете, пока запустится обратный вызов внутри readFile
. Это означает, что при попытке обновления currentSettings.channel
ваша jsonRead()
функция только что начала считывать файл и currentSettings
это undefined
. Вы не сможете обновить его channel
свойство.
Я обновил ваши jsonWrite
функции и jsonRead
функции, чтобы вернуть обещания и упростить их использование. Проверьте рабочий код ниже:
const Discord = require("discord.js");
const fs = require('fs');
const path = require('path');
const client = new Discord.Client();
const prefix = '!';
client.on('message', async (msg) => {
// create an args variable that slices off the prefix and splits it into an array
const args = msg.content.slice(prefix.length).split(/ /);
// create a command variable by taking the first element in the array
// and removing it from args
const command = args.shift().toLowerCase();
const cstTimeStamp = new Date().toLocaleString();
if (command === 'setmainchannel') {
const mainChannel = msg.mentions.channels.first();
const filePath = path.resolve(__dirname, './main-channel.json');
if (!mainChannel) {
console.log(`${cstTimeStamp} ${msg.author.tag} requested to set a main channel but didn't provide a channeln`);
return msg.channel.send("There's no channel to set the main to");
}
try {
const currentSettings = await jsonRead(filePath);
currentSettings.channel = mainChannel;
jsonWrite(filePath, currentSettings);
console.log(`${cstTimeStamp} ${msg.author.tag} set the main channel as ${currentSettings.channel}n`);
msg.channel.send(`Set the main channel as ${currentSettings.channel}`);
} catch (err) {
console.log(err);
}
}
});
client.once('ready', () => {
console.log('Bot is onlinen');
});
client.login('Token hidden for safety reasons');
function jsonRead(filePath) {
return new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf-8', (err, content) => {
if (err) {
reject(err);
} else {
try {
const parsedContent = JSON.parse(content);
resolve(parsedContent);
} catch (err) {
reject(err);
}
}
});
});
}
function jsonWrite(filePath, data) {
return new Promise((resolve, reject) => {
fs.writeFile(filePath, JSON.stringify(data), (err) => {
if (err) {
reject(err);
}
resolve(true);
});
});
}
Ответ №2:
Ладно, я понимаю, что здесь происходит. Я заставил логику реагировать ТОЛЬКО !setmainchannel
на ЭТО , в то время как я должен был это сделать if(msg.content.startsWith("!setmainchannel")
!
Комментарии:
1. Нет, это не единственная ошибка. Изменение только этого не решит проблему, и это все равно приведет к ошибке типа. Смотрите мой ответ для получения более подробной информации.