diff --git a/commands/admin/setup.js b/commands/admin/setup.js index c92886b..518154a 100644 --- a/commands/admin/setup.js +++ b/commands/admin/setup.js @@ -78,7 +78,14 @@ async function execute(bot, message, args, command, Discord, mongouri, items, xp if (!l.includes(tier)) { return message.reply("Please select an existing tier ('none', 'low', 'medium', 'high')"); } dbo.updateOne({_id: 'LOG'}, {$set: {severity: tier}}) - } + } else if (command == 'announcement_role') { + const role = message.mentions.roles.first().id; + dbo.updateOne({_id: 'announcement'}, { $set: { 'role': role } }); + } else if (command == "announcement_channel") { + const channel = message.guild.channels.cache.find(ch => ch.name === args[1]); + if (!channel) { return message.reply('The specified channel does not exist!'); } + dbo.updateOne({_id: 'announcement'}, { $set: { 'channel': channel } }); + } else if (command == 'help') { let temp; @@ -88,7 +95,9 @@ async function execute(bot, message, args, command, Discord, mongouri, items, xp temp = 'To enable logging, use the command _!setup keep\\_logs true_ and _!setup log\\_channel_ [channel name] to set the logging channel!\n'; temp += 'Use _!setup keep\\_logs false_ to disable logging and _!setup log\\_severity [none, low, medium, high]_ to set the threshold\n'; temp += '__Severities:__\n*none* - unmute, unban\n*low* - mute\n*medium* - kick\n*high* - ban\nEvery tier also includes all notifs for ***higher*** tiers (AKA _!setup log\\_severity none_ will log everything from every severity)\n'; - } else { temp = 'Please use the following format: _!setup help [welcome, logs]_\nExample: _!setup help welcome_'; } + } else if (args[1] == 'announcement') { + temp = "To pick the announcement channel, use _!setup announcement\\_channel_\nTo pick the announcement role, use _!setup announcement\\_role_"; + } else { temp = 'Use _!setup Please use the following format: _!setup help [welcome, logs, announcement]_\nExample: _!setup help welcome_'; } message.reply(temp); } diff --git a/commands/dm_handler.js b/commands/dm_handler.js index 05f7c1c..cbeac7f 100644 --- a/commands/dm_handler.js +++ b/commands/dm_handler.js @@ -1,5 +1,6 @@ const { convoManager } = require('./premium/chat.js'); const { handleInp } = require('./premium/stripe'); +const reminders = require('./premium/reminders.js') const { MongoClient, ServerApiVersion, ConnectionClosedEvent } = require('mongodb'); function handle_dm(message, bot) { @@ -9,10 +10,8 @@ function handle_dm(message, bot) { const member = bot.guilds.cache.get(bot.home_server).members.cache.get(message.author.id); bot.mongoconnection.then(async (client) => { - // if (err) { return console.log(err); } - const dbo = client.db('main').collection('authorized'); - dbo.find({id: message.author}).toArray((err, docs) => { + dbo.find({ discordID: message.author.id }).toArray((err, docs) => { //Only available to Selmer Bot devs, testers and "authorized" users if (docs[0] != undefined || member.roles.cache.has('944048889038774302') || member.roles.cache.has('946610800418762792')) { @@ -25,6 +24,8 @@ function handle_dm(message, bot) { } else if (message.content.indexOf('!premium') != -1) { handleInp(bot, message); + } else if (message.content.indexOf('!reminders') != -1) { + reminders.execute(message, null, null, null, bot); } else { return message.reply('UNUSABLE DM COMMAND DETECTED'); } diff --git a/commands/interactionhandler.js b/commands/interactionhandler.js index d1a10b2..df19599 100644 --- a/commands/interactionhandler.js +++ b/commands/interactionhandler.js @@ -2,9 +2,14 @@ const { MongoClient, ServerApiVersion } = require('mongodb'); const { createSubscriptionManual } = require('./premium/stripe.js'); const { pause_start_stop, playNext, showQueue } = require('./misc/playAudio.js'); const { resolveComplaint } = require('./dev only/submitcomplaint.js'); +const reminders = require('./premium/reminders.js'); // const { RSSInteractionHandler } = require('./premium/rssFeed.js'); +const { Interaction } = require('discord.js') - +/** + * + * @param {Interaction} interaction + */ async function handle_interaction(interaction, mongouri, turnManager, bot, STATE, items, xp_collection) { if (interaction.isButton()) { const battlecommandlist = ['ATTACK', 'HEAL', 'DEFEND', 'ITEMS', 'ULTIMATE']; @@ -72,6 +77,10 @@ async function handle_interaction(interaction, mongouri, turnManager, bot, STATE } else if (interaction.customId == 'DEBUGURGENT' || interaction.customId == 'DEBUGDONE') { resolveComplaint(interaction); + } else if (interaction.customId.indexOf('newEvent') != -1 || interaction.customId.indexOf('getEvents') != -1) { + reminders.modalHandle(bot, interaction); + } else if (interaction.customId.indexOf('reminderQueue') != -1) { + reminders.turnPage(bot, interaction); } //Button else ifs here }); } @@ -83,7 +92,6 @@ async function handle_interaction(interaction, mongouri, turnManager, bot, STATE if (interaction.customId.toLowerCase().indexOf('|heal') != -1) { bot.mongoconnection.then(client => { - console.log(id); if (id != interaction.user.id) { return; } let current_user = turnManager.getTurn(client, bot, interaction); @@ -132,6 +140,11 @@ async function handle_interaction(interaction, mongouri, turnManager, bot, STATE } /*else if (interaction.customId.indexOf('RSS') != -1) { RSSInteractionHandler(bot, interaction); }*/ //menu else ifs here + } + + //Forms + else if (interaction.isModalSubmit()) { + reminders.modalHandle(bot, interaction); } //other selection types here } diff --git a/commands/misc/help.js b/commands/misc/help.js index 6116b35..42304ee 100644 --- a/commands/misc/help.js +++ b/commands/misc/help.js @@ -1,5 +1,5 @@ const { modHelp } = require('../admin/moderation.js'); - +//CHANGE THIS TO FORMS? module.exports ={ name: "help", description: "Gets help for all of Selmer Bot's commands", diff --git a/commands/premium/chat.js b/commands/premium/chat.js index 807bda2..649f144 100644 --- a/commands/premium/chat.js +++ b/commands/premium/chat.js @@ -38,7 +38,7 @@ async function getResponse(convo, bot) { return response; } - async function convoManager(clientinp, bot, message) { +async function convoManager(clientinp, bot, message) { //Just in case, make sure it can't be changed const client = clientinp; diff --git a/commands/premium/reminders.js b/commands/premium/reminders.js index e69de29..dfd2619 100644 --- a/commands/premium/reminders.js +++ b/commands/premium/reminders.js @@ -0,0 +1,409 @@ +const { Modal, TextInputComponent, MessageActionRow, MessageButton, MessageEmbed, Interaction } = require('discord.js'); + + +/** + * @param {Interaction} interaction + */ +function postEmbd(bot, desc, interaction, page, isGuild, id, refered) { + try { + const author = { + name: "Selmer Bot", + url: "", + iconURL: bot.user.displayAvatarURL() + }; + + const newEmbed = new MessageEmbed() + .setTitle("REMINDERS") + .setAuthor(author) + .setDescription(desc[page]) + .setFooter({ text: `Page ${page + 1}` }); + + + const row = new MessageActionRow(); + //Make sure the page is never < 1 + const prevbtn = new MessageButton() + .setCustomId(`reminderQueue|${isGuild}-${id}|`) + .setLabel('⬅️') + .setStyle('SECONDARY') + + if (page <= 0) { + prevbtn.customId += `0`; + // prevbtn.setCustomId(`reminderQueue|${isGuild}-${id}|0`); + prevbtn.setDisabled(true); + } else { + prevbtn.customId += `${page - 1}`; + } + + const nextbtn = new MessageButton() + .setCustomId(`reminderQueue|${isGuild}-${id}|`) + .setLabel('➡️') + .setStyle('SECONDARY'); + + if ((page + 1) >= desc.length) { + nextbtn.customId += `${desc.length}`; + // nextbtn.setCustomId(`reminderQueue|`); + nextbtn.setDisabled(true); + } else { + nextbtn.customId += `${page + 1}`; + } + + row.addComponents(prevbtn, nextbtn); + + if (page > 0 || refered) { + interaction.update({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [newEmbed], components: [row] }); + } else { + interaction.reply({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [newEmbed], components: [row] }); + } + } catch (err) { + console.log(err); + return interaction.reply("Uh Oh! There's been an error!"); + } +} + + +async function postForm(interaction, isGuild = false) { + // Create the modal + const modal = new Modal(); + + if (!isGuild) { + modal.setTitle('Creating a New Personal Reminder') + .setCustomId('newEventModal|user'); + } else { + modal.setTitle('Creating a New Guild Reminder') + .setCustomId('newEventModal|guild'); + } + + // Add components to modal + // Create the text input components + // The label is the prompt the user sees for this input + // Short means only a single line of text + // Paragraph means multiple lines of text + + const nameInp = new TextInputComponent() + .setCustomId('name') + .setLabel("What is the Event's name?") + .setStyle('SHORT'); + + const descInp = new TextInputComponent() + .setCustomId('description') + .setLabel("What's the event's description?") + .setStyle('PARAGRAPH'); + + const dateInp = new TextInputComponent() + .setCustomId('date') + .setLabel("What's the event's date?") + .setPlaceholder('1/1/2020') + .setStyle('SHORT'); + + const timeInp = new TextInputComponent() + .setCustomId('time') + .setLabel("What's the event's time?") + .setPlaceholder("2:00 PM or 14:00") + .setStyle('SHORT'); + + + const locurlinp = new TextInputComponent() + .setCustomId('locationwurl') + .setLabel("Where is the event happening?") + .setPlaceholder('To add a URL, simply use location;url (the seperator is a semi-colon)') + .setStyle('SHORT'); + + // An action row only holds one text input, + // so you need one action row per text input. + const name = new MessageActionRow().addComponents(nameInp); + const desc = new MessageActionRow().addComponents(descInp); + const date = new MessageActionRow().addComponents(dateInp); + const time = new MessageActionRow().addComponents(timeInp); + const offset = new MessageActionRow().addComponents(locurlinp); + + // Add inputs to the modal + modal.addComponents(name, desc, date, time, offset); + + // Show the modal to the user + interaction.showModal(modal); +} + + + +//#region DATABASE PROCESSING +//ADD SERVER SUPPORT +function addEvent(obj, connection, interaction, embd) { + try { + // console.log(obj.time, typeof obj.time); return; + + connection.then((client) => { + // Update the Key object first to check if the time is already there + const kbo = client.db('main').collection('reminderKeys'); + kbo.findOne(({ 'userId': obj.event.userId })).then((doc) => { + const t = obj.time.toString(); + try { + if (doc) { + if (doc.times.indexOf(obj.time) == -1) { + kbo.updateOne({ 'userId': obj.event.userId }, { $push: { times: t } }) + } else { + //Event already exists at this time + return interaction.reply("An event already exists at this time!"); + } + } else { + doc = { userId: obj.event.userId, times: [t] } + kbo.insertOne(doc); + } + + + //Update the Time object + const dbo = client.db('main').collection('reminders'); + dbo.findOne({ time: t }).then((doc) => { + let n = 0; + if (doc) { + n = doc.amt; + doc.amt ++; + + doc[`${n}`] = obj.event; + dbo.findOneAndReplace({ time: t }, doc); + } else { + const d = new Date(Number(obj.time)); + doc = { "0": obj.event, "time": t, "month": d.getMonth(), "amt": 1 }; //Month used for clearing when the calendar month begins (maybe modify the garbage collection with an `else if (day == 1? clear last month)` ) + dbo.insertOne(doc); + } + + //Reply with the reminder in correct format + interaction.reply({ content: "REMINDER SAVED!", embeds: [embd], ephemeral: true }); + }).catch((err) => { + console.log("ERR"); + console.error(err); + interaction.reply("Uh Oh! An error has occured!"); + }); + } catch (err) { + console.error(err); interaction.reply("Uh Oh! An error has occured!"); + } + }).catch((err) => { + console.log("ERR"); + console.error(err); + interaction.reply("Uh Oh! An error has occured!"); + }); + }); + } catch (err) { + console.error(err); + return interaction.reply("Uh Oh! An error has occured!"); + } +} + + +function getEvents(bot, interaction, id, jpage = 0, isGuild = false, refered = false) { + var userId = false; + var guildId = false; + const numperpage = 5; + + if (isGuild) { + guildId = id; + } else { + userId = id; + } + + bot.mongoconnection.then((client) => { + try { + var times; + const dbo = client.db('main').collection('reminderKeys'); + + //ReminderKeys are all stored as userId, the reminders themselves are not + dbo.findOne({$or: [ {userId: userId}, {userId: guildId} ]}).then((doc) => { + if (!doc) { return interaction.reply("No events exist!"); } + times = doc.times; + const tbo = client.db('main').collection('reminders'); + + tbo.find({time: {$in: times}}).toArray((err, docs) => { + //There's gotta be a better way + var temp = [""]; + var page = 0; + + for (let i = 0; i < docs.length; i ++) { + if (i != 0 && i % numperpage == 0) { + page ++; + temp[page] = ''; + } + // temp += `__***Events On ${new Date(Number(docs[i].time))}***__\n\n`; + for (let j in docs[i]) { + if (!isNaN(j) && (docs[i][j].userId == userId || docs[i][j].guildId == guildId)) { + const obj = docs[i][j]; + temp[page] += `Name: ${obj.name}\nDescription: ${obj.description}\nDate/Time: ${new Date(Number(docs[i].time))}\nOffset: ${obj.offset}\nLink: ${obj.link}\nLocation: ${obj.location}\n------------------------------\n` + } + } + } + + //Create the embed + postEmbd(bot, temp, interaction, jpage, isGuild, id, refered); + }); + }); + } catch (err) { + console.log(err); + return interaction.reply("Uh Oh! There's been an error!"); + } + }); +} + +//#endregion + + + +//fields: [, , ,