Skip to content

Commit

Permalink
Add challenges to OTL Google calendar.
Browse files Browse the repository at this point in the history
Fixes #296.
  • Loading branch information
roncli committed Jan 5, 2022
1 parent 05f4fb1 commit 7003d73
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 18 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -27,6 +27,7 @@
"discord.js": "13.5.0",
"express": "4.17.2",
"express-minify": "1.0.0",
"googleapis": "92.0.0",
"html-minifier-terser": "6.1.0",
"morgan": "1.10.0",
"node-schedule": "2.1.0",
Expand Down
145 changes: 145 additions & 0 deletions src/calendar.js
@@ -0,0 +1,145 @@
/**
* @typedef {import("googleapis").calendar_v3.Schema$Event} Google.Calendar.SchemaEvent
*/

const google = require("googleapis").google,
Log = require("./logging/log"),
settings = require("../settings").google,

calendar = google.calendar({
version: "v3",
key: settings.key.private_key
});

// ### ## #
// # # # #
// # ### # ### # ## ## # ### # ##
// # # # # # ## # # ## # ## #
// # #### # ##### # # # # #### #
// # # # # # # # # # ## # # #
// ### #### ### ### # # ## # #### #
/**
* A class that handles calls to Google Calendar.
*/
class Calendar {
// # #
// # #
// ### ### ###
// # # # # # #
// # ## # # # #
// # # ### ###
/**
* Adds a Google Calendar event.
* @param {Google.Calendar.SchemaEvent} event The event.
* @returns {Promise} A promise that returns the calendar event.
*/
static async add(event) {
try {
const res = await calendar.events.insert({
auth: "",
calendarId: settings.calendarId,
requestBody: event
});

if (res.status !== 200) {
Log.exception("Error while creating a Google Calendar entry.", res.statusText);
return void 0;
}

return res.data;
} catch (err) {
Log.exception("Error while creating a Google Calendar entry.", err);
return void 0;
}
}

// # ## #
// # # #
// ### ## # ## ### ##
// # # # ## # # ## # # ##
// # # ## # ## # ##
// ### ## ### ## ## ##
/**
* Deletes a Goolge Calendar event.
* @param {Google.Calendar.SchemaEvent} event The event.
* @returns {Promise} A promise that resolves when the event has been deleted.
*/
static async delete(event) {
try {
const res = await calendar.events.delete({
auth: "",
calendarId: settings.calendarId,
eventId: event.id
});

if (res.status !== 200) {
Log.exception("Error while deleting a Google Calendar entry.", res.statusText);
}
} catch (err) {
Log.exception("Error while deleting a Google Calendar entry.", err);
}
}

// #
// #
// ### ## ###
// # # # ## #
// ## ## #
// # ## ##
// ###
/**
* Gets a Google Calendar event by its ID.
* @param {string} id The event ID.
* @returns {Promise<Google.Calendar.SchemaEvent>} A promise that returns the calendar event.
*/
static async get(id) {
try {
const res = await calendar.events.get({
calendarId: settings.calendarId,
eventId: id
});

if (res.status !== 200) {
Log.exception("Error while retrieving a Google Calendar entry.", res.statusText);
return void 0;
}

return res.data;
} catch (err) {
Log.exception("Error while retrieving a Google Calendar entry.", err);
return void 0;
}
}

// # #
// # #
// # # ### ### ### ### ##
// # # # # # # # # # # ##
// # # # # # # # ## # ##
// ### ### ### # # ## ##
// #
/**
* Adds a Google Calendar event.
* @param {string} id The event ID.
* @param {Google.Calendar.SchemaEvent} event The event.
* @returns {Promise} A promise that resolves when the event has been updated.
*/
static async update(id, event) {
try {
const res = await calendar.events.patch({
auth: "",
calendarId: settings.calendarId,
eventId: id,
requestBody: event
});

if (res.status !== 200) {
Log.exception("Error while updating a Google Calendar entry.", res.statusText);
}
} catch (err) {
Log.exception("Error while updating a Google Calendar entry.", err);
}
}
}

