Classes, Collections, and new Notification Relay
This commit is contained in:
		
							parent
							
								
									54fd78659e
								
							
						
					
					
						commit
						a757b988b0
					
				| @ -44,5 +44,9 @@ | ||||
| 		"missingTreeMessage": "There was a problem finding the Tree message. Please make sure the ``/tree`` and ``/top trees`` messages are this channel, or run </setup:1065407649363005561> to set the ``/tree`` and ``/top trees`` channels.", | ||||
| 		"missingTreeChannel": "There was a problem finding the Tree channel, was it deleted? Please make sure the ``/tree`` and ``/top trees`` messages are in this channel, or run </setup:1065407649363005561> to set the ``/tree`` and ``/top trees`` channels." | ||||
| 	}, | ||||
| 	"notifications": { | ||||
| 		"water": "is ready to be watered again!", | ||||
| 		"fruit": "Fruit is appearing!" | ||||
| 	}, | ||||
| 	"temp": {} | ||||
| } | ||||
							
								
								
									
										17
									
								
								main.js
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								main.js
									
									
									
									
									
								
							| @ -27,11 +27,12 @@ const strings = require('./data/strings.json'); | ||||
| const dbfn = require('./modules/dbfn.js'); | ||||
| const isDev = process.env.isDev; | ||||
| 
 | ||||
