diff --git a/main.js b/main.js index 30f440c..a41eefd 100644 --- a/main.js +++ b/main.js @@ -56,7 +56,7 @@ client.on('interactionCreate', async interaction => { if (interaction.isButton() && interaction.component.customId == 'refresh') { await fn.refresh(interaction).catch(err => { - interaction.update(fn.builders.errorEmbed(err)); + interaction.channel.send(fn.builders.errorEmbed(err)); }); } else if (interaction.isButton() && interaction.component.customId == 'resetping') { await fn.resetPing(interaction); diff --git a/modules/dbfn.js b/modules/dbfn.js index 4f694bc..c0a54a9 100644 --- a/modules/dbfn.js +++ b/modules/dbfn.js @@ -81,7 +81,7 @@ module.exports = { if (err) throw `Error connecting to the database: ${err.message}`; }); // Get a server's tree information from the database - const selectGuildInfoQuery = `SELECT tree_name, tree_height, tree_message_id, tree_channel_id, leaderboard_message_id, leaderboard_channel_id, ping_role_id, ping_channel_id, reminded_status, reminder_optin FROM guild_info WHERE guild_id = ${db.escape(guildId)}`; + const selectGuildInfoQuery = `SELECT * FROM guild_info WHERE guild_id = ${db.escape(guildId)}`; // TODO run this query and return a promise then structure the output into a GuildInfo object. resolve with { "status": , "data": guildInfo } return new Promise((resolve, reject) => { db.query(selectGuildInfoQuery, (err, res) => { @@ -100,7 +100,8 @@ module.exports = { "leaderboardChannelId": "123", "reminderMessage": "Abc", "reminderChannelId": "123", - "remindedStatus": 0 + "remindedStatus": 0, + "comparisonMessageId": "123" };*/ if (res.length == 0) { reject("There is no database entry for your guild yet. Try running /setup"); @@ -119,7 +120,9 @@ module.exports = { "reminderMessage": row.ping_role_id, "reminderChannelId": row.ping_channel_id, "remindedStatus": row.reminded_status, - "reminderOptIn": row.reminder_optin + "reminderOptIn": row.reminder_optin, + "comparisonMessageId": row.comparison_message_id, + "comparisonChannelId": row.comparison_channel_id }; db.end(); resolve({ "status": "Successfully fetched guild information", "data": guildInfo }); @@ -401,6 +404,7 @@ module.exports = { } db.end(); resolve({ "status": `Successfully set the reminded status to ${remindedStatus}`, "data": res }); + // console.log("Boop: " + remindedStatus); }); }); }, @@ -443,7 +447,7 @@ module.exports = { if (err) throw `Error connecting to the database: ${err.message}`; }); // Get a server's tree information from the database - const getOptedInGuildsQuery = `SELECT guild_id, tree_name, tree_height, tree_message_id, tree_channel_id, leaderboard_message_id, leaderboard_channel_id, ping_role_id, ping_channel_id, reminded_status FROM guild_info WHERE reminder_optin = 1 AND reminded_status = 0`; + const getOptedInGuildsQuery = `SELECT * FROM guild_info WHERE reminder_optin = 1`; // TODO run this query and return a promise then structure the output into a GuildInfo object. resolve with { "status": , "data": guildInfo } return new Promise((resolve, reject) => { db.query(getOptedInGuildsQuery, (err, res) => { @@ -462,7 +466,8 @@ module.exports = { "leaderboardChannelId": "123", "reminderMessage": "Abc", "reminderChannelId": "123", - "remindedStatus": 0 + "remindedStatus": 0, + "comparisonMessageId": "123" };*/ if (res.length == 0) { resolve({ "status": "No servers have opted in yet" }); @@ -482,7 +487,9 @@ module.exports = { "leaderboardChannelId": row.leaderboard_channel_id, "reminderMessage": row.ping_role_id, "reminderChannelId": row.ping_channel_id, - "remindedStatus": row.reminded_status + "remindedStatus": row.reminded_status, + "comparisonMessageId": row.comparison_message_id, + "comparisonChannelId": row.comparison_channel_id }); }); db.end(); @@ -490,7 +497,7 @@ module.exports = { }); }); }, - setComparisonMessage(comparisonMessageId, guildId) { + setComparisonMessage(comparisonMessage, guildId) { const db = mysql.createConnection({ host: process.env.DBHOST, user: process.env.DBUSER, @@ -502,10 +509,11 @@ module.exports = { if (err) throw `Error connecting to the database: ${err.message}`; }); // Returns a Promise, resolve({ "status": "", "data": leaderboard }) - const setRemindedStatusQuery = `UPDATE guild_info SET comparison_message_id = ${db.escape(comparisonMessageId)} WHERE guild_id = ${db.escape(guildId)}`; + const setComparisonMessageQuery = `UPDATE guild_info SET comparison_message_id = ${db.escape(comparisonMessage.id)}, comparison_channel_id = ${db.escape(comparisonMessage.interaction.channelId)} WHERE guild_id = ${db.escape(guildId)}`; + // console.log(JSON.stringify(comparisonMessage)); // TODO run the query and return a promise then process the results. resolve with { "status": , "data": leaderboard } return new Promise((resolve, reject) => { - db.query(setRemindedStatusQuery, (err, res) => { + db.query(setComparisonMessageQuery, (err, res) => { if (err) { console.error(err); db.end(); @@ -513,7 +521,7 @@ module.exports = { return; } db.end(); - resolve({ "status": `Successfully set the comparison message ID: ${comparisonMessageId}`, "data": res }); + resolve({ "status": `Successfully set the comparison message ID: ${comparisonMessage}`, "data": res }); }); }); } diff --git a/modules/functions.js b/modules/functions.js index 847ebe7..833337e 100644 --- a/modules/functions.js +++ b/modules/functions.js @@ -539,8 +539,8 @@ const functions = { const { guildId, reminderChannelId, reminderMessage } = guildInfo; const reminderChannel = await guild.channels.fetch(reminderChannelId); const reminderEmbed = functions.builders.reminderEmbed(reminderMessage, guildInfo); - reminderChannel.send(reminderEmbed).then(async m => { - await dbfn.setRemindedStatus(guildId, 1); + await reminderChannel.send(reminderEmbed).then(async m => { + const setRemindedStatusReponse = await dbfn.setRemindedStatus(guildId, 1); return 1; }).catch(err => { console.error(err); @@ -550,51 +550,68 @@ const functions = { setTimeout(this.sendReminder(interaction), ms); }, async checkReady(client) { // Check if the guilds trees are ready to water - // TODO This is hard coded for the dev server, need to change it to lookup each server and iterate over them - // Would also be helpful to have an opt-in or opt-out ability for water checks try { + // Get the guildInfos for each guild that is opted in and waiting to send a reminder const getOptedInGuildsResponse = await dbfn.getOptedInGuilds(); - // console.log(JSON.stringify(getOptedInGuildsResponse)); + // getOptedInGuilds will return this if it gets an empty set from the database if (getOptedInGuildsResponse.status != "No servers have opted in yet") { + // Get the Array of Guilds from the response const guilds = getOptedInGuildsResponse.data; + // Iterate over the Array for (let i = 0; i < guilds.length; i++) { + // console.log(`iter: ${i}`); + // Save the 'old' guild info that came from getOptedInGuilds const oldGuildInfo = guilds[i]; + // Get up-to-date guildInfo from the database, probably unnecessary and redundant const getGuildInfoResponse = await dbfn.getGuildInfo(oldGuildInfo.guildId); + // Save the new guildInfo so we can reference its remindedStatus const guildInfo = getGuildInfoResponse.data; const { guildId, treeChannelId, treeMessageId, remindedStatus } = guildInfo; - + // console.log(`${guildInfo.treeName}: ${remindedStatus}`); + // Double check the remindedStatus to prevent double pings if (remindedStatus == 0) { + // Fetch the guild const guild = await client.guilds.fetch(guildId); + // Fetch the tree channel const treeChannel = await guild.channels.fetch(treeChannelId); + // Fetch the tree message const treeMessage = await treeChannel.messages.fetch(treeMessageId); + // Get the description from the embed of the tree message const description = treeMessage.embeds[0].description; + // Default to not being ready to water let readyToWater = false; + // Obviously if the tree says it's Ready to be watered, it's ready if (description.includes("Ready to be watered")) { readyToWater = true; + // But sometimes the tree doesn't refresh the embed, in that case we'll do a secondary check using the + // timestamp included in the embed. } else { const beginWaterTimestamp = description.indexOf(""); + // Split the description starting at "" to get just the numerical timestamp const waterTimestamp = parseInt(description.slice(beginWaterTimestamp, endWaterTimestamp)); + // The Discord timestamp is in seconds, not ms so we need to divide by 1000 const nowTimestamp = (Date.now() / 1000); readyToWater = (nowTimestamp > waterTimestamp); } if (readyToWater) { - // console.log("Ready to water"); + // Send the reminder message await this.sendReminder(guildInfo, guild); - this.sleep(5000).then(async () => { - await this.checkReady(client); - }); - return; - } else { - // console.log("Not ready to water\n" + `Water At: ${waterTimestamp} | Now: ${nowTimestamp}`); - this.sleep(5000).then(async () => { - await this.checkReady(client); - }); - return; } + } else { + // const guild = await client.guilds.fetch(guildInfo.guildId); + // const comparisonChannel = await guild.channels.fetch(guildInfo.comparisonChannelId); + // const comparisonMessage = await comparisonChannel.messages.fetch(guildInfo.comparisonMessageId); + // const embed = comparisonMessage.embeds[0]; + // const actionRow = this.builders.actionRows.comparisonActionRow(guildInfo); + // comparisonMessage.edit({ embeds: [embed], components: [actionRow] }); } } + // Wait for .5 seconds before looping back to check other trees + this.sleep(500).then(async () => { + await this.checkReady(client); + }); } else { // console.log(getOptedInGuildsResponse.status); this.sleep(5000).then(async () => {