mirror of
https://github.com/ION606/selmerBot.git
synced 2026-05-15 05:36:54 +00:00
Added the 'import_ics' command
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
const { ICalParser } = require('cozy-ical');
|
||||
const { URL } = require('url');
|
||||
const { Constants } = require('discord.js');
|
||||
const request = require('request');
|
||||
const { verPremium } = require('../premium/verifyPremium.js');
|
||||
|
||||
|
||||
//#region SET REMINDERS
|
||||
|
||||
function addReminder(interaction, bot, obj, Id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
bot.mongoconnection.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': Id })).then((doc) => {
|
||||
const t = obj.time.toString();
|
||||
try {
|
||||
if (doc.times.indexOf(obj.time) == -1) {
|
||||
kbo.updateOne({ 'userId': Id }, { $push: { times: t } })
|
||||
} else {
|
||||
//Event already exists at this time
|
||||
reject("An event already exists at this time!");
|
||||
return; // interaction.channel.send("An event already exists at this time!");
|
||||
}
|
||||
|
||||
//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 });
|
||||
resolve(true);
|
||||
}).catch((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!");
|
||||
reject(err);
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log("ERR");
|
||||
console.error(err);
|
||||
reject(false);
|
||||
// interaction.reply("Uh Oh! An error has occured!");
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// return interaction.reply("Uh Oh! An error has occured!"); // Gets "acknowledged" too many times
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
|
||||
//#region SETUP AND PARSING
|
||||
function isValidUrl(s) {
|
||||
try {
|
||||
new URL(s);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class calClass {
|
||||
constructor(vevent) {
|
||||
const model = vevent.model;
|
||||
const alarms = vevent.subComponents;
|
||||
|
||||
if (alarms && alarms[0] && alarms[0].model) {
|
||||
let temp = alarms[0].model.trigger;
|
||||
temp = temp.split('DT')[1];
|
||||
temp = temp.split("H");
|
||||
|
||||
let hours = (temp[0] && temp[0] != '0') ? Number(temp[0]) : 0;
|
||||
let minutesStr = temp[1].split('M')[0];
|
||||
let minutes = (minutesStr && !isNaN(minutesStr)) ? hours + Number(minutesStr) : hours;
|
||||
|
||||
this.offset = minutes;
|
||||
} else {
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
this.name = model.summary;
|
||||
this.description = (model.description) ? model.description : "N/A";
|
||||
|
||||
const dateTime = new Date(model.startDate);
|
||||
this.time = dateTime.getTime()/1000;
|
||||
|
||||
if (isValidUrl(model.location)) {
|
||||
this.url = model.location || undefined;
|
||||
this.loc = undefined;
|
||||
} else {
|
||||
this.url = undefined;
|
||||
this.loc = model.location || undefined;
|
||||
}
|
||||
}
|
||||
|
||||
isValidUrl(s) {
|
||||
try {
|
||||
new URL(s);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
exportAsObj(gid, uid) {
|
||||
const obj = { time: this.time, event: { guildId: gid, userId: uid, name: this.name, description: this.description, offset: this.offset, link: this.url, location: this.loc } }
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function parseData(calStr, gid, uid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const parser = new ICalParser();
|
||||
parser.parseString(calStr, function(err, cal) {
|
||||
try {
|
||||
const arr = [];
|
||||
|
||||
for (i in cal.subComponents) {
|
||||
const a = new calClass(cal.subComponents[i]);
|
||||
arr.push(a.exportAsObj(gid, uid));
|
||||
}
|
||||
|
||||
resolve(arr);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {String} fileName
|
||||
*/
|
||||
function readFileAndParse(url, bot, interaction, gid, uid) {
|
||||
request.get(url, function (error, response, body) {
|
||||
try {
|
||||
if (!error && response.statusCode == 200) {
|
||||
const isGuild = (gid && !uid) || false;
|
||||
const notAdded = [];
|
||||
|
||||
const Id = (isGuild) ? gid : uid;
|
||||
|
||||
parseData(body, gid, uid).then((arr) => {
|
||||
|
||||
new Promise((resolve, reject) => {
|
||||
// If the key does not exist, create it
|
||||
if (arr.length > 0) {
|
||||
bot.mongoconnection.then((client) => {
|
||||
const kbo = client.db('main').collection('reminderKeys');
|
||||
kbo.findOne(({ 'userId': Id })).then((doc) => {
|
||||
if (!doc) {
|
||||
doc = { userId: Id, times: [] }
|
||||
kbo.insertOne(doc);
|
||||
|
||||
reject("New user created, please try again!");
|
||||
} else {
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
reject("No data...");
|
||||
}
|
||||
|
||||
// const m = new Map(arr.map((obj, ind) => { return [ind, obj]; }));
|
||||
}).then(() => {
|
||||
Promise.all(arr.map((obj, ind) => {
|
||||
addReminder(interaction, bot, obj, Id).then(() => {})
|
||||
.catch((err) => {
|
||||
notAdded.push(err);
|
||||
});
|
||||
})).then((t) => {
|
||||
const r1 = { content: `ITEMS NOT ADDED:\n${notAdded.join("\n")}`, ephemeral: true }
|
||||
|
||||
if (r1.content != "ITEMS NOT ADDED:\n") {
|
||||
interaction.reply(r1).catch((err) => { interaction.channel.send(r1); });
|
||||
} else {
|
||||
const r2 = `All ${arr.length} items added to calendar!`;
|
||||
interaction.reply(r2).catch((err) => { interaction.channel.send(r2); });
|
||||
}
|
||||
});
|
||||
}).catch((err) => {
|
||||
interaction.reply(err);
|
||||
})
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
interaction.reply({ content: "Uh oh, there's been an error!", ephemeral: true});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: 'import_ics',
|
||||
description: 'Import events using a calendar',
|
||||
async execute(interaction, Discord, Client, bot) {
|
||||
//Check if the user has premium
|
||||
await verPremium(bot, interaction.user.id).then(() => {
|
||||
const url = interaction.options.data[0].attachment.attachment;
|
||||
|
||||
if (!url.endsWith(".ics")) {
|
||||
return interaction.reply("Please use a valid ***.ics*** file!")
|
||||
}
|
||||
|
||||
let uid, gid;
|
||||
if (interaction.channel.type == 'DM') {
|
||||
uid = interaction.user.id;
|
||||
} else {
|
||||
gid = interaction.guildId;
|
||||
}
|
||||
readFileAndParse(url, bot, interaction, gid, uid);
|
||||
}).catch(() => {
|
||||
interaction.reply("You have to be a premium subscriber to use this feature!");
|
||||
});
|
||||
},
|
||||
options: [
|
||||
{name: 'ics_file', description: 'The ics file to input', type: Constants.ApplicationCommandOptionTypes.ATTACHMENT, required: true},
|
||||
],
|
||||
isDm: true
|
||||
}
|
||||
@@ -190,57 +190,78 @@ function addEvent(obj, connection, interaction, embd) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns { Promise<[]> | Promise<[false, []] | [true, String]>} (all events) || (custom err) ? [true, err] : [false, err]
|
||||
*/
|
||||
function getEvents(bot, interaction, id, jpage = 0, isGuild = false, refered = false, isExport = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var userId = false;
|
||||
var guildId = false;
|
||||
const numperpage = 5;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (isGuild) {
|
||||
guildId = id;
|
||||
} else {
|
||||
userId = id;
|
||||
}
|
||||
bot.mongoconnection.then((client) => {
|
||||
try {
|
||||
var times;
|
||||
const dbo = client.db('main').collection('reminderKeys');
|
||||
|
||||
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`
|
||||
}
|
||||
//ReminderKeys are all stored as userId, the reminders themselves are not
|
||||
dbo.findOne({$or: [ {userId: userId}, {userId: guildId} ]}).then((doc) => {
|
||||
if (!doc) {
|
||||
if (isExport) {
|
||||
return reject([true, "No events exist!"]);
|
||||
}
|
||||
|
||||
return interaction.reply("No events exist!");
|
||||
}
|
||||
|
||||
//Create the embed
|
||||
postEmbd(bot, temp, interaction, jpage, isGuild, id, refered);
|
||||
times = doc.times;
|
||||
const tbo = client.db('main').collection('reminders');
|
||||
|
||||
tbo.find({time: {$in: times}}).toArray((err, docs) => {
|
||||
|
||||
if (isExport) {
|
||||
return resolve(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);
|
||||
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return interaction.reply("Uh Oh! There's been an error!");
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
if (isExport) {
|
||||
return reject([false, err]);
|
||||
}
|
||||
return interaction.reply("Uh Oh! There's been an error!");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -410,6 +431,6 @@ module.exports = {
|
||||
}
|
||||
});
|
||||
});
|
||||
}, modalHandle, turnPage,
|
||||
}, modalHandle, turnPage, addEvent, getEvents,
|
||||
options: []
|
||||
}
|
||||
Reference in New Issue
Block a user