| client.once('ready', () => { | ||||
| 	fn.collections.slashCommands(client); | ||||
| client.once('ready', async () => { | ||||
| 	await fn.collectionBuilders.slashCommands(client); | ||||
| 	await fn.collectionBuilders.guildInfos(client); | ||||
| 	await fn.setupCollectors(client); | ||||
| 	console.log('Ready!'); | ||||
| 	client.user.setActivity({ name: strings.activity.name, type: ActivityType.Watching }); | ||||
| 	fn.checkReady(client); | ||||
| 	if (isDev == 'false') { | ||||
| 		client.channels.fetch(statusChannelId).then(channel => { | ||||
| 			channel.send(`${new Date().toISOString()} -- \nStartup Sequence Complete <@481933290912350209>`); | ||||
| @ -60,18 +61,8 @@ client.on('interactionCreate', async interaction => { | ||||
| 		await fn.refresh(interaction).catch(err => { | ||||
| 			interaction.channel.send(fn.builders.errorEmbed(err)); | ||||
| 		}); | ||||
| 	} else if (interaction.isButton() && interaction.component.customId == 'resetping') { | ||||
| 		await fn.resetPing(interaction); | ||||
| 		await fn.refresh(interaction).catch(err => { | ||||
| 			interaction.channel.send(fn.builders.errorEmbed(err)); | ||||
| 		}); | ||||
| 	} else if (interaction.isButton() && interaction.component.customId == 'deleteping') { | ||||
| 		if (interaction.message.deletable) { | ||||
| 			await dbfn.setRemindedStatus(interaction.guildId, 0); | ||||
| 			await dbfn.getGuildInfo(interaction.guildId).then(async res => { | ||||
| 				const guildInfo = res.data; | ||||
| 				await fn.refreshComparisonMessage(interaction.client, guildInfo); | ||||
| 			}); | ||||
| 			await interaction.message.delete().catch(err => { | ||||
| 				console.error(err); | ||||
| 			}); | ||||
|  | ||||
							
								
								
									
										127
									
								
								modules/CustomClasses.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								modules/CustomClasses.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,127 @@ | ||||
| const mysql = require('mysql'); | ||||
| const db = mysql.createConnection({ | ||||
|     host: process.env.DBHOST, | ||||
|     user: process.env.DBUSER, | ||||
|     password: process.env.DBPASS, | ||||
|     database: process.env.DBNAME, | ||||
|     port: process.env.DBPORT | ||||
| }); | ||||
| 
 | ||||
| module.exports = { | ||||
|     GuildInfo: class { | ||||
|         constructor() { | ||||
|             this.guildId = ""; | ||||
|             this.treeName = ""; | ||||
|             this.treeHeight = 0; | ||||
|             this.treeMessageId = ""; | ||||
|             this.treeChannelId = ""; | ||||
|             this.leaderboardMessageId = ""; | ||||
|             this.leaderboardChannelId = ""; | ||||
|             this.waterMessage = ""; | ||||
|             this.fruitMessage = ""; | ||||
|             this.reminderChannelId = ""; | ||||
|             this.watchChannelId = ""; | ||||
|         } | ||||
|      | ||||
|         setId(id) { | ||||
|             this.guildId = id; | ||||
|             return this; | ||||
|         } | ||||
|         setName(name) { | ||||
|             this.treeName = name; | ||||
|             return this; | ||||
|         } | ||||
|         setHeight(height) { | ||||
|             this.treeHeight = height; | ||||
|             return this; | ||||
|         } | ||||
|         setTreeMessage(messageId, channelId) { | ||||
|             this.treeMessageId = messageId; | ||||
|             this.treeChannelId = channelId; | ||||
|             return this; | ||||
|         } | ||||
|         setLeaderboardMessage(messageId, channelId) { | ||||
|             this.leaderboardMessageId = messageId; | ||||
|             this.leaderboardChannelId = channelId; | ||||
|             return this; | ||||
|         } | ||||
|         setReminders(waterMessage, fruitMessage, reminderChannelId, watchChannelId) { | ||||
|             this.waterMessage = waterMessage; | ||||
|             this.fruitMessage = fruitMessage; | ||||
|             this.reminderChannelId = reminderChannelId; | ||||
|             this.watchChannelId = watchChannelId; | ||||
|             return this; | ||||
|         } | ||||
|         queryBuilder(query) { | ||||
|             let queryParts = []; | ||||
|             switch (query) { | ||||
|                 case "setAll": | ||||
|                     queryParts = [ | ||||
|                         `INSERT INTO guild_info `, | ||||
|                         `(guild_id, `, | ||||
|                         `tree_name, `, | ||||
|                         `tree_height, `, | ||||
|                         `tree_message_id, `, | ||||
|                         `tree_channel_id, `, | ||||
|                         `leaderboard_message_id, `, | ||||
|                         `leaderboard_channel_id, `, | ||||
|                         `water_message, `, | ||||
|                         `fruit_message, `, | ||||
|                         `reminder_channel_id, `, | ||||
|                         `watch_channel_id) `, | ||||
|                         `VALUES (${db.escape(this.guildId)}, `, | ||||
|                         `${db.escape(this.treeName)}, `, | ||||
|                         `${db.escape(this.treeHeight)}, `, | ||||
|                         `${db.escape(this.treeMessageId)}, `, | ||||
|                         `${db.escape(this.treeChannelId)}, `, | ||||
|                         `${db.escape(this.leaderboardMessageId)}, `, | ||||
|                         `${db.escape(this.leaderboardChannelId)}, `, | ||||
|                         `${db.escape(this.waterMessage)}, `, | ||||
|                         `${db.escape(this.fruitMessage)}, `, | ||||
|                         `${db.escape(this.reminderChannelId)}, `, | ||||
|                         `${db.escape(this.watchChannelId)}) `, | ||||
|                         `ON DUPLICATE KEY UPDATE tree_name = ${db.escape(this.treeName)}, `, | ||||
|                         `tree_height = ${db.escape(this.treeHeight)}, `, | ||||
|                         `tree_message_id = ${db.escape(this.treeMessageId)}, `, | ||||
|                         `tree_channel_id = ${db.escape(this.treeChannelId)}, `, | ||||
|                         `leaderboard_message_id = ${db.escape(this.leaderboardMessageId)}, `, | ||||
|                         `leaderboard_channel_id = ${db.escape(this.leaderboardChannelId)}, `, | ||||
|                         `water_message = ${db.escape(this.waterMessage)}, `, | ||||
|                         `fruit_message = ${db.escape(this.fruitMessage)}, `, | ||||
|                         `reminder_channel_id = ${db.escape(this.reminderChannelId)}, `, | ||||
|                         `watch_channel_id = ${db.escape(this.watchChannelId)})` | ||||
|                     ]; | ||||
|                     return queryParts.join(''); | ||||
|                     break; | ||||
|                 case "setReminders": | ||||
|                     queryParts = [ | ||||
|                         `UPDATE guild_info SET water_message = ${db.escape(this.waterMessage)}, `, | ||||
|                         `fruit_message = ${db.escape(this.fruitMessage)}, `, | ||||
|                         `reminder_channel_id = ${db.escape(this.reminderChannelId)}, `, | ||||
|                         `watch_channel_id = ${db.escape(this.watchChannelId)} `, | ||||
|                         `WHERE guild_id = ${db.escape(this.guildId)}` | ||||
|                     ]; | ||||
|                     return queryParts.join(''); | ||||
|                     break; | ||||
|                 case "setTreeMessage": | ||||
|                     queryParts = [ | ||||
|                         `UPDATE guild_info SET tree_message_id = ${db.escape(this.treeMessageId)}, `, | ||||
|                         `tree_channel_id = ${db.escape(this.treeChannelId)}, `, | ||||
|                         `WHERE guild_id = ${db.escape(this.guildId)}` | ||||
|                     ]; | ||||
|                     return queryParts.join(''); | ||||
|                     break; | ||||
|                 case "setLeaderboardMessage": | ||||
|                     queryParts = [ | ||||
|                         `UPDATE guild_info SET leaderboard_message_id = ${db.escape(this.leaderboardMessageId)}, `, | ||||
|                         `leaderboard_channel_id = ${db.escape(this.leaderboardChannelId)}, `, | ||||
|                         `WHERE guild_id = ${db.escape(this.guildId)}` | ||||
|                     ]; | ||||
|                     return queryParts.join(''); | ||||
|                     break; | ||||
|                 default: | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -4,7 +4,7 @@ dotenv.config(); | ||||
| 
 | ||||
| const { REST } = require('@discordjs/rest'); | ||||
| const { Routes } = require('discord-api-types/v9'); | ||||
| const clientId = process.env.clientId; | ||||
| const clientId = process.env.BOTID; | ||||
| const token = process.env.TOKEN; | ||||
| const fs = require('fs'); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										164
									
								
								modules/dbfn.js
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								modules/dbfn.js
									
									
									
									
									
								
							| @ -2,6 +2,7 @@ const dotenv = require('dotenv'); | ||||
| dotenv.config(); | ||||
| const debugMode = process.env.DEBUG || true; | ||||
| const mysql = require('mysql'); | ||||
| const { GuildInfo } = require('./CustomClasses.js'); | ||||
| 
 | ||||
| /* Table Structures | ||||
| guild_info | ||||
| @ -33,42 +34,6 @@ leaderboard | ||||
| */ | ||||
| 
 | ||||
| module.exports = { | ||||
| 	createGuildTables(guildId) { | ||||
| 		const db = mysql.createConnection({ | ||||
| 			host: process.env.DBHOST, | ||||
| 			user: process.env.DBUSER, | ||||
| 			password: process.env.DBPASS, | ||||
| 			database: process.env.DBNAME, | ||||
| 			port: process.env.DBPORT | ||||
| 		}); | ||||
| 		db.connect((err) => { | ||||
| 			if (err) throw `Error connecting to the database: ${err.message}`; | ||||
| 		}); | ||||
| 		// Create the guild-information and rank-information tables to be used.
 | ||||
| 		const createGuildInfoTableQuery = "CREATE TABLE IF NOT EXISTS guild_info(guild_id VARCHAR(50) NOT NULL, tree_name VARCHAR(100) NOT NULL DEFAULT 'Run /setup where your tree is.', tree_height INT(10) NOT NULL DEFAULT 0, tree_message_id VARCHAR(50) NOT NULL DEFAULT 'Run /setup where your tree is.', tree_channel_id VARCHAR(50) NOT NULL DEFAULT 'Run /setup where your tree is.', leaderboard_message_id VARCHAR(50) NOT NULL DEFAULT 'Run /setup where your leaderboard is.', leaderboard_channel_id VARCHAR(50) NOT NULL DEFAULT 'Run /setup where your leaderboard is.', CONSTRAINT guild_pk PRIMARY KEY (guild_id))"; | ||||
| 		const createLeaderboardTableQuery = "CREATE TABLE IF NOT EXISTS leaderboard(id INT(10) NOT NULL AUTO_INCREMENT,guild_id VARCHAR(50) NOT NULL,tree_name VARCHAR(100) NOT NULL,tree_rank INT(10) NOT NULL,tree_height INT(10) NOT NULL DEFAULT 1,has_pin TINYINT(1) NOT NULL DEFAULT 0,timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, CONSTRAINT id_pk PRIMARY KEY(id))"; | ||||
| 		// TODO run the queries, then add a call to this function at the beginning of main.js or functions.js
 | ||||
| 		return new Promise((resolve, reject) => { | ||||
| 			db.query(createGuildInfoTableQuery, (err) => { | ||||
| 				if (err) { | ||||
| 					reject("Error creating the guild_info table: " + err.message); | ||||
| 					console.error("Offending query: " + createGuildInfoTableQuery); | ||||
| 					db.end(); | ||||
| 					return; | ||||
| 				} | ||||
| 				db.query(createLeaderboardTableQuery, (err) => { | ||||
| 					if (err) { | ||||
| 						reject("Error creating the leaderboard table: " + err.message); | ||||
| 						console.error("Offending query: " + createLeaderboardTableQuery); | ||||
| 						db.end(); | ||||
| 						return; | ||||
| 					} | ||||
| 					resolve({ "status": "Successfully checked both tables.", "data": null }); | ||||
| 					db.end(); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
| 	getGuildInfo(guildId) { | ||||
| 		const db = mysql.createConnection({ | ||||
| 			host: process.env.DBHOST, | ||||
| @ -91,45 +56,26 @@ module.exports = { | ||||
| 					db.end(); | ||||
| 					return; | ||||
| 				} | ||||
| 				/*const guildInfo = { "guildId": "123", | ||||
| 					"treeName": "name", | ||||
| 					"treeHeight": 123, | ||||
| 					"treeMessageId": "123", | ||||
| 					"treeChannelId": "123", | ||||
| 					"leaderboardMessageId": "123", | ||||
| 					"leaderboardChannelId": "123", | ||||
| 					"reminderMessage": "Abc", | ||||
| 					"reminderChannelId": "123", | ||||
| 					"remindedStatus": 0, | ||||
| 					"comparisonMessageId": "123" | ||||
| 				};*/ | ||||
| 				if (res.length == 0) { | ||||
| 					reject("There is no database entry for your guild yet. Try running /setup"); | ||||
| 					db.end(); | ||||
| 					return; | ||||
| 				} | ||||
| 				row = res[0]; | ||||
| 				const guildInfo = { | ||||
| 					"guildId": guildId, | ||||
| 					"treeName": row.tree_name, | ||||
| 					"treeHeight": row.tree_height, | ||||
| 					"treeMessageId": row.tree_message_id, | ||||
| 					"treeChannelId": row.tree_channel_id, | ||||
| 					"leaderboardMessageId": row.leaderboard_message_id, | ||||
| 					"leaderboardChannelId": row.leaderboard_channel_id, | ||||
| 					"reminderMessage": row.ping_role_id, | ||||
| 					"reminderChannelId": row.ping_channel_id, | ||||
| 					"remindedStatus": row.reminded_status, | ||||
| 					"reminderOptIn": row.reminder_optin, | ||||
| 					"comparisonMessageId": row.comparison_message_id, | ||||
| 					"comparisonChannelId": row.comparison_channel_id | ||||
| 				}; | ||||
| 				const guildInfo = new GuildInfo() | ||||
| 					.setId(row.guild_id) | ||||
| 					.setName(row.tree_name) | ||||
| 					.setHeight(row.tree_height) | ||||
| 					.setTreeMessage(row.tree_message_id, row.tree_channel_id) | ||||
| 					.setLeaderboardMessage(row.leaderboard_message_id, row.leaderboard_channel_id) | ||||
| 					.setReminders(row.water_message, row.fruit_message, row.reminder_channel_id, row.watch_channel_id); | ||||
| 
 | ||||
| 				db.end(); | ||||
| 				resolve({ "status": "Successfully fetched guild information", "data": guildInfo }); | ||||
| 				resolve(guildInfo); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
| 	setGuildInfo(guildInfo) { | ||||
| 	getAllGuildInfos() { | ||||
| 		const db = mysql.createConnection({ | ||||
| 			host: process.env.DBHOST, | ||||
| 			user: process.env.DBUSER, | ||||
| @ -140,13 +86,53 @@ module.exports = { | ||||
| 		db.connect((err) => { | ||||
| 			if (err) throw `Error connecting to the database: ${err.message}`; | ||||
| 		}); | ||||
| 		// Returns a Promise, resolve({ "status": "", "data": null })
 | ||||
| 		// guildInfo = { "guildId": "123", "treeName": "name", "treeHeight": 123, "treeMessageId": "123", "treeChannelId": "123", "leaderboardMessageId": "123", "leaderboardChannelId": "123"}
 | ||||
| 		// Set a server's tree information in the database
 | ||||
| 		const insertGuildInfoQuery = `INSERT INTO guild_info (guild_id, tree_name, tree_height, tree_message_id, tree_channel_id, leaderboard_message_id, leaderboard_channel_id) VALUES (${db.escape(guildInfo.guildId)}, ${db.escape(guildInfo.treeName)}, ${db.escape(guildInfo.treeHeight)},${db.escape(guildInfo.treeMessageId)}, ${db.escape(guildInfo.treeChannelId)}, ${db.escape(guildInfo.leaderboardMessageId)}, ${db.escape(guildInfo.leaderboardChannelId)}) ON DUPLICATE KEY UPDATE tree_name = ${db.escape(guildInfo.treeName)},tree_height = ${db.escape(guildInfo.treeHeight)},tree_message_id = ${db.escape(guildInfo.treeMessageId)},tree_channel_id = ${db.escape(guildInfo.treeChannelId)},leaderboard_message_id = ${db.escape(guildInfo.leaderboardMessageId)},leaderboard_channel_id = ${db.escape(guildInfo.leaderboardChannelId)}`; | ||||
| 		// TODO run this query and return a promise, then resolve with { "status": , "data": null }
 | ||||
| 		// Get a server's tree information from the database
 | ||||
| 		const query = 'SELECT * FROM guild_info'; | ||||
| 		// 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(insertGuildInfoQuery, (err, res) => { | ||||
| 			db.query(query, (err, res) => { | ||||
| 				if (err) { | ||||
| 					console.error(err); | ||||
| 					reject("Error fetching all guild infos: " + err.message); | ||||
| 					db.end(); | ||||
| 					return; | ||||
| 				} | ||||
| 				if (res.length == 0) { | ||||
| 					reject("There are no servers yet!"); | ||||
| 					db.end(); | ||||
| 					return; | ||||
| 				} | ||||
| 				let guildInfos = []; | ||||
| 				for (let i = 0; i < res.length; i++) { | ||||
| 					let row = res[i]; | ||||
| 					guildInfos.push(new GuildInfo() | ||||
| 						.setId(row.guild_id) | ||||
| 						.setName(row.tree_name) | ||||
| 						.setHeight(row.tree_height) | ||||
| 						.setTreeMessage(row.tree_message_id, row.tree_channel_id) | ||||
| 						.setLeaderboardMessage(row.leaderboard_message_id, row.leaderboard_channel_id) | ||||
| 						.setReminders(row.water_message, row.fruit_message, row.reminder_channel_id, row.watch_channel_id) | ||||
| 					); | ||||
| 				} | ||||
| 
 | ||||
| 				db.end(); | ||||
| 				resolve(guildInfos); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
| 	setGuildInfo(query) { | ||||
| 		const db = mysql.createConnection({ | ||||
| 			host: process.env.DBHOST, | ||||
| 			user: process.env.DBUSER, | ||||
| 			password: process.env.DBPASS, | ||||
| 			database: process.env.DBNAME, | ||||
| 			port: process.env.DBPORT | ||||
| 		}); | ||||
| 		db.connect((err) => { | ||||
| 			if (err) throw `Error connecting to the database: ${err.message}`; | ||||
| 		}); | ||||
| 		return new Promise((resolve, reject) => { | ||||
| 			db.query(query, (err, res) => { | ||||
| 				if (err) { | ||||
| 					console.error(err); | ||||
| 					reject("Error setting the guild info: " + err.message); | ||||
| @ -154,7 +140,7 @@ module.exports = { | ||||
| 					return; | ||||
| 				} | ||||
| 				db.end(); | ||||
| 				resolve({ "status": "Successfully set the guild information", "data": null }); | ||||
| 				resolve(); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
| @ -353,7 +339,7 @@ module.exports = { | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
| 	setReminderInfo(guildId, reminderMessage, reminderChannelId) { | ||||
| 	setReminderInfo(guildInfo) { | ||||
| 		const db = mysql.createConnection({ | ||||
| 			host: process.env.DBHOST, | ||||
| 			user: process.env.DBUSER, | ||||
| @ -365,7 +351,7 @@ module.exports = { | ||||
| 			if (err) throw `Error connecting to the database: ${err.message}`; | ||||
| 		}); | ||||
| 		// Returns a Promise, resolve({ "status": "", "data": leaderboard })
 | ||||
| 		const insertReminderInfoQuery = `UPDATE guild_info SET ping_role_id = ${db.escape(reminderMessage)}, ping_channel_id = ${db.escape(reminderChannelId)} WHERE guild_id = ${db.escape(guildId)}`; | ||||
| 		const insertReminderInfoQuery = `UPDATE guild_info SET waterMessage = ${db.escape(guildInfo.waterMessage)}, ping_channel_id = ${db.escape(reminderChannelId)}, fruit_message = ${db.escape(guildInfo.fruitMessage)} WHERE guild_id = ${db.escape(guildId)}`; | ||||
| 		// TODO run the query and return a promise then process the results. resolve with { "status": , "data": leaderboard }
 | ||||
| 		return new Promise((resolve, reject) => { | ||||
| 			db.query(insertReminderInfoQuery, (err, res) => { | ||||
| @ -376,7 +362,7 @@ module.exports = { | ||||
| 					return; | ||||
| 				} | ||||
| 				db.end(); | ||||
| 				resolve({ "status": `Successfully set the reminder message to "${reminderMessage}" in <#${reminderChannelId}>`, "data": res }); | ||||
| 				resolve({ "status": `Your notification relay has been set up.\nWater Message: "${guildInfo.waterMessage}"\nFruit Message: "${guildInfo.fruitMessage}"\nRelay Channel: <#${guildInfo.reminderChannelId}>\nWatch Channel: <#${guildInfo.notificationChannelId}>`, "data": res }); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
| @ -524,5 +510,33 @@ module.exports = { | ||||
| 				resolve({ "status": `Successfully set the comparison message ID: ${comparisonMessage}`, "data": res }); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
| 	setNotificationChannel(id, guildId) { | ||||
| 		const db = mysql.createConnection({ | ||||
| 			host: process.env.DBHOST, | ||||
| 			user: process.env.DBUSER, | ||||
| 			password: process.env.DBPASS, | ||||
| 			database: process.env.DBNAME, | ||||
| 			port: process.env.DBPORT | ||||
| 		}); | ||||
| 		db.connect((err) => { | ||||
| 			if (err) throw `Error connecting to the database: ${err.message}`; | ||||
| 		}); | ||||
| 		// Returns a Promise, resolve({ "status": "", "data": leaderboard })
 | ||||
| 		const query = `UPDATE guild_info SET notification_channel_id = ${db.escape(id)} 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(query, (err, res) => { | ||||
| 				if (err) { | ||||
| 					console.error(err); | ||||
| 					db.end(); | ||||
| 					reject("Error updating the notification channel ID: " + err.message); | ||||
| 					return; | ||||
| 				} | ||||
| 				db.end(); | ||||
| 				resolve({ "status": `Successfully set the notification channel ID: ${comparisonMessage}`, "data": res }); | ||||
| 			}); | ||||
| 		}); | ||||
| 	} | ||||
| }; | ||||
| @ -11,6 +11,7 @@ const fs = require('fs'); | ||||
| // Discord.js
 | ||||
| const Discord = require('discord.js'); | ||||
| const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = Discord; | ||||
| const { GuildInfo } = require('./CustomClasses'); | ||||
| 
 | ||||
| // Various imports from other files
 | ||||
| const config = require('../data/config.json'); | ||||
| @ -21,7 +22,7 @@ const { finished } = require('stream'); | ||||
| 
 | ||||
| const functions = { | ||||
| 	// Functions for managing and creating Collections
 | ||||
| 	collections: { | ||||
| 	collectionBuilders: { | ||||
| 		// Create the collection of slash commands
 | ||||
| 		slashCommands(client) { | ||||
| 			if (!client.slashCommands) client.slashCommands = new Discord.Collection(); | ||||
| @ -33,6 +34,15 @@ const functions = { | ||||
| 				} | ||||
| 			} | ||||
| 			if (isDev) console.log('Slash Commands Collection Built'); | ||||
| 		}, | ||||
| 		async guildInfos(client) { | ||||
| 			const guildInfos = await dbfn.getAllGuildInfos(); | ||||
| 			if (!client.guildInfos) client.guildInfos = new Discord.Collection(); | ||||
| 			client.guildInfos.clear(); | ||||
| 			for (const guildInfo of guildInfos) { | ||||
| 				client.guildInfos.set(guildInfo.guildId, guildInfo); | ||||
| 			} | ||||
| 			return 'guildInfos Collection Built'; | ||||
| 		} | ||||
| 	}, | ||||
| 	builders: { | ||||
| @ -58,44 +68,9 @@ const functions = { | ||||
| 					.addComponents( | ||||
| 						refreshButton | ||||
| 					); | ||||
| 				if (guildInfo.reminderOptIn == 1 && guildInfo.remindedStatus == 1) { | ||||
| 					const resetPingButton = new ButtonBuilder() | ||||
| 						.setCustomId('resetping') | ||||
| 						.setLabel('Reset Ping') | ||||
| 						.setStyle(ButtonStyle.Secondary); | ||||
| 					refreshActionRow.addComponents(resetPingButton); | ||||
| 				} else if (guildInfo.reminderOptIn == 1 && guildInfo.remindedStatus == 0) { | ||||
| 					const resetPingButton = new ButtonBuilder() | ||||
| 						.setCustomId('resetping') | ||||
| 						.setLabel('[Armed]') | ||||
| 						.setStyle(ButtonStyle.Secondary); | ||||
| 					refreshActionRow.addComponents(resetPingButton); | ||||
| 				} | ||||
| 				return refreshActionRow; | ||||
| 			} | ||||
| 		}, | ||||
| 		async refreshAction(guildId) { | ||||
| 			// Create the button to go in the Action Row
 | ||||
| 			const refreshButton = new ButtonBuilder() | ||||
| 				.setCustomId('refresh') | ||||
| 				.setLabel('Refresh') | ||||
| 				.setStyle(ButtonStyle.Primary); | ||||
| 			const resetPingButton = new ButtonBuilder() | ||||
| 				.setCustomId('resetping') | ||||
| 				.setLabel('Reset Ping') | ||||
| 				.setStyle(ButtonStyle.Secondary); | ||||
| 			// Create the Action Row with the Button in it, to be sent with the Embed
 | ||||
| 			let refreshActionRow = new ActionRowBuilder() | ||||
| 				.addComponents( | ||||
| 					refreshButton | ||||
| 				); | ||||
| 			const getGuildInfoResponse = await dbfn.getGuildInfo(guildId); | ||||
| 			const guildInfo = getGuildInfoResponse.data; | ||||
| 			if (guildInfo.reminderMessage != "" && guildInfo.reminderChannelId != "") { | ||||
| 				refreshActionRow.addComponents(resetPingButton); | ||||
| 			} | ||||
| 			return refreshActionRow; | ||||
| 		}, | ||||
| 		comparisonEmbed(content, guildInfo) { | ||||
| 			// Create the embed using the content passed to this function
 | ||||
| 			const embed = new EmbedBuilder() | ||||
| @ -110,7 +85,7 @@ const functions = { | ||||
| 			// Create the embed using the content passed to this function
 | ||||
| 			const embed = new EmbedBuilder() | ||||
| 				.setColor(strings.embeds.color) | ||||
| 				.setTitle('Water Reminder') | ||||
| 				.setTitle('Notification Relay') | ||||
| 				.setDescription(`[Click here to go to your Tree](https://discord.com/channels/${guildInfo.guildId}/${guildInfo.treeChannelId}/${guildInfo.treeMessageId})`) | ||||
| 				.setFooter({ text: `Click ♻️ to delete this message` }); | ||||
| 			const messageContents = { content: content, embeds: [embed], components: [this.actionRows.reminderActionRow()] }; | ||||
| @ -417,8 +392,9 @@ const functions = { | ||||
| 
 | ||||
| 					// await dbfn.setGuildInfo(guildInfo);
 | ||||
| 					// Bundle guildInfo into the response
 | ||||
| 					const getGuildInfoResponse = await dbfn.getGuildInfo(guildInfo.guildId); | ||||
| 					response.data = getGuildInfoResponse.data; | ||||
| 					// const getGuildInfoResponse = await dbfn.getGuildInfo(guildInfo.guildId);
 | ||||
| 					await functions.collectionBuilders.guildInfos(interaction.client); | ||||
| 					response.data = interaction.client.guildInfos.get(guildInfo.guildId); | ||||
| 
 | ||||
| 					// Set the response status, this is only used as a response to /setup
 | ||||
| 					if (treeFound && leaderboardFound) { // we found both the tree and leaderboard
 | ||||
| @ -453,8 +429,9 @@ const functions = { | ||||
| 		} | ||||
| 	}, | ||||
| 	async refresh(interaction) { | ||||
| 		const getGuildInfoResponse = await dbfn.getGuildInfo(interaction.guildId); | ||||
| 		let guildInfo = getGuildInfoResponse.data; | ||||
| 		// const getGuildInfoResponse = await dbfn.getGuildInfo(interaction.guildId);
 | ||||
| 		// let guildInfo = getGuildInfoResponse.data;
 | ||||
| 		let guildInfo = interaction.client.guildInfos.get(interaction.guild.id); | ||||
| 		const findMessagesResponse = await this.messages.find(interaction, guildInfo); | ||||
| 		if (findMessagesResponse.code == 1) { | ||||
| 			guildInfo = findMessagesResponse.data; | ||||
| @ -466,10 +443,7 @@ const functions = { | ||||
| 			const comparedRankings = await this.rankings.compare(interaction, guildInfo); | ||||
| 
 | ||||
| 			const embed = this.builders.comparisonEmbed(comparedRankings, guildInfo); | ||||
| 			await interaction.update(embed).then(async interactionResponse => { | ||||
| 				// console.log(interactionResponse.interaction.message);
 | ||||
| 				await dbfn.setComparisonMessage(interactionResponse.interaction.message, interaction.guildId); | ||||
| 			}); | ||||
| 			await interaction.update(embed).catch(err => console.error(err)); | ||||
| 		} else { | ||||
| 			await interaction.update(this.builders.errorEmbed(findMessagesResponse.status)); | ||||
| 		} | ||||
| @ -485,20 +459,12 @@ const functions = { | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
| 	getInfo(guildId) { | ||||
| 		return new Promise((resolve, reject) => { | ||||
| 			dbfn.getGuildInfo(guildId).then(res => { | ||||
| 				let guildInfo = res.data; | ||||
| 				let guildInfoString = ""; | ||||
| 				guildInfoString += `Tree Message: https://discord.com/channels/${guildId}/${guildInfo.treeChannelId}/${guildInfo.treeMessageId}\n`; | ||||
| 				guildInfoString += `Rank Message: https://discord.com/channels/${guildId}/${guildInfo.leaderboardChannelId}/${guildInfo.leaderboardMessageId}\n`; | ||||
| 				resolve(`Here is your servers setup info:\n${guildInfoString}`); | ||||
| 			}).catch(err => { | ||||
| 				console.error(err); | ||||
| 				reject(err); | ||||
| 				return; | ||||
| 			}) | ||||
| 		}); | ||||
| 	getInfo(interaction) { | ||||
| 		let guildInfo = interaction.client.guildInfos.get(interaction.guild.id); | ||||
| 		let guildInfoString = ""; | ||||
| 		guildInfoString += `Tree Message: https://discord.com/channels/${guildId}/${guildInfo.treeChannelId}/${guildInfo.treeMessageId}\n`; | ||||
| 		guildInfoString += `Rank Message: https://discord.com/channels/${guildId}/${guildInfo.leaderboardChannelId}/${guildInfo.leaderboardMessageId}\n`; | ||||
| 		return `Here is your servers setup info:\n${guildInfoString}`; | ||||
| 	}, | ||||
| 	getWaterTime(size) { | ||||
| 		return Math.floor(Math.pow(size * 0.07 + 5, 1.1)); // Seconds
 | ||||
| @ -539,89 +505,13 @@ const functions = { | ||||
| 			}, ms); | ||||
| 		}); | ||||
| 	}, | ||||
| 	async sendReminder(guildInfo, guild) { | ||||
| 		const { guildId, reminderChannelId, reminderMessage } = guildInfo; | ||||
| 		const reminderChannel = await guild.channels.fetch(reminderChannelId); | ||||
| 		const reminderEmbed = functions.builders.reminderEmbed(reminderMessage, guildInfo); | ||||
| 		await reminderChannel.send(reminderEmbed).then(async m => { | ||||
| 			const setRemindedStatusReponse = await dbfn.setRemindedStatus(guildId, 1); | ||||
| 			return 1; | ||||
| 		}).catch(err => { | ||||
| 	async sendReminder(guildInfo, message, channelId, guild) { | ||||
| 		const reminderChannel = await guild.channels.fetch(channelId); | ||||
| 		const reminderEmbed = functions.builders.reminderEmbed(message, guildInfo); | ||||
| 		await reminderChannel.send(reminderEmbed).catch(err => { | ||||
| 			console.error(err); | ||||
| 		}); | ||||
| 	}, | ||||
| 	async setReminder(interaction, ms) { | ||||
| 		setTimeout(this.sendReminder(interaction), ms); | ||||
| 	}, | ||||
| 	async checkReady(client) { // Check if the guilds trees are ready to water
 | ||||
| 		// let time = new Date(Date.now());
 | ||||
| 		// console.log("Ready check " + time.getSeconds());
 | ||||
| 		try { | ||||
| 			// Get the guildInfos for each guild that is opted in and waiting to send a reminder
 | ||||
| 			const getOptedInGuildsResponse = await dbfn.getOptedInGuilds(); | ||||
| 			// 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("<t:") + 3; | ||||
| 							const endWaterTimestamp = description.indexOf(":>"); | ||||
| 							// Split the description starting at "<t:" and ending 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) { | ||||
| 							// Send the reminder message
 | ||||
| 							await this.sendReminder(guildInfo, guild); | ||||
| 							guildInfo.remindedStatus = 1; | ||||
| 							await this.refreshComparisonMessage(client, guildInfo); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				await this.sleep(5000); | ||||
| 				this.checkReady(client); | ||||
| 			} else { | ||||
| 				// console.log(getOptedInGuildsResponse.status);
 | ||||
| 				await this.sleep(5000); | ||||
| 				this.checkReady(client); | ||||
| 			} | ||||
| 		} catch (err) { | ||||
| 			console.error(err); | ||||
| 			await this.sleep(30000); | ||||
| 			this.checkReady(client); | ||||
| 		} | ||||
| 	}, | ||||
| 	async refreshComparisonMessage(client, guildInfo) { | ||||
| 		if (guildInfo.comparisonChannelId != "" && guildInfo.comparisonMessageId != "") { | ||||
| 			const guild = await client.guilds.fetch(guildInfo.guildId); | ||||
| @ -633,8 +523,25 @@ const functions = { | ||||
| 			return; | ||||
| 		} | ||||
| 	}, | ||||
| 	async resetPing(interaction) { | ||||
| 		await dbfn.setRemindedStatus(interaction.guildId, 0); | ||||
| 	async setupCollectors(client) { | ||||
| 		let guildInfos = client.guildInfos; | ||||
| 		guildInfos.set("collectors", []); | ||||
| 		await guildInfos.forEach(async guildInfo => { | ||||
| 			if (guildInfo.watchChannelId != "" && guildInfo instanceof GuildInfo) { | ||||
| 				const guild = await client.guilds.fetch(guildInfo.guildId); | ||||
| 				// console.log(guildInfo instanceof GuildInfo);
 | ||||
| 				const channel = await guild.channels.fetch(guildInfo.watchChannelId); | ||||
| 				const filter = message => message.author.id != process.env.BOTID; | ||||
| 				const collector = channel.createMessageCollector({ filter }); | ||||
| 				collector.on('collect', message => { | ||||
| 					if (message.content.includes(strings.notifications.water)) { | ||||
| 						this.sendReminder(guildInfo, guildInfo.waterMessage, guildInfo.reminderChannelId, guild); | ||||
| 					} else if (message.content.includes(strings.notifications.fruit)) { | ||||
| 						this.sendReminder(guildInfo, guildInfo.fruitMessage, guildInfo.reminderChannelId, guild); | ||||
| 					} | ||||
| 				}); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										124
									
								
								modules/testing.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								modules/testing.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,124 @@ | ||||
| const GuildInfo = class { | ||||
|     constructor() { | ||||
|         this.guildId = ""; | ||||
|         this.treeName = ""; | ||||
|         this.treeHeight = 0; | ||||
|         this.treeMessageId = ""; | ||||
|         this.treeChannelId = ""; | ||||
|         this.leaderboardMessageId = ""; | ||||
|         this.leaderboardChannelId = ""; | ||||
|         this.waterMessage = ""; | ||||
|         this.fruitMessage = ""; | ||||
|         this.reminderChannelId = ""; | ||||
|         this.watchChannelId = ""; | ||||
|     } | ||||
| 
 | ||||
|     setId(id) { | ||||
|         this.guildId = id; | ||||
|         return this; | ||||
|     } | ||||
|     setName(name) { | ||||
|         this.treeName = name; | ||||
|         return this; | ||||
|     } | ||||
|     setHeight(height) { | ||||
|         this.treeHeight = height; | ||||
|         return this; | ||||
|     } | ||||
|     setTreeMessage(messageId, channelId) { | ||||
|         this.treeMessageId = messageId; | ||||
|         this.treeChannelId = channelId; | ||||
|         return this; | ||||
|     } | ||||
|     setLeaderboardMessage(messageId, channelId) { | ||||
|         this.leaderboardMessageId = messageId; | ||||
|         this.leaderboardChannelId = channelId; | ||||
|         return this; | ||||
|     } | ||||
|     setReminders(waterMessage, fruitMessage, reminderChannelId, watchChannelId) { | ||||
|         this.waterMessage = waterMessage; | ||||
|         this.fruitMessage = fruitMessage; | ||||
|         this.reminderChannelId = reminderChannelId; | ||||
|         this.watchChannelId = watchChannelId; | ||||
|         return this; | ||||
|     } | ||||
|     queryBuilder(query) { | ||||
|         let queryParts = []; | ||||
|         switch (query) { | ||||
|             case "setAll": | ||||
|                 queryParts = [ | ||||
|                     `INSERT INTO guild_info `, | ||||
|                     `(guild_id, `, | ||||
|                     `tree_name, `, | ||||
|                     `tree_height, `, | ||||
|                     `tree_message_id, `, | ||||
|                     `tree_channel_id, `, | ||||
|                     `leaderboard_message_id, `, | ||||
|                     `leaderboard_channel_id, `, | ||||
|                     `water_message, `, | ||||
|                     `fruit_message, `, | ||||
|                     `reminder_channel_id, `, | ||||
|                     `watch_channel_id) `, | ||||
|                     `VALUES (${db.escape(this.guildId)}, `, | ||||
|                     `${db.escape(this.treeName)}, `, | ||||
|                     `${db.escape(this.treeHeight)}, `, | ||||
|                     `${db.escape(this.treeMessageId)}, `, | ||||
|                     `${db.escape(this.treeChannelId)}, `, | ||||
|                     `${db.escape(this.leaderboardMessageId)}, `, | ||||
|                     `${db.escape(this.leaderboardChannelId)}, `, | ||||
|                     `${db.escape(this.waterMessage)}, `, | ||||
|                     `${db.escape(this.fruitMessage)}, `, | ||||
|                     `${db.escape(this.reminderChannelId)}, `, | ||||
|                     `${db.escape(this.watchChannelId)}) `, | ||||
|                     `ON DUPLICATE KEY UPDATE tree_name = ${db.escape(this.treeName)}, `, | ||||
|                     `tree_height = ${db.escape(this.treeHeight)}, `, | ||||
|                     `tree_message_id = ${db.escape(this.treeMessageId)}, `, | ||||
|                     `tree_channel_id = ${db.escape(this.treeChannelId)}, `, | ||||
|                     `leaderboard_message_id = ${db.escape(this.leaderboardMessageId)}, `, | ||||
|                     `leaderboard_channel_id = ${db.escape(this.leaderboardChannelId)}, `, | ||||
|                     `water_message = ${db.escape(this.waterMessage)}, `, | ||||
|                     `fruit_message = ${db.escape(this.fruitMessage)}, `, | ||||
|                     `reminder_channel_id = ${db.escape(this.reminderChannelId)}, `, | ||||
|                     `watch_channel_id = ${db.escape(this.watchChannelId)})` | ||||
|                 ]; | ||||
|                 return queryParts.join(); | ||||
|                 break; | ||||
|             case "setReminders": | ||||
|                 queryParts = [ | ||||
|                     `UPDATE guildInfo SET water_message = ${db.escape(this.waterMessage)}, `, | ||||
|                     `fruit_message = ${db.escape(this.fruitMessage)}, `, | ||||
|                     `reminder_channel_id = ${db.escape(this.reminderChannelId)}, `, | ||||
|                     `watch_channel_id = ${db.escape(this.watchChannelId)} `, | ||||
|                     `WHERE guild_id = ${db.escape(this.guildId)}` | ||||
|                 ]; | ||||
|                 return queryParts.join(); | ||||
|                 break; | ||||
|             case "setTreeMessage": | ||||
|                 queryParts = [ | ||||
|                     `UPDATE guildInfo SET tree_message_id = ${db.escape(this.treeMessageId)}, `, | ||||
|                     `tree_channel_id = ${db.escape(this.treeChannelId)}, `, | ||||
|                     `WHERE guild_id = ${db.escape(this.guildId)}` | ||||
|                 ]; | ||||
|                 return queryParts.join(); | ||||
|                 break; | ||||
|             case "setLeaderboardMessage": | ||||
|                 queryParts = [ | ||||
|                     `UPDATE guildInfo SET leaderboard_message_id = ${db.escape(this.leaderboardMessageId)}, `, | ||||
|                     `leaderboard_channel_id = ${db.escape(this.leaderboardChannelId)}, `, | ||||
|                     `WHERE guild_id = ${db.escape(this.guildId)}` | ||||
|                 ]; | ||||
|                 return queryParts.join(); | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| new GuildInfo() | ||||
|     .setId(row.guild_id) | ||||
|     .setName(row.tree_name) | ||||
|     .setHeight(row.tree_height) | ||||
|     .setTreeMessage(row.tree_message_id, row.tree_channel_id) | ||||
|     .setLeaderboardMessage(row.leaderboard_message_id, row.leaderboard_channel_id) | ||||
|     .setReminders(row.water_message, row.fruit_message, row.reminder_channel_id); | ||||
| @ -1,6 +1,7 @@ | ||||
| const { SlashCommandBuilder } = require('discord.js'); | ||||
| const { SlashCommandBuilder, Guild } = require('discord.js'); | ||||
| const dbfn = require('../modules/dbfn.js'); | ||||
| const fn = require('../modules/functions.js'); | ||||
| const { GuildInfo } = require('../modules/CustomClasses.js'); | ||||
| 
 | ||||
| module.exports = { | ||||
| 	data: new SlashCommandBuilder() | ||||
| @ -10,61 +11,40 @@ module.exports = { | ||||
| 		try { | ||||
| 			await interaction.deferReply(); | ||||
| 			// Get the guildInfo from the database
 | ||||
| 			dbfn.getGuildInfo(interaction.guildId).then(async getGuildInfoResponse => { | ||||
| 				let guildInfo = getGuildInfoResponse.data; | ||||
| 				// Find the most recent tree and leaderboard messages in their respective channels
 | ||||
| 
 | ||||
| 			if (interaction.client.guildInfos.has(interaction.guildId)) { | ||||
| 				let guildInfo = interaction.client.guildInfos.get(interaction.guildId); | ||||
| 				const findMessagesResponse = await fn.messages.find(interaction, guildInfo); | ||||
| 				if (findMessagesResponse.code == 1) { | ||||
| 					guildInfo = findMessagesResponse.data; | ||||
| 					let guildInfo = interaction.client.guildInfos.get(interaction.guildId); | ||||
| 					// Parse the leaderboard message
 | ||||
| 					await fn.rankings.parse(interaction, guildInfo); | ||||
| 					// Build the string that shows the comparison // TODO Move the string building section to fn.builders?
 | ||||
| 					const comparedRankings = await fn.rankings.compare(interaction, guildInfo); | ||||
| 
 | ||||
| 					const embed = fn.builders.comparisonEmbed(comparedRankings, guildInfo); | ||||
| 					await interaction.editReply(embed).then(async message => { | ||||
| 						await dbfn.setComparisonMessage(message, interaction.guildId); | ||||
| 					}); | ||||
| 					await interaction.editReply(embed).catch(err => console.error(err)); | ||||
| 				} else { | ||||
| 					await interaction.editReply(fn.builders.errorEmbed(findMessagesResponse.status)); | ||||
| 				} | ||||
| 
 | ||||
| 			}).catch(async err => { // If we fail to fetch the guild's info from the database
 | ||||
| 				// If the error is because the guild hasn't been setup yet, set it up
 | ||||
| 				if (err === "There is no database entry for your guild yet. Try running /setup") { | ||||
| 					// Create a basic guildInfo with blank data
 | ||||
| 					let guildInfo = { | ||||
| 						guildId: `${interaction.guildId}`, | ||||
| 						treeName: "", | ||||
| 						treeHeight: 0, | ||||
| 						treeMessageId: "", | ||||
| 						treeChannelId: `${interaction.channelId}`, // Use this interaction channel for the initial channel IDs
 | ||||
| 						leaderboardMessageId: "", | ||||
| 						leaderboardChannelId: `${interaction.channelId}`, | ||||
| 						reminderMessage: "", | ||||
| 						reminderChannelId: "", | ||||
| 						remindedStatus: 0, | ||||
| 						reminderOptIn: 0, | ||||
| 					} | ||||
| 					// Using the above guildInfo, try to find the Grow A Tree messages
 | ||||
| 					const findMessagesResponse = await fn.messages.find(interaction, guildInfo); | ||||
| 					guildInfo = findMessagesResponse.data; | ||||
| 					if (findMessagesResponse.code == 1) { | ||||
| 						// Build the string that shows the comparison // TODO Move the string building section to fn.builders?
 | ||||
| 						const comparedRankings = await fn.rankings.compare(interaction, guildInfo); | ||||
| 						const embed = fn.builders.comparisonEmbed(comparedRankings, guildInfo); | ||||
| 						await interaction.editReply(embed).then(async message => { | ||||
| 							await dbfn.setComparisonMessage(message.id, interaction.guildId); | ||||
| 						}); | ||||
| 					} else { | ||||
| 						await interaction.editReply(fn.builders.errorEmbed(findMessagesResponse.status)); | ||||
| 					} | ||||
| 
 | ||||
| 			} else { | ||||
| 				// Create a basic guildInfo with blank data
 | ||||
| 				let guildInfo = new GuildInfo() | ||||
| 					.setId(interaction.guildId) | ||||
| 					.setTreeMessage("", interaction.channelId) | ||||
| 					.setLeaderboardMessage("", interaction.channelId) | ||||
| 				// Using the above guildInfo, try to find the Grow A Tree messages
 | ||||
| 				const findMessagesResponse = await fn.messages.find(interaction, guildInfo); | ||||
| 				guildInfo = findMessagesResponse.data; | ||||
| 				if (findMessagesResponse.code == 1) { | ||||
| 					// Build the string that shows the comparison // TODO Move the string building section to fn.builders?
 | ||||
| 					const comparedRankings = await fn.rankings.compare(interaction, guildInfo); | ||||
| 					const embed = fn.builders.comparisonEmbed(comparedRankings, guildInfo); | ||||
| 					await interaction.editReply(embed).catch(err => console.error(err)); | ||||
| 				} else { | ||||
| 					await interaction.editReply(fn.builders.errorEmbed("An unknown error occurred while running the compare command.")); | ||||
| 					console.error(err); | ||||
| 					await interaction.editReply(fn.builders.errorEmbed(findMessagesResponse.status)); | ||||
| 				} | ||||
| 			}); | ||||
| 			} | ||||
| 		} catch (err) { | ||||
| 			interaction.editReply(fn.builders.errorEmbed(err)).catch(err => { | ||||
| 				console.error(err); | ||||
|  | ||||
							
								
								
									
										49
									
								
								slash-commands/notifications.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								slash-commands/notifications.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js'); | ||||
| const dbfn = require('../modules/dbfn.js'); | ||||
| const fn = require('../modules/functions.js'); | ||||
| 
 | ||||
| module.exports = { | ||||
| 	data: new SlashCommandBuilder() | ||||
| 		.setName('notifications') | ||||
| 		.setDescription('Setup a notification relay for improved water and fruit notifications') | ||||
| 		.addChannelOption(o => | ||||
| 			o | ||||
| 				.setName('watchchannel') | ||||
| 				.setDescription('The channel Grow A Tree sends your notifications in') | ||||
| 				.setRequired(true)) | ||||
| 		.addStringOption(o => | ||||
| 			o | ||||
| 				.setName('watermessage') | ||||
| 				.setDescription('Message to send for water reminders') | ||||
| 				.setRequired(true)) | ||||
| 		.addChannelOption(o => | ||||
| 			o | ||||
| 				.setName('pingchannel') | ||||
| 				.setDescription('The channel to send the water reminder in') | ||||
| 				.setRequired(true)) | ||||
| 		.addStringOption(o => | ||||
| 			o | ||||
| 				.setName('fruitmessage') | ||||
| 				.setDescription("Message to send for fruit reminders") | ||||
| 				.setRequired(false)) | ||||
| 		.setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles), | ||||
| 	async execute(interaction) { | ||||
| 		try { | ||||
| 			await interaction.deferReply({ ephemeral: true }); | ||||
| 			if (interaction.client.guildInfos.has(interaction.guildId)) { | ||||
| 				const watchChannel = interaction.options.getChannel('watchchannel'); | ||||
| 				const waterMessage = interaction.options.getString('watermessage'); | ||||
| 				const fruitMessage = interaction.options.getString('fruitmessage') ? interaction.options.getString('fruitmessage') : interaction.options.getString('watermessage'); | ||||
| 				const reminderChannel = interaction.options.getChannel('pingchannel'); | ||||
| 				let guildInfo = interaction.client.guildInfos.get(interaction.guildId); | ||||
| 				guildInfo.setReminders(waterMessage, fruitMessage, reminderChannel.id, watchChannel.id); | ||||
| 				let query = guildInfo.queryBuilder("setReminders"); | ||||
| 				console.log(query); | ||||
| 				await dbfn.setGuildInfo(query); | ||||
| 				await interaction.editReply(`I'll watch <#${watchChannel.id}> for Grow A Tree Notifications and relay them to <#${reminderChannel.id}>.`).catch(e => console.error(e)); | ||||
| 			} | ||||
| 		} catch (err) { | ||||
| 			console.error("Error occurred while setting up a notification relay: " + err); | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| @ -1,31 +0,0 @@ | ||||
| const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js'); | ||||
| const dbfn = require('../modules/dbfn.js'); | ||||
| const fn = require('../modules/functions.js'); | ||||
| 
 | ||||
| module.exports = { | ||||
| 	data: new SlashCommandBuilder() | ||||
| 		.setName('setping') | ||||
| 		.setDescription('Opt-in to automatic water reminders') | ||||
| 		.addStringOption(o => | ||||
| 			o.setName('pingmsg') | ||||
| 			 .setDescription('The message to send for a water reminder') | ||||
| 			 .setRequired(true)) | ||||
| 		.addChannelOption(o => | ||||
| 			o.setName('pingchannel') | ||||
| 			 .setDescription('The channel to send the water reminder in') | ||||
| 			 .setRequired(true)) | ||||
| 		.setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles), | ||||
| 	async execute(interaction) { | ||||
| 		try { | ||||
| 			await interaction.deferReply({ ephemeral: true }); | ||||
| 			const reminderMessage = interaction.options.getString('pingmsg'); | ||||
| 			const reminderChannel = interaction.options.getChannel('pingchannel'); | ||||
| 			const setPingRoleResponse = await dbfn.setReminderInfo(interaction.guildId, reminderMessage, reminderChannel.id); | ||||
| 			await dbfn.setReminderOptIn(interaction.guildId, 1); | ||||
| 			interaction.editReply(setPingRoleResponse.status); | ||||
| 		} catch(err) { | ||||
| 			console.error(err); | ||||
| 			await interaction.editReply(fn.builders.errorEmbed(err)); | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| @ -1,18 +0,0 @@ | ||||
| const { SlashCommandBuilder } = require('discord.js'); | ||||
| const dbfn = require('../modules/dbfn.js'); | ||||
| const fn = require('../modules/functions.js'); | ||||
| 
 | ||||
| module.exports = { | ||||
| 	data: new SlashCommandBuilder() | ||||
| 		.setName('setping') | ||||
| 		.setDescription('Run this command when you water your tree to have a reminder sent.'), | ||||
| 	async execute(interaction) { | ||||
| 		await interaction.deferReply({ ephemeral: true }); | ||||
| 		const getGuildInfoResponse = await dbfn.getGuildInfo(interaction.guildId); | ||||
| 		const guildInfo = getGuildInfoResponse.data; | ||||
| 		const reminderTimeS = fn.getWaterTime(guildInfo.treeHeight); | ||||
| 		const reminderTimeMs = reminderTimeS * 1000; | ||||
| 		fn.setReminder(interaction, reminderTimeMs, guildInfo.pingRoleId); | ||||
| 		interaction.editReply("A reminder has been set."); | ||||
| 	}, | ||||
| }; | ||||
| @ -7,7 +7,7 @@ module.exports = { | ||||
| 		.setDescription('View information about how the bot is set up in your server'), | ||||
| 	execute(interaction) { | ||||
| 		interaction.deferReply({ephemeral: true}).then(() => { | ||||
| 			fn.getInfo(interaction.guildId).then(res => { | ||||
| 			fn.getInfo(interaction).then(res => { | ||||
| 				const embed = fn.builders.embed(res); | ||||
| 				interaction.editReply(embed); | ||||
| 			}).catch(err => { | ||||
|  | ||||
| @ -6,21 +6,20 @@ module.exports = { | ||||
| 	data: new SlashCommandBuilder() | ||||
| 		.setName('timetoheight') | ||||
| 		.setDescription('Calculate how long it would take to reach a given height') | ||||
| 		.addStringOption(o =>  | ||||
| 		.addIntegerOption(o =>  | ||||
| 			o.setName('endheight') | ||||
| 			 .setDescription('Ending tree height in feet') | ||||
| 			 .setRequired(true)) | ||||
| 		.addStringOption(o =>  | ||||
| 		.addIntegerOption(o =>  | ||||
| 			o.setName('beginheight') | ||||
| 			 .setDescription('Beginning tree height in feet') | ||||
| 			 .setRequired(false)), | ||||
| 	async execute(interaction) { | ||||
| 		await interaction.deferReply({ ephemeral: true }); | ||||
| 		let beginHeight = interaction.options.getString('beginheight'); | ||||
| 		const endHeight = interaction.options.getString('endheight'); | ||||
| 		let beginHeight = interaction.options.getInteger('beginheight'); | ||||
| 		const endHeight = interaction.options.getInteger('endheight'); | ||||
| 		if (!beginHeight) { | ||||
| 			const getGuildInfoResponse = await dbfn.getGuildInfo(interaction.guildId); | ||||
| 			const guildInfo = getGuildInfoResponse.data; | ||||
| 			const guildInfo = interaction.client.guildInfos.get(interaction.guild.id); | ||||
| 			beginHeight = guildInfo.treeHeight; | ||||
| 		} | ||||
|         fn.timeToHeight(beginHeight, endHeight).then(res => { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user