const ESMCommand = require("../esm_command"); module.exports = class ESMCommand_XM8_Notification extends ESMCommand { constructor(bot) { super(bot); this.permissions = { restricted: true }; this.marxetInfo = {}; this.values = {}; this.validTypes = ["base-raid", "flag-stolen", "flag-restored", "protection-money-due", "protection-money-paid", "charge-plant-started", "grind-started", "hack-started", "flag-steal-started", "marxet-item-sold", "custom"]; } async fromServer() { if (this.util.isEmpty(this.params)) return; let recipients = JSON.parse(this.params.recipients).r; if (this.util.isEmpty(recipients)) { return this.ESMBot.logger.trace(`Empty Recipents!\n${this.toString()}`); } if (!this.validTypes.includes(this.params.type)) { return this.ESMBot.send(await this.db.getLoggingChannel(this.serverID), { title: "Invalid XM8 Notification Type", description: `\`${this.params.type}\` is not a valid XM8 notification type.`, color: this.ESMBot.colors.YELLOW }); } this.values = { communityID: this.util.getCommunityID(this.serverID), serverID: this.serverID, serverName: (await this.db.getServer(this.serverID)).name, territoryName: this.params.message, territoryID: this.params.id, userName: "", userTag: "", marxetItem: "", marxetAmount: "" }; if (this.params.type === "marxet-item-sold") { let marxetInfo = JSON.parse(this.params.message); if (this.util.isEmpty(marxetInfo) || this.util.isEmpty(marxetInfo.item) || this.util.isEmpty(marxetInfo.amount)) { return this.ESMBot.send(await this.db.getLoggingChannel(this.serverID), { title: "Empty XM8 Notification (marxet-item-sold)", description: `The message received from the server was empty!`, color: this.ESMBot.colors.RED }); } this.values.marxetItem = marxetInfo.item; this.values.marxetAmount = marxetInfo.amount; } let output = `**------------------**\nINCOMING XM8 NOTIFICATION\n\tserver_id: \`${this.serverID}\`\n\ttype: \`${this.params.type}\`\n\trecipients (${_.size(recipients)}):\n\`\`\`${recipients}\`\`\`\n`; for (let steamUID of recipients) { output += `Processing recipient: \`${steamUID}\`\n`; if (this.util.isEmpty(steamUID)) { output += `\t**[FATAL]** SteamUID empty\n`; continue; } let discordIDs = await this.db.getDiscordIDsFromSteamUID(steamUID); if (this.util.isEmpty(discordIDs)) { output += `\t**[FATAL]** User not registered with ESM\n`; continue; } output += `\t${_.size(discordIDs)} Discord ID(s) found: \`${discordIDs}\`\n`; for (let id of discordIDs) { output += `\tProcessing Discord ID: \`${id}\`\n`; let allowed = await this.db.getNotificationPreference(id, this.serverID, this.params.type); let user = await this.ESMBot.getUser(id); if (user == null) { output += `\t\t**[FATAL]** Discord returned NULL user\n`; continue; } output += `\t\tDiscord User Found\n`; if (!allowed) { output += `\t\t**[FATAL]** User blocks notification type\n`; continue; } this.values.userName = user.username; this.values.userTag = user.toString(); output += `\t\tUser allows notification type\n`; await this.util.sleep(2000); this.ESMBot.send(user, await this.buildEmbed()); output += `\t**[SUCCESS]** Message sent\n`; } } this.ESMBot.send(this.ESMBot.config.LOGGING.CATCH_ALL, output); let community = await this.db.getCommunity(this.serverID); if (community.log_xm8_notifications) { this.ESMBot.send(community.logging_channel, output); } } async buildEmbed() { let embed = new this.ESMBot.discord.MessageEmbed() .setAuthor(_.truncate(`[${this.values.serverID}] ${this.values.serverName}`, { length: this.util.embed.TITLE_LENGTH_MAX }), this.client.user.avatarURL()) .setTimestamp(this.ESMBot.moment.utc()) .setFooter(`Use '!notif' to disable`); if (this.params.type === "custom") { let customInfo = JSON.parse(this.params.message); if (customInfo.title) { embed.setTitle(_.truncate(`${customInfo.title}`, { length: this.util.embed.TITLE_LENGTH_MAX })); } embed.setDescription(_.truncate(`${customInfo.body}`, { length: this.util.embed.DESCRIPTION_LENGTH_MAX })); embed.setColor(this.ESMBot.colors.BLUE); } else { let notifications = await this.db.getNotifications(this.values.communityID, this.params.type); if (_.isEmpty(notifications)) { notifications = this.getBackupNotification(); } let notification = this.util.selectRandom(notifications); this.formatNotification(notification, embed); } return embed; } formatNotification(notification, embed) { if (!_.isEmpty(notification.title)) { embed.setTitle( _.truncate( this.replaceTemplates(notification.title), { length: this.util.embed.TITLE_LENGTH_MAX } ) ); } if (!_.isEmpty(notification.message)) { embed.setDescription( _.truncate( this.replaceTemplates(notification.message), { length: this.util.embed.DESCRIPTION_LENGTH_MAX } ) ); } if (notification.color === "random") { embed.setColor(this.util.selectRandom(_.values(this.ESMBot.colors))); } else { embed.setColor(notification.color); } } replaceTemplates(template) { return template .replace(/{{\s*serverid\s*}}/gi, this.values.serverID) .replace(/{{\s*servername\s*}}/gi, this.values.serverName) .replace(/{{\s*communityid\s*}}/gi, this.values.communityID) .replace(/{{\s*territoryname\s*}}/gi, this.values.territoryName) .replace(/{{\s*territoryid\s*}}/gi, this.values.territoryID) .replace(/{{\s*item\s*}}/gi, this.values.marxetItem) .replace(/{{\s*amount\s*}}/gi, this.values.marxetAmount) .replace(/{{\s*username\s*}}/gi, this.values.userName) .replace(/{{\s*usertag\s*}}/gi, this.values.userTag); } getBackupNotification() { let notification = { category: "", color: "", title: "", message: "" }; switch (this.params.type) { case "base-raid": notification = { category: "xm8", color: "#3ED3FB", message: "Hop on quick, **{{ territoryName }}** (`{{ territoryID }}`) is being raided", title: "Oh noes! {{ territoryName }} is being raided!", type: "base-raid" }; break; case "flag-stolen": notification = { category: "xm8", color: "#C62551", message: "**{{ territoryName }}'s** flag has been stolen! Go get it back!", title: "Flag Stolen `({{ territoryID }})`", type: "flag-stolen" }; break; case "flag-restored": notification = { category: "xm8", color: "#9FDE3A", message: "**{{ territoryName }}'s** flag has been restored! Good job getting it back!", title: "Flag Restored `({{ territoryID }})`", type: "flag-restored" }; break; case "protection-money-due": notification = { category: "xm8", color: "#DECA39", message: "**{{ territoryName }}'s** protection money is due today!\nUse `!pay {{ serverID }}, {{ territoryID }}` to make a payment!", title: "Protection Money Due `({{ territoryID }})`", type: "protection-money-due" }; break; case "protection-money-paid": notification = { category: "xm8", color: "#3ED3FB", message: "**{{ territoryName }}'s** protection money has been paid", title: "Protection Money Paid `({{ territoryID }})`", type: "protection-money-paid" }; break; case "charge-plant-started": notification = { category: "xm8", color: "#DE7839", message: "Someone set us up the bomb. **{{ territoryName }}** is about to go BOOM!", title: "Charge Planted `({{ territoryID }})`", type: "charge-plant-started" }; break; case "grind-started": notification = { category: "xm8", color: "#DE7839", message: "Some scalliwag is tryna grind yer locks! **{{ territoryName }}** is being raided!", title: "Grinding Started `({{ territoryID }})`", type: "grind-started" }; break; case "hack-started": notification = { category: "xm8", color: "#DE7839", message: "H4x0rs are trying to get into your stuff! **{{ territoryName }}** is being robbed! ", title: "Hacking Started `({{ territoryID }})`", type: "hack-started" }; break; case "flag-steal-started": notification = { category: "xm8", color: "#DE7839", message: "Someone is trying to steal **{{ territoryName }}'s** flag!", title: "Flag Steal Started `({{ territoryID }})`", type: "flag-steal-started" }; break; case "marxet-item-sold": notification = { category: "xm8", color: "#9FDE3A", message: "You just sold **{{ item }}** for **{{ amount }}** poptabs", title: "Item sold on MarXet", type: "marxet-item-sold" }; break; } return [notification]; } }