У меня есть дискорд-бот, который я создал и развернул в Heroku с помощью discord. js
Вы можете получить доступ ко всему моему проекту в моей учетной записи bitbucket здесь: https://bitbucket.org/hb33green/carol/src/master/
Я могу отлично запустить бота, он входит в разногласия и имеет базовую c функциональность без сообщений об ошибках (что делает его таким сложным для понимания). Однако бот теряет функциональность, когда я запускаю его через героку. Эта проблема возникает в двух местах в моем коде:
Один раз в моем ol_roll. js file
sent.awaitReactions((reaction, user) => { return (reaction.emoji.name === roll || reaction.emoji.name === cancel) && user.id === msg.author.id; },
{ max: 1, time: responseTime, errors: ["time"] })
.then(collected => {
if (collected.firstKey() == roll) {
var hasData = false;
var hasSessionData = false;
for (i = 0; i < sessionLucky.users.length; i++) {
if (sessionLucky.users[i].hasOwnProperty(msg.author.id)) {
hasSessionData = true;
}
}
for (i = 0; i < lucky.users.length; i++) {
if (lucky.users[i].hasOwnProperty(msg.author.id)) {
hasData = true;
}
}
var result = roller.roller(sidesOfDice, numOfDice, keepsOfDice, keepBefore, vicious, modifier);
finalSum = result[result.length - 1];
var temp = "";
for (i = 0; i < sidesOfDice.length; i++) {
temp += "d" + sidesOfDice[i].toString() + ":[";
for (j = 0; j < numOfDice[i]; j++) {
if (result[0] > sidesOfDice[i]) {
temp += result[0] + " (";
while (result[0] > sidesOfDice[i]) {
temp += sidesOfDice[i] + " + ";
result[0] -= sidesOfDice[i];
}
temp += result[0] + "), "
} else {
temp += result[0] + ", ";
}
result.splice(0, 1);
}
temp = temp.substring(0, temp.length - 2);
temp += "] ";
}
if (!hasData) {
var newObj = {
[msg.author.id]: {
"success percent": 0,
"success count": 0,
"failure percent": 0,
"failure count": 0
}
}
lucky.users.push(newObj);
}
if (!hasSessionData) {
var newObj = {
[msg.author.id]: {
"success percent": 0,
"success count": 0,
"failure percent": 0,
"failure count": 0
}
}
sessionLucky.users.push(newObj);
}
var outcomeString = "";
if (finalSum >= cr) {
outcomeString = "Success!";
for (i = 0; i < sessionLucky.users.length; i++) {
if (sessionLucky.users[i].hasOwnProperty(msg.author.id)) {
sessionLucky.users[i][msg.author.id]["success percent"] += results[1];
sessionLucky.users[i][msg.author.id]["success count"] += 1;
break;
}
}
for (i = 0; i < lucky.users.length; i++) {
if (lucky.users[i].hasOwnProperty(msg.author.id)) {
lucky.users[i][msg.author.id]["success percent"] += results[1];
lucky.users[i][msg.author.id]["success count"] += 1;
break;
}
}
} else {
outcomeString = "Failure...";
for (i = 0; i < sessionLucky.users.length; i++) {
if (sessionLucky.users[i].hasOwnProperty(msg.author.id)) {
sessionLucky.users[i][msg.author.id]["failure percent"] += results[1];
sessionLucky.users[i][msg.author.id]["failure count"] += 1;
break;
}
}
for (i = 0; i < lucky.users.length; i++) {
if (lucky.users[i].hasOwnProperty(msg.author.id)) {
lucky.users[i][msg.author.id]["failure percent"] += results[1];
lucky.users[i][msg.author.id]["failure count"] += 1;
break;
}
}
}
let backToRawSession = JSON.stringify(sessionLucky, null, 2);
let backToRaw = JSON.stringify(lucky, null, 2);
fs.writeFileSync("./session_luck.json", backToRawSession);
fs.writeFileSync("./luck.json", backToRaw);
post = new Date();
post = post.getTime() / 1000;
const embedCont = new Discord.RichEmbed()
.setColor("DARK_GREEN")
.setAuthor("Open Legend Roller")
.setTitle(`${outcomeString} ${finalSum}`)
.setDescription(`Dice: ${temp}`)
.addField("Success Rate", `${results[1]}%`, true)
.addField("Failure Rate", `${results[0]}%`, true)
.addField("Challenge Rating", `${cr}`, true)
.addField("Level", `${lvl}`, true)
.setFooter(`Requested by ${msg.author.username} | Response Time ≈ ${(post - pre).toFixed(2)} seconds.`, `${msg.author.displayAvatarURL}`)
.setTimestamp();
if (adv > 0) {
embedCont.addField("Advantage", `${adv}`, true);
} else if (adv < 0) {
embedCont.addField("Disadvantage", `${Math.abs(adv)}`, true);
}
if (lp != 0) {
embedCont.addField("Legend Points", `${lp}`, true);
}
embedCont.addField("Other Parameters", `Vicious: ${vicious}\nKeep Before: ${keepBefore}`, true);
msg.channel.send(embedCont).then(() => {
sent.delete();
});
} else if (collected.firstKey() == cancel) {
sent.delete();
msg.react(cancel);
}
})
.catch(() => {
post = new Date();
post = post.getTime() / 1000;
const embedTimeOut = new Discord.RichEmbed()
.setColor("DARK_GREEN")
.setAuthor("Open Legend Roller")
.setDescription(`In order to save on resources a dice roll auto-cancelled after ${Math.round(responseTime / 1000)} seconds.`)
.setFooter(`Requested by ${msg.author.username} | Response Time ≈ ${(post - pre).toFixed(2)} seconds.`, `${msg.author.displayAvatarURL}`)
.setTimestamp();
msg.channel.send(embedTimeOut).then(() => {
sent.delete();
});
});
});
И снова в моем списке. js file
sent.awaitReactions((reaction, user) => { return (reaction.emoji.name === roll || reaction.emoji.name === cancel) && user.id === msg.author.id; },
{ max: 1, time: responseTime, errors: ["time"] })
.then(collected => {
if (collected.firstKey() == roll) {
var hasData = false;
var hasSessionData = false;
for (i = 0; i < sessionLucky.users.length; i++) {
if (sessionLucky.users[i].hasOwnProperty(msg.author.id)) {
hasSessionData = true;
}
}
for (i = 0; i < lucky.users.length; i++) {
if (lucky.users[i].hasOwnProperty(msg.author.id)) {
hasData = true;
}
}
var result = roller.roller(sidesOfDice, numOfDice, keepsOfDice, keepBefore, vicious, modifier);
finalSum = result[result.length - 1];
var temp = "";
for (i = 0; i < sidesOfDice.length; i++) {
temp += "d" + sidesOfDice[i].toString() + ":[";
for (j = 0; j < numOfDice[i]; j++) {
if (result[0] > sidesOfDice[i]) {
temp += result[0] + " (";
while (result[0] > sidesOfDice[i]) {
temp += sidesOfDice[i] + " + ";
result[0] -= sidesOfDice[i];
}
temp += result[0] + "), "
} else {
temp += result[0] + ", ";
}
result.splice(0, 1);
}
temp = temp.substring(0, temp.length - 2);
temp += "] ";
}
if (!hasData) {
var newObj = {
[msg.author.id]: {
"success percent": 0,
"success count": 0,
"failure percent": 0,
"failure count": 0
}
}
lucky.users.push(newObj);
}
if (!hasSessionData) {
var newObj = {
[msg.author.id]: {
"success percent": 0,
"success count": 0,
"failure percent": 0,
"failure count": 0
}
}
sessionLucky.users.push(newObj);
}
var outcomeString = "";
if (finalSum >= cr) {
outcomeString = "Success!";
for (i = 0; i < sessionLucky.users.length; i++) {
if (sessionLucky.users[i].hasOwnProperty(msg.author.id)) {
sessionLucky.users[i][msg.author.id]["success percent"] += results[1];
sessionLucky.users[i][msg.author.id]["success count"] += 1;
break;
}
}
for (i = 0; i < lucky.users.length; i++) {
if (lucky.users[i].hasOwnProperty(msg.author.id)) {
lucky.users[i][msg.author.id]["success percent"] += results[1];
lucky.users[i][msg.author.id]["success count"] += 1;
break;
}
}
} else {
outcomeString = "Failure...";
for (i = 0; i < sessionLucky.users.length; i++) {
if (sessionLucky.users[i].hasOwnProperty(msg.author.id)) {
sessionLucky.users[i][msg.author.id]["failure percent"] += results[1];
sessionLucky.users[i][msg.author.id]["failure count"] += 1;
break;
}
}
for (i = 0; i < lucky.users.length; i++) {
if (lucky.users[i].hasOwnProperty(msg.author.id)) {
lucky.users[i][msg.author.id]["failure percent"] += results[1];
lucky.users[i][msg.author.id]["failure count"] += 1;
break;
}
}
}
let backToRawSession = JSON.stringify(sessionLucky, null, 2);
let backToRaw = JSON.stringify(lucky, null, 2);
fs.writeFileSync("./session_luck.json", backToRawSession);
fs.writeFileSync("./luck.json", backToRaw);
post = new Date();
post = post.getTime() / 1000;
const embedCont = new Discord.RichEmbed()
.setColor("DARK_BLUE")
.setAuthor("Regular Roller")
.setTitle(`${outcomeString} ${finalSum}`)
.setDescription(`Dice: ${temp}`)
.addField("Success Rate", `${results[1]}%`, true)
.addField("Failure Rate", `${results[0]}%`, true)
.addField("Challenge Rating", `${cr}`, true)
.setFooter(`Requested by ${msg.author.username} | Response Time ≈ ${(post - pre).toFixed(2)} seconds.`, `${msg.author.displayAvatarURL}`)
.setTimestamp()
.addField("Other Parameters", `Vicious: ${vicious}\nKeep Before: ${keepBefore}`, true);
msg.channel.send(embedCont).then(() => {
sent.delete();
});
} else if (collected.firstKey() == cancel) {
sent.delete();
msg.react(cancel);
}
})
.catch(() => {
post = new Date();
post = post.getTime() / 1000;
const embedTimeOut = new Discord.RichEmbed()
.setColor("DARK_GREEN")
.setAuthor("Open Legend Roller")
.setDescription(`In order to save on resources a dice roll auto-cancelled after ${Math.round(responseTime / 1000)} seconds.`)
.setFooter(`Requested by ${msg.author.username} | Response Time ≈ ${(post - pre).toFixed(2)} seconds.`, `${msg.author.displayAvatarURL}`)
.setTimestamp();
msg.channel.send(embedTimeOut).then(() => {
sent.delete();
});
});
});
Выше приведены только крошечные куски, но здесь есть проблемы. (Опять же, если вы хотите увидеть все это в контексте, вы можете увидеть все в хранилище битбакетов здесь: https://bitbucket.org/hb33green/carol/src/master/)
В основном происходит отправка rich-embed и хранится в переменной с именем 'sent'. Затем бот ожидает, что произойдет одна из трех вещей:
1) Пользователь также реагирует с помощью смайликов с большими пальцами вверх (сохраненных извне в переменной, называемой «roll»), и в этом случае бот отвечает вычисление нового броска.
2) Пользователь также реагирует большим пальцем вниз, и исходное сообщение удаляется, а бот запроса пользователя реагирует ботом большими пальцами вниз (снова сохраняется внешне в переменной с именем ' cancel ').
3) Пользователь не отвечает в течение заданного количества миллисекунд, и исходный ответ удаляется, и отправляется новое сообщение о том, что оно было удалено из-за неактивности (число миллисекунд равно , как вы уже догадались, хранятся извне и на них может ссылаться переменная responseTime).
Однако ничего из этого не происходит. Сообщение, которое сохраняется в 'sent', отправляется правильно, но бот никогда не будет ничего делать после этого. Он не выполняет предназначенную функцию и не отправляет сообщения об ошибках в журналы после того, как пользователь отреагирует или истечет время. Я не могу понять, в чем проблема.
Все остальное в боте работает отлично, кроме метода awaitReactions (). И я чувствую, что это может быть проблемой с тем, как я развернул его на heroku, учитывая, что точно такой же код прекрасно работает, если я разверну его на своей машине.
Заранее спасибо!