module.exports = Calendar;
9 changes: 6 additions & 3 deletions src/database/challenge.js
Expand Up @@ -1056,7 +1056,8 @@ class ChallengeDb {
c.GameType,
c.SuggestedGameType,
c.SuggestedGameTypeTeamId,
c.DiscordEventId
c.DiscordEventId,
c.GoogleEventId
FROM tblChallenge c
LEFT OUTER JOIN tblPlayer p ON c.CasterPlayerId = p.PlayerId
WHERE c.ChallengeId = @challengeId
Expand Down Expand Up @@ -1111,6 +1112,7 @@ class ChallengeDb {
suggestedGameType: data.recordsets[0][0].SuggestedGameType,
suggestedGameTypeTeamId: data.recordsets[0][0].SuggestedGameTypeTeamId,
discordEventId: data.recordsets[0][0].DiscordEventId,
googleEventId: data.recordsets[0][0].GoogleEventId,
homeMaps: data.recordsets[1] && data.recordsets[1].map((row) => row.Map) || void 0
} || void 0;
}
Expand Down Expand Up @@ -1736,10 +1738,11 @@ class ChallengeDb {
*/
static async setEvent(challenge) {
await db.query(/* sql */`
UPDATE tblChallenge SET DiscordEventId = @discordEventId WHERE ChallengeId = @challengeId
UPDATE tblChallenge SET DiscordEventId = @discordEventId, GoogleEventId = @googleEventId WHERE ChallengeId = @challengeId
`, {
challengeId: {type: Db.INT, value: challenge.id},
discordEventId: {type: Db.VARCHAR(24), value: challenge.details.event.id}
discordEventId: {type: Db.VARCHAR(24), value: challenge.details.discordEvent.id},
googleEventId: {type: Db.VARCHAR(1024), value: challenge.details.googleEvent.id}
});
}

Expand Down
77 changes: 62 additions & 15 deletions src/models/challenge.js
Expand Up @@ -16,7 +16,8 @@
* @typedef {import("../../types/playerTypes").UserOrGuildMember} PlayerTypes.UserOrGuildMember
*/

const Common = require("../../web/includes/common"),
const Calendar = require("../calendar"),
Common = require("../../web/includes/common"),
Db = require("../database/challenge"),
Exception = require("../logging/exception"),
Log = require("../logging/log"),
Expand Down Expand Up @@ -1667,13 +1668,14 @@ class Challenge {
gameType: details.gameType,
suggestedGameType: details.suggestedGameType,
suggestedGameTypeTeam: details.suggestedGameTypeTeamId ? details.suggestedGameTypeTeamId === this.challengingTeam.id ? this.challengingTeam : this.challengedTeam : void 0,
event: await Discord.findEventById(details.discordEventId)
discordEvent: await Discord.findEventById(details.discordEventId),
googleEvent: await Calendar.get(details.googleEventId)
};
}

