Skip to content

Commit

Permalink
#103 created a broadcast "safe" method for event creation.
Browse files Browse the repository at this point in the history
now i need to do it for event edits.
  • Loading branch information
jcolson committed Mar 15, 2021
1 parent 4bec738 commit 3c18f0b
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 66 deletions.
3 changes: 3 additions & 0 deletions bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ const roll = require('./handlers/roll.js');
const DEFAULT_CONFIGDIR = __dirname;
const client = new Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });

Client.prototype.dnd_users = users;

require('log-timestamp')(function () { return `[${new Date().toISOString()}] [shrd:${client.shard.ids}] %s` });

global.vaultVersion = require('./package.json').version;
global.Config = require(path.resolve(process.env.CONFIGDIR || DEFAULT_CONFIGDIR, './config.json'));
global.client = client;

/**
* connect to the mongodb
Expand Down
92 changes: 59 additions & 33 deletions handlers/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,64 @@ const utils = require('../utils/utils.js');
* @param {GuildModel} guildConfig
*/
async function handleEventCreate(msg, guildConfig) {
let eventChannel = msg.channel;
let eventChannelID = guildConfig.channelForEvents ? guildConfig.channelForEvents : msg.channel.id;
try {
let currUser = await UserModel.findOne({ userID: msg.member.id, guildID: msg.guild.id });
if (!currUser || !currUser.timezone) {
// throw new Error('Please set your timezone first using `timezone [YOUR TIMEZONE]`!');
await utils.sendDirectOrFallbackToChannel([
{ name: 'Your Timezone', value: `<@${msg.member.id}>, you have no Timezone set yet, use \`${guildConfig.prefix}timezone Europe/Berlin\`, for example.` },
{ name: 'Timezone Lookup', value: `<${Config.httpServerURL}/timezones?guildID=${msg.guild.id}&channel=${msg.channel.id}>` }
], msg);
let eventString = msg.content.substring((guildConfig.prefix + 'event create').length);
let eventCreateResult = await bc_eventCreate(msg.member.id, eventChannelID, msg.guild.id, eventString);
if (eventCreateResult) {
await msg.delete();
} else {
let eventString = msg.content.substring((guildConfig.prefix + 'event create').length);
let eventArray = parseEventString(eventString);
throw new Error("Could not create event.");
}
} catch (error) {
console.error('events.handleEventCreate:', error.message);
await utils.sendDirectOrFallbackToChannel([
{ name: 'Error', value: `${error.message}` },
{ name: 'Timezone Lookup', value: `<${Config.httpServerURL}/timezones?guildID=${msg.guild.id}&channel=${msg.channel.id}>` }
], msg);
}
}

let validatedEvent = await validateEvent(eventArray, msg, currUser);
if (guildConfig.channelForEvents) {
eventChannel = await msg.guild.channels.resolve(guildConfig.channelForEvents);
/**
* broadcast safe method of event creation
* @param {String} currUserId
* @param {String} channelIDForEvent
* @param {String} guildID
* @param {String} eventString
* @returns
*/
async function bc_eventCreate(currUserId, channelIDForEvent, guildID, eventString) {
try {
let theGuild = client.guilds.cache.get(guildID);
if (theGuild) {
let currUser = await UserModel.findOne({ userID: currUserId, guildID: guildID });
if (!currUser || !currUser.timezone) {
throw new Error('Please set your timezone first using `timezone [YOUR TIMEZONE]`!');
} else {
let eventArray = parseEventString(eventString);
let validatedEvent = await validateEvent(eventArray, guildID, currUser);
let eventChannel = await theGuild.channels.resolve(channelIDForEvent);
let sentMessage = await eventChannel.send(await embedForEvent(theGuild.iconURL(), [validatedEvent], undefined, true));
validatedEvent.channelID = sentMessage.channel.id;
validatedEvent.messageID = sentMessage.id;
await validatedEvent.save();
await sentMessage.react('✅');
await sentMessage.react('❎');
await sentMessage.react('▶️');
await sentMessage.react('🕟');
await sentMessage.react(`\u{1F5D1}`);
await utils.sendDirectOrFallbackToChannel([{ name: '🗡 Event Create 🛡', value: `<@${currUserId}> - created event successfully.`, inline: true }], sentMessage, await client.users.resolve(currUserId));
return true;
}
let sentMessage = await eventChannel.send(await embedForEvent(msg, [validatedEvent], undefined, true));
validatedEvent.channelID = sentMessage.channel.id;
validatedEvent.messageID = sentMessage.id;
await validatedEvent.save();
await sentMessage.react('✅');
await sentMessage.react('❎');
await sentMessage.react('▶️');
await sentMessage.react('🕟');
await sentMessage.react(`\u{1F5D1}`);
await utils.sendDirectOrFallbackToChannel([{ name: '🗡 Event Create 🛡', value: `<@${msg.member.id}> - created event successfully.`, inline: true }], sentMessage, msg.author);
await msg.delete();
} else {
console.log('events.bc_eventCreate: unknown guild on this shard, ignoring');
}
} catch (error) {
console.error('handleEventCreate:', error.message);
error.message += ` For Channel: ${eventChannel.name}`;
await utils.sendDirectOrFallbackToChannelError(error, msg);
console.error('events.bc_eventCreate:', error.message);
error.message += ` For Channel: ${channelIDForEvent}`;
throw error;
}
return false;
}

async function handleEventEdit(msg, guildConfig) {
Expand Down Expand Up @@ -77,7 +101,7 @@ async function handleEventEdit(msg, guildConfig) {
throw new Error(`Please have <@${existingEvent.userID}> edit, or ask an <@&${guildConfig.arole}> to edit.`);
}
let eventArray = parseEventString(eventString, existingEvent);
let validatedEvent = await validateEvent(eventArray, msg, currUser, existingEvent);
let validatedEvent = await validateEvent(eventArray, msg.guild.id, currUser, existingEvent);
validatedEvent.reminderSent = undefined;
let eventMessage;
try {
Expand Down Expand Up @@ -271,7 +295,7 @@ async function handleEventListDeployed(msg, guildConfig) {
* @param {UserModel} currUser
* @returns {EventModel}
*/
async function validateEvent(eventArray, msg, currUser, existingEvent) {
async function validateEvent(eventArray, guildID, currUser, existingEvent) {
if ((!eventArray['!TITLE'] && !existingEvent && !existingEvent.title) || eventArray['!TITLE'] === null) {
throw new Error('You must include a title for your event.');
} else if ((!eventArray['!FOR'] && eventArray['!FOR'] === null && !existingEvent && !existingEvent.duration) || eventArray['!FOR'] === null) {
Expand All @@ -290,7 +314,7 @@ async function validateEvent(eventArray, msg, currUser, existingEvent) {
throw new Error(`The number of player slots needs to be a number, not: "${eventArray['!WITH']}"`);
}

let validatedEvent = existingEvent ? existingEvent : new EventModel({ guildID: msg.guild.id, userID: msg.member.id });
let validatedEvent = existingEvent ? existingEvent : new EventModel({ guildID: guildID, userID: currUser.userID });

if (eventArray['!ON'] || eventArray['!AT']) {
let timezoneOffset = getTimeZoneOffset(currUser.timezone);
Expand Down Expand Up @@ -407,14 +431,14 @@ function nextValidIndex(startindex, sepIndexArray) {
/**
* returns the MessageEmbed(s) for an array of events passed
*
* @param {Message} msg
* @param {String} guildIconURL
* @param {EventModel[]} charArray
* @param {String} title
* @param {Boolean} isShow
*
* @returns {MessageEmbed[]}
*/
async function embedForEvent(msg, eventArray, title, isShow) {
async function embedForEvent(guildIconURL, eventArray, title, isShow) {
let returnEmbeds = [];
// return 3 events for show and 8 events for a list
let charPerEmbed = isShow ? 1 : 4;
Expand All @@ -429,7 +453,8 @@ async function embedForEvent(msg, eventArray, title, isShow) {
// .setURL('https://discord.js.org/')
.setAuthor('Event Coordinator', Config.dndVaultIcon, 'https://github.com/jcolson/dndvault-bot')
// .setDescription(description)
.setThumbnail(msg.guild.iconURL());
.setThumbnail(guildIconURL);
// .setThumbnail(msg.guild.iconURL());
let i = 0;
for (let theEvent of eventArray) {
if (i++ >= charPerEmbed) {
Expand Down Expand Up @@ -769,3 +794,4 @@ exports.handleEventListProposed = handleEventListProposed;
exports.handleEventListDeployed = handleEventListDeployed;
exports.getLinkForEvent = getLinkForEvent;
exports.sendReminders = sendReminders;
exports.bc_eventCreate = bc_eventCreate;
59 changes: 37 additions & 22 deletions handlers/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,33 @@ async function handleDefault(msg, guildConfig) {
}
}

async function handleWebTimezone(userID, channelID, timezone, guildConfig) {
console.log(`${userID} ${channelID} ${timezone} ${guildConfig.prefix}`);
/**
* handle updating timezone in a broadcast safe manner
* @param {String} userID
* @param {String} channelID
* @param {String} timezone
* @param {String} guildID
* @returns boolean
*/
async function bc_setUsersTimezone(userID, channelID, timezone, guildID) {
console.log(`users.bc_setUsersTimezone: ${userID} ${channelID} ${timezone} ${guildID}`);
try {
let currUser = await UserModel.findOne({ userID: userID, guildID: guildConfig.guildID });
timezone = isValidTimeZone(timezone);
if (!currUser) {
currUser = new UserModel({ guildID: guildConfig.guildID, userID: userID, timezone: timezone });
} else {
// console.log('setting timezone to "%s"', timeZoneString);
currUser.timezone = timezone;
if (client.guilds.cache.get(guildID)) {
let currUser = await UserModel.findOne({ userID: userID, guildID: guildID });
timezone = isValidTimeZone(timezone);
if (!currUser) {
currUser = new UserModel({ guildID: guildID, userID: userID, timezone: timezone });
} else {
console.log('users.bc_setUsersTimezone: setting timezone to "%s"', timezone);
currUser.timezone = timezone;
}
await currUser.save();
return true;
}
await currUser.save();
} catch (error) {
console.error(`handleWebTimezone ${error.message}`);
return false;
console.error(`users.bc_setUsersTimezone ${error.message}`);
}
return true;
return false;
}

/**
Expand All @@ -73,19 +83,24 @@ async function handleTimezone(msg, guildConfig) {
{ name: 'Timezone Lookup', value: `<${Config.httpServerURL}/timezones?guildID=${msg.guild.id}&channel=${msg.channel.id}>` }
], msg);
} else {
timeZoneString = isValidTimeZone(timeZoneString);
if (!currUser) {
currUser = new UserModel({ guildID: msg.guild.id, userID: msg.member.id, timezone: timeZoneString });
let timezoneResult = await bc_setUsersTimezone(msg.member.id, msg.channel.id, timeZoneString, msg.guild.id);
// timeZoneString = isValidTimeZone(timeZoneString);
// if (!currUser) {
// currUser = new UserModel({ guildID: msg.guild.id, userID: msg.member.id, timezone: timeZoneString });
// } else {
// // console.log('setting timezone to "%s"', timeZoneString);
// currUser.timezone = timeZoneString;
// }
// await currUser.save();
if (timezoneResult) {
await utils.sendDirectOrFallbackToChannel([{ name: 'Timezone', value: `<@${msg.member.id}>, your timezone was successfully set to: ${currUser.timezone}` }], msg);
} else {
// console.log('setting timezone to "%s"', timeZoneString);
currUser.timezone = timeZoneString;
throw new Error(`Could not set timezone: ${timeZoneString}`);
}
await currUser.save();
await utils.sendDirectOrFallbackToChannel([{ name: 'Timezone', value: `<@${msg.member.id}>, your timezone was successfully set to: ${currUser.timezone}` }], msg);
}
await msg.delete();
} catch (error) {
console.log('handleTimezone:', error);
console.log('users.handleTimezone:', error);
error.message += `\nexample timezone: \`Europe/Berlin\`\nTimezone Lookup: <${Config.httpServerURL}/timezones?guildID=${msg.guild.id}&channel=${msg.channel.id}>`;
await utils.sendDirectOrFallbackToChannelError(error, msg);
}
Expand Down Expand Up @@ -136,4 +151,4 @@ async function hasRoleOrIsAdmin(member, roleId) {
exports.handleTimezone = handleTimezone;
exports.hasRoleOrIsAdmin = hasRoleOrIsAdmin;
exports.handleDefault = handleDefault;
exports.handleWebTimezone = handleWebTimezone;
exports.bc_setUsersTimezone = bc_setUsersTimezone;
23 changes: 12 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const { ShardingManager } = require('discord.js');
const path = require('path');
const fetch = require('node-fetch');
const url = require('url');
const users = require('./handlers/users.js');
const { connect, disconnect } = require('mongoose');

const GuildModel = require('./models/Guild');
Expand All @@ -21,8 +20,6 @@ const session = require('express-session');
const Grant = require('grant').express();
const grant = new Grant(Config);

// const grant = require('grant').express();

let shutdown = false;

/**
Expand Down Expand Up @@ -193,18 +190,22 @@ let server = app
let requestUrl = new URL(request.url, `${request.protocol}://${request.headers.host}`);
// console.log(request.session.discordMe);
// console.log(requestUrl);
let status = await users.handleWebTimezone(
request.session.discordMe.id,
request.session.grant.dynamic.channel,
requestUrl.searchParams.get('timezone'),
request.session.guildConfig);
response.json({ status: status });
const timezoneToSet = requestUrl.searchParams.get('timezone');
let status = await manager.broadcastEval(
`this.dnd_users.bc_setUsersTimezone
('${request.session.discordMe.id}',
'${request.session.grant.dynamic.channel}',
'${timezoneToSet}',
'${request.session.guildConfig.guildID}');`
);
console.log(`users.bc_setUsersTimezone response: ${status.includes(true)}`);
response.json({ status: status.includes(true) });
} else {
console.log(`we don't know the guild so we will error and let the user copy/paste`);
response.json({ status: 'false' });
}
} catch (error) {
console.error(error.message);
console.error(`error: route: ${ROUTE_TIMEZONESSET} - ${error.message}`);
response.setHeader('Content-Type', 'text/html');
response.status(500);
response.json({ status: 'false' });
Expand Down Expand Up @@ -235,7 +236,7 @@ let server = app
console.log(`event is not owned by current user, dereferencing`);
event = undefined;
}
let userConfig = await UserModel.findOne({userID: request.session.discordMe.id, guildID: request.session.guildConfig.guildID});
let userConfig = await UserModel.findOne({ userID: request.session.discordMe.id, guildID: request.session.guildConfig.guildID });
// console.log(userConfig);
response.render('events', { title: 'Events', event: event, Config: Config, guildConfig: request.session.guildConfig, discordMe: request.session.discordMe, userConfig: userConfig })
} catch (error) {
Expand Down

0 comments on commit 3c18f0b

Please sign in to comment.