// ## #
// # #
// # ## ## # #
// # ## ## # #9
// # # # # ##
// # # # # # #
// ### ## ## # #
Expand Down Expand Up @@ -3038,13 +3040,16 @@ class Challenge {

const parameters = [];
const eventParameters = [];
const htmlParameters = [];

if (this.details.dateConfirmed) {
eventParameters.push(`Final Score: **${this.challengingTeam.tag}** ${this.details.challengingTeamScore}, **${this.challengedTeam.tag}** ${this.details.challengedTeamScore}${this.details.overtimePeriods ? `, ${this.details.overtimePeriods > 1 ? this.details.overtimePeriods : ""}OT` : ""}`);
htmlParameters.push(`Final Score: <b>${this.challengingTeam.tag}</b> ${this.details.challengingTeamScore}, <b>${this.challengedTeam.tag}</b> ${this.details.challengedTeamScore}${this.details.overtimePeriods ? `, ${this.details.overtimePeriods > 1 ? this.details.overtimePeriods : ""}OT` : ""}`);
}

parameters.push(`Game Type: **${Challenge.getGameTypeName(this.details.gameType)}**`);
eventParameters.push(`Game Type: **${Challenge.getGameTypeName(this.details.gameType)}**`);
htmlParameters.push(`Game Type: <b>${Challenge.getGameTypeName(this.details.gameType)}</b>`);

if (this.details.matchTime) {
parameters.push(`Match Time: **<t:${Math.floor(this.details.matchTime.getTime() / 1000)}:F>**`);
Expand All @@ -3053,11 +3058,13 @@ class Challenge {
if (this.details.teamSize) {
parameters.push(`Team Size: **${this.details.teamSize}v${this.details.teamSize}**`);
eventParameters.push(`Team Size: **${this.details.teamSize}v${this.details.teamSize}**`);
htmlParameters.push(`Team Size: <b>${this.details.teamSize}v${this.details.teamSize}</b>`);
}

if (this.details.map) {
parameters.push(`Map: **${this.details.map}**`);
eventParameters.push(`Map: **${this.details.map}**`);
htmlParameters.push(`Map: <b>${this.details.map}</b>`);
}

if (this.details.overtimePeriods) {
Expand All @@ -3068,12 +3075,14 @@ class Challenge {
parameters.push(`Caster: **${this.details.caster}** at **https://twitch.tv/${await this.details.caster.getTwitchName()}**`);
if (!this.details.dateConfirmed) {
eventParameters.push(`Caster: **${this.details.caster}** at **https://twitch.tv/${await this.details.caster.getTwitchName()}**`);
htmlParameters.push(`Caster: <b>${this.details.caster}</b> at <a target="_blank" href="https://twitch.tv/${await this.details.caster.getTwitchName()}">https://twitch.tv/${await this.details.caster.getTwitchName()}</a>`);
}
}

if (this.details.postseason) {
parameters.push("**Postseason Game**");
eventParameters.push("**Postseason Game**");
htmlParameters.push("<b>Postseason Game</b>");
}

embed.addField("Match Parameters:", parameters.join("\n"));
Expand Down Expand Up @@ -3194,35 +3203,34 @@ class Challenge {
await message.pin();
}

if (this.details.event.isCompleted()) {
this.details.event = void 0;
// Set Discord event.
if (this.details.discordEvent.isCompleted()) {
this.details.discordEvent = void 0;
}

try {
if (this.details.event) {
if (this.details.discordEvent) {
if (!this.details.matchTime) {
await this.details.event.delete();
await this.details.discordEvent.delete();

this.details.event = void 0;

await this.setEvent();
this.details.discordEvent = void 0;
} else if (matchTimeUpdate) {
await this.details.event.edit({
await this.details.discordEvent.edit({
name: `${this.details.title ? `${this.details.title} - ` : ""}${this.challengingTeam.name} vs ${this.challengedTeam.name}`,
scheduledStartTime: this.details.matchTime,
scheduledEndTime: new Date(this.details.matchTime.getTime() + 60 * 60 * 1000),
description: eventParameters.join("\n"),
reason: "Match update."
});
} else {
await this.details.event.edit({
await this.details.discordEvent.edit({
name: `${this.details.title ? `${this.details.title} - ` : ""}${this.challengingTeam.name} vs ${this.challengedTeam.name}`,
description: eventParameters.join("\n"),
reason: "Match update."
});
}
} else if (this.details.matchTime) {
this.details.event = await Discord.createEvent({
this.details.discordEvent = await Discord.createEvent({
name: `${this.details.title ? `${this.details.title} - ` : ""}${this.challengingTeam.name} vs ${this.challengedTeam.name}`,
scheduledStartTime: this.details.matchTime,
scheduledEndTime: new Date(this.details.matchTime.getTime() + 60 * 60 * 1000),
Expand All @@ -3232,11 +3240,50 @@ class Challenge {
entityMetadata: {location: "OTL"},
reason: "Match update."
});
}
} catch (err) {
Log.exception("There was an error while trying to update a challenge's Discord event.", err);
}

await this.setEvent();
// Set Google event.
try {
if (this.details.googleEvent) {
if (this.details.matchTime) {
await Calendar.update(this.details.googleEvent.id, {
summary: `${this.details.title ? `${this.details.title} - ` : ""}${this.challengingTeam.name} vs ${this.challengedTeam.name}`,
start: {
dateTime: this.details.matchTime.toISOString()
},
end: {
dateTime: new Date(this.details.matchTime.getTime() + 20 * 60 * 1000).toISOString()
},
description: htmlParameters.join("<br />")
});
} else {
await Calendar.delete(this.details.googleEvent);

this.details.googleEvent = void 0;
}
} else if (this.details.matchTime) {
this.details.googleEvent = await Calendar.add({
summary: `${this.details.title ? `${this.details.title} - ` : ""}${this.challengingTeam.name} vs ${this.challengedTeam.name}`,
start: {
dateTime: this.details.matchTime.toISOString()
},
end: {
dateTime: new Date(this.details.matchTime.getTime() + 20 * 60 * 1000).toISOString()
},
description: htmlParameters.join("<br />")
});
}
} catch (err) {
Log.exception("There was an error while trying to update a challenge's guild event.", err);
Log.exception("There was an error while trying to update a challenge's Google event.", err);
}

try {
await this.setEvent();
} catch (err) {
Log.exception("There was a critical database error setting the events. Please clean up the events in the database, Discord, and Google calendar.", err);
}
}

Expand Down
1 change: 1 addition & 0 deletions types/challengeDbTypes.d.ts
Expand Up @@ -183,6 +183,7 @@ declare namespace ChallengeDbTypes {
SuggestedGameType: string
SuggestedGameTypeTeamId: number
DiscordEventId: string
GoogleEventId: string
}[],
{
Map: string
Expand Down
1 change: 1 addition & 0 deletions types/challengeTypes.d.ts
Expand Up @@ -127,6 +127,7 @@ declare namespace ChallengeTypes {
suggestedGameType: string
suggestedGameTypeTeamId: number
discordEventId: string
googleEventId: string
homeMaps: string[]
}

Expand Down

0 comments on commit 7003d73

Please sign in to comment.