From f7d162b9551c3da2bd57fa742f68fb362acb9d65 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 19:42:52 +0200 Subject: [PATCH 01/23] Add custom webhooks for votes --- src/routes/voteOnSponsorTime.js | 113 +++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 32 deletions(-) diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index f664d40a..02ffee87 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -178,41 +178,89 @@ async function voteOnSponsorTime(req, res) { } } - // Send discord message - if (incrementAmount < 0) { - // Get video ID - let submissionInfoRow = db.prepare('get', "SELECT s.videoID, s.userID, s.startTime, s.endTime, s.category, u.userName, " + - "(select count(1) from sponsorTimes where userID = s.userID) count, " + - "(select count(1) from sponsorTimes where userID = s.userID and votes <= -2) disregarded " + - "FROM sponsorTimes s left join userNames u on s.userID = u.userID where s.UUID=?", - [UUID]); - - let userSubmissionCountRow = db.prepare('get', "SELECT count(*) as submissionCount FROM sponsorTimes WHERE userID = ?", [nonAnonUserID]); - - if (submissionInfoRow !== undefined && userSubmissionCountRow != undefined) { - let webhookURL = null; - if (voteTypeEnum === voteTypes.normal) { - webhookURL = config.discordReportChannelWebhookURL; - } else if (voteTypeEnum === voteTypes.incorrect) { - webhookURL = config.discordCompletelyIncorrectReportWebhookURL; - } - - if (config.youtubeAPIKey !== null && webhookURL !== null) { - YouTubeAPI.videos.list({ - part: "snippet", - id: submissionInfoRow.videoID - }, function (err, data) { - if (err || data.items.length === 0) { - err && console.log(err); - return; - } - + // Get video ID + let submissionInfoRow = db.prepare('get', "SELECT s.videoID, s.userID, s.startTime, s.endTime, s.category, u.userName, " + + "(select count(1) from sponsorTimes where userID = s.userID) count, " + + "(select count(1) from sponsorTimes where userID = s.userID and votes <= -2) disregarded " + + "FROM sponsorTimes s left join userNames u on s.userID = u.userID where s.UUID=?", + [UUID]); + + let userSubmissionCountRow = db.prepare('get', "SELECT count(*) as submissionCount FROM sponsorTimes WHERE userID = ?", [nonAnonUserID]); + + if (submissionInfoRow !== undefined && userSubmissionCountRow != undefined) { + let webhookURL = null; + if (voteTypeEnum === voteTypes.normal) { + webhookURL = config.discordReportChannelWebhookURL; + } else if (voteTypeEnum === voteTypes.incorrect) { + webhookURL = config.discordCompletelyIncorrectReportWebhookURL; + } + + if (config.youtubeAPIKey !== null && (webhookURL !== null || config.webhooks.size !== 0)) { + YouTubeAPI.videos.list({ + part: "snippet", + id: submissionInfoRow.videoID + }, function (err, data) { + if (err || data.items.length === 0) { + err && console.log(err); + return; + } + let isUpvote = incrementAmount > 0 + // Send custom webhooks + if (config.webhooks.size !== 0) { + console.log("Dispatching webhooks"); + config.webhooks.forEach(customWebhook => { + let customWebhookURL = customWebhook.url; + let scopes = customWebhook.scopes; + let key = customWebhook.key; + if ((!isUpvote && !scopes.includes("vote.down")) || (isUpvote && !scopes.includes("vote.up"))) { + return; + } + request.post(customWebhookURL, { + json: { + "user": { + "status": userSubmissionCountRow.submissionCount === 0 ? "new" : (isVIP ? "vip" : "normal") + }, + "video": { + "id": submissionInfoRow.videoID, + "title": data.items[0].snippet.title, + "url": "https://www.youtube.com/watch?v=" + submissionInfoRow.videoID, + "thumbnail": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "" + }, + "submission": { + "id": UUID, + "views": row.views, + "category": category, + "startTime": submissionInfoRow.startTime, + "endTime": submissionInfoRow.endTime, + "user": { + "uuid": submissionInfoRow.userID, + "username": submissionInfoRow.userName, + "submissions": { + "total": submissionInfoRow.count, + "ignored": submissionInfoRow.disregarded + } + } + }, + "votes": { + "before": row.votes, + "after": (row.votes + incrementAmount - oldIncrementAmount) + } + }, + headers: { + "Authorization": key, + "Event-Type": isUpvote ? "upvote" : "downvote" + } + }); + }); + } + // Send discord message + if (webhookURL !== null && !isUpvote) { request.post(webhookURL, { json: { "embeds": [{ "title": data.items[0].snippet.title, "url": "https://www.youtube.com/watch?v=" + submissionInfoRow.videoID - + "&t=" + (submissionInfoRow.startTime.toFixed(0) - 2), + + "&t=" + (submissionInfoRow.startTime.toFixed(0) - 2), "description": "**" + row.votes + " Votes Prior | " + (row.votes + incrementAmount - oldIncrementAmount) + " Votes Now | " + row.views + " Views**\n\n**Submission ID:** " + UUID + "\n**Category:** " + submissionInfoRow.category @@ -241,8 +289,9 @@ async function voteOnSponsorTime(req, res) { console.log("\n"); } }); - }); - } + } + + }); } } From 2ffed72977a1632301a5da4f6d9cac2bb97f0637 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 20:02:18 +0200 Subject: [PATCH 02/23] Fix merge conflicts --- src/routes/voteOnSponsorTime.js | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index fe49002a..a5d6ace9 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -194,7 +194,6 @@ async function voteOnSponsorTime(req, res) { } } -<<<<<<< HEAD // Get video ID let submissionInfoRow = db.prepare('get', "SELECT s.videoID, s.userID, s.startTime, s.endTime, s.category, u.userName, " + "(select count(1) from sponsorTimes where userID = s.userID) count, " + @@ -272,37 +271,6 @@ async function voteOnSponsorTime(req, res) { } // Send discord message if (webhookURL !== null && !isUpvote) { -======= - // Send discord message - if (incrementAmount < 0) { - // Get video ID - let submissionInfoRow = db.prepare('get', "SELECT s.videoID, s.userID, s.startTime, s.endTime, s.category, u.userName, " + - "(select count(1) from sponsorTimes where userID = s.userID) count, " + - "(select count(1) from sponsorTimes where userID = s.userID and votes <= -2) disregarded " + - "FROM sponsorTimes s left join userNames u on s.userID = u.userID where s.UUID=?", - [UUID]); - - let userSubmissionCountRow = db.prepare('get', "SELECT count(*) as submissionCount FROM sponsorTimes WHERE userID = ?", [nonAnonUserID]); - - if (submissionInfoRow !== undefined && userSubmissionCountRow != undefined) { - let webhookURL = null; - if (voteTypeEnum === voteTypes.normal) { - webhookURL = config.discordReportChannelWebhookURL; - } else if (voteTypeEnum === voteTypes.incorrect) { - webhookURL = config.discordCompletelyIncorrectReportWebhookURL; - } - - if (config.youtubeAPIKey !== null && webhookURL !== null) { - YouTubeAPI.videos.list({ - part: "snippet", - id: submissionInfoRow.videoID - }, function (err, data) { - if (err || data.items.length === 0) { - err && logger.error(err); - return; - } - ->>>>>>> origin/master request.post(webhookURL, { json: { "embeds": [{ From 77d08d2340188acbbabb068fe9b6195d6a7a1acf Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 20:05:11 +0200 Subject: [PATCH 03/23] Use logger instead of console.log --- src/routes/voteOnSponsorTime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index a5d6ace9..dea5a312 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -223,7 +223,7 @@ async function voteOnSponsorTime(req, res) { let isUpvote = incrementAmount > 0 // Send custom webhooks if (config.webhooks.size !== 0) { - console.log("Dispatching webhooks"); + logger.debug("Dispatching webhooks"); config.webhooks.forEach(customWebhook => { let customWebhookURL = customWebhook.url; let scopes = customWebhook.scopes; From a268f9a892d020423a2f2ff6834f96a4f29b0d44 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 20:54:18 +0200 Subject: [PATCH 04/23] Update example & test config --- config.json.example | 3 ++- test.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config.json.example b/config.json.example index 22971d93..dea95da9 100644 --- a/config.json.example +++ b/config.json.example @@ -17,5 +17,6 @@ "dbSchema": "./databases/_sponsorTimes.db.sql", "privateDBSchema": "./databases/_private.db.sql", "mode": "development", - "readOnly": false + "readOnly": false, + "webhooks": [] } diff --git a/test.json b/test.json index 28373a12..0dbb51da 100644 --- a/test.json +++ b/test.json @@ -15,5 +15,6 @@ "dbSchema": "./databases/_sponsorTimes.db.sql", "privateDBSchema": "./databases/_private.db.sql", "mode": "test", - "readOnly": false + "readOnly": false, + "webhooks": [] } From e5aa631da0188cb289bb7a17e09401c0ddfc59e3 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 21:44:50 +0200 Subject: [PATCH 05/23] Refactor custom webhooks --- src/routes/voteOnSponsorTime.js | 83 ++++++++++++++------------------- src/utils/dispatchWebhooks.js | 22 +++++++++ 2 files changed, 56 insertions(+), 49 deletions(-) create mode 100644 src/utils/dispatchWebhooks.js diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index dea5a312..1ab96b33 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -4,7 +4,9 @@ var config = require('../config.js'); var getHash = require('../utils/getHash.js'); var getIP = require('../utils/getIP.js'); var getFormattedTime = require('../utils/getFormattedTime.js'); -var isUserTrustworthy = require('../utils/isUserTrustworthy.js') +var isUserTrustworthy = require('../utils/isUserTrustworthy.js'); +const dispatchWebhooks = require('../utils/dispatchWebhooks.js') + var databases = require('../databases/databases.js'); var db = databases.db; @@ -217,58 +219,41 @@ async function voteOnSponsorTime(req, res) { id: submissionInfoRow.videoID }, function (err, data) { if (err || data.items.length === 0) { - err && console.log(err); + err && logger.error(err); return; } - let isUpvote = incrementAmount > 0 + let isUpvote = incrementAmount > 0; // Send custom webhooks - if (config.webhooks.size !== 0) { - logger.debug("Dispatching webhooks"); - config.webhooks.forEach(customWebhook => { - let customWebhookURL = customWebhook.url; - let scopes = customWebhook.scopes; - let key = customWebhook.key; - if ((!isUpvote && !scopes.includes("vote.down")) || (isUpvote && !scopes.includes("vote.up"))) { - return; - } - request.post(customWebhookURL, { - json: { - "user": { - "status": userSubmissionCountRow.submissionCount === 0 ? "new" : (isVIP ? "vip" : "normal") - }, - "video": { - "id": submissionInfoRow.videoID, - "title": data.items[0].snippet.title, - "url": "https://www.youtube.com/watch?v=" + submissionInfoRow.videoID, - "thumbnail": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "" - }, - "submission": { - "id": UUID, - "views": row.views, - "category": category, - "startTime": submissionInfoRow.startTime, - "endTime": submissionInfoRow.endTime, - "user": { - "uuid": submissionInfoRow.userID, - "username": submissionInfoRow.userName, - "submissions": { - "total": submissionInfoRow.count, - "ignored": submissionInfoRow.disregarded - } - } - }, - "votes": { - "before": row.votes, - "after": (row.votes + incrementAmount - oldIncrementAmount) - } - }, - headers: { - "Authorization": key, - "Event-Type": isUpvote ? "upvote" : "downvote" + dispatchWebhooks(isUpvote ? "vote.up" : "vote.down", { + "user": { + "status": userSubmissionCountRow.submissionCount === 0 ? "new" : (isVIP ? "vip" : "normal") + }, + "video": { + "id": submissionInfoRow.videoID, + "title": data.items[0].snippet.title, + "url": "https://www.youtube.com/watch?v=" + submissionInfoRow.videoID, + "thumbnail": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "" + }, + "submission": { + "id": UUID, + "views": row.views, + "category": category, + "startTime": submissionInfoRow.startTime, + "endTime": submissionInfoRow.endTime, + "user": { + "UUID": submissionInfoRow.userID, + "username": submissionInfoRow.userName, + "submissions": { + "total": submissionInfoRow.count, + "ignored": submissionInfoRow.disregarded } - }); - }); - } + } + }, + "votes": { + "before": row.votes, + "after": (row.votes + incrementAmount - oldIncrementAmount) + } + }); // Send discord message if (webhookURL !== null && !isUpvote) { request.post(webhookURL, { diff --git a/src/utils/dispatchWebhooks.js b/src/utils/dispatchWebhooks.js new file mode 100644 index 00000000..4872ef7c --- /dev/null +++ b/src/utils/dispatchWebhooks.js @@ -0,0 +1,22 @@ +const config = require("../config.js"); +const logger = require('../utils/logger.js'); +const request = require('request'); + + +function dispatchEvent(scope, data) { + let webhooks = config.webhooks; + if (webhooks === undefined || webhooks.size === 0) return; + logger.debug("Dispatching webhooks"); + webhooks.forEach(webhook => { + let webhookURL = webhook.url; + let authKey = webhook.key; + let scopes = webhook.scopes || []; + if (!scopes.includes(scope.toLowerCase())) return; + request.post(webhookURL, {json: data, headers: { + "Authorization": authKey, + "Event-Type": scope // Maybe change this in the future? + }}); + }); +} + +module.exports = dispatchEvent; \ No newline at end of file From 7ae97e4c6969cb4151184953a8ea41cf5093560a Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 21:45:39 +0200 Subject: [PATCH 06/23] Change submission id to UUID --- src/routes/voteOnSponsorTime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index 1ab96b33..e0038725 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -235,7 +235,7 @@ async function voteOnSponsorTime(req, res) { "thumbnail": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "" }, "submission": { - "id": UUID, + "UUID": UUID, "views": row.views, "category": category, "startTime": submissionInfoRow.startTime, From 2597a57f3a590f27c3e9b28d6a66bc25261eaa8c Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 22:02:34 +0200 Subject: [PATCH 07/23] Update user status to include self remove --- src/routes/voteOnSponsorTime.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index e0038725..84c7cf5e 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -224,9 +224,20 @@ async function voteOnSponsorTime(req, res) { } let isUpvote = incrementAmount > 0; // Send custom webhooks + let userStatus; + if (isOwnSubmission) { + userStatus = "self"; + } else if (isVIP) { + userStatus = "vip"; + } else if (userSubmissionCountRow.submissionCount === 0) { + userStatus = "new"; + } else { + userStatus = "other"; + } dispatchWebhooks(isUpvote ? "vote.up" : "vote.down", { + "isOwnSubmission": isOwnSubmission, "user": { - "status": userSubmissionCountRow.submissionCount === 0 ? "new" : (isVIP ? "vip" : "normal") + "status": userStatus }, "video": { "id": submissionInfoRow.videoID, From 14a990f7eaf0c2c5808cc1797684545af2bfd8e0 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 22:09:02 +0200 Subject: [PATCH 08/23] Remove duplicate isOwnSubmission --- src/routes/voteOnSponsorTime.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index 84c7cf5e..8e29098e 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -235,7 +235,6 @@ async function voteOnSponsorTime(req, res) { userStatus = "other"; } dispatchWebhooks(isUpvote ? "vote.up" : "vote.down", { - "isOwnSubmission": isOwnSubmission, "user": { "status": userStatus }, From 20d813d2ea1b097a6abaead1daeee5708c08d6e8 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 22:13:00 +0200 Subject: [PATCH 09/23] Fix missing semicolon --- src/routes/voteOnSponsorTime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index 8e29098e..1cf75e5f 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -5,7 +5,7 @@ var getHash = require('../utils/getHash.js'); var getIP = require('../utils/getIP.js'); var getFormattedTime = require('../utils/getFormattedTime.js'); var isUserTrustworthy = require('../utils/isUserTrustworthy.js'); -const dispatchWebhooks = require('../utils/dispatchWebhooks.js') +const dispatchWebhooks = require('../utils/dispatchWebhooks.js'); var databases = require('../databases/databases.js'); From 9eddc330c5984dbb5b1e8abff43f1f9c494ef0a3 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 22:30:35 +0200 Subject: [PATCH 10/23] Move getVoteAuthor to webhookUtils and move user status (api) to webhookUtils --- src/routes/voteOnSponsorTime.js | 24 ++---------------------- src/utils/webhookUtils.js | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 22 deletions(-) create mode 100644 src/utils/webhookUtils.js diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index 1cf75e5f..7b891a89 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -6,6 +6,7 @@ var getIP = require('../utils/getIP.js'); var getFormattedTime = require('../utils/getFormattedTime.js'); var isUserTrustworthy = require('../utils/isUserTrustworthy.js'); const dispatchWebhooks = require('../utils/dispatchWebhooks.js'); +const {getVoteAuthor, getVoteAuthorRaw} = require('../utils/webhookUtils.js'); var databases = require('../databases/databases.js'); @@ -15,17 +16,6 @@ var YouTubeAPI = require('../utils/youtubeAPI.js'); var request = require('request'); const logger = require('../utils/logger.js'); -function getVoteAuthor(submissionCount, isVIP, isOwnSubmission) { - if (submissionCount === 0) { - return "Report by New User"; - } else if (isVIP) { - return "Report by VIP User"; - } else if (isOwnSubmission) { - return "Report by Submitter"; - } - - return ""; -} function categoryVote(UUID, userID, isVIP, category, hashedIP, res) { // Check if they've already made a vote @@ -224,19 +214,9 @@ async function voteOnSponsorTime(req, res) { } let isUpvote = incrementAmount > 0; // Send custom webhooks - let userStatus; - if (isOwnSubmission) { - userStatus = "self"; - } else if (isVIP) { - userStatus = "vip"; - } else if (userSubmissionCountRow.submissionCount === 0) { - userStatus = "new"; - } else { - userStatus = "other"; - } dispatchWebhooks(isUpvote ? "vote.up" : "vote.down", { "user": { - "status": userStatus + "status": getVoteAuthorRaw(userSubmissionCountRow.submissionCount, isVIP, isOwnSubmission) }, "video": { "id": submissionInfoRow.videoID, diff --git a/src/utils/webhookUtils.js b/src/utils/webhookUtils.js new file mode 100644 index 00000000..34f86516 --- /dev/null +++ b/src/utils/webhookUtils.js @@ -0,0 +1,26 @@ +function getVoteAuthorRaw(submissionCount, isVIP, isOwnSubmission) { + if (isOwnSubmission) { + return "self"; + } else if (isVIP) { + return "vip"; + } else if (submissionCount === 0) { + return "new"; + } else { + return "other"; + }; +}; + +function getVoteAuthor(submissionCount, isVIP, isOwnSubmission) { + if (submissionCount === 0) { + return "Report by New User"; + } else if (isVIP) { + return "Report by VIP User"; + } else if (isOwnSubmission) { + return "Report by Submitter"; + } + + return ""; +} + +module.exports.getVoteAuthorRaw = getVoteAuthorRaw; +module.exports.getVoteAuthor = getVoteAuthor; \ No newline at end of file From a897c313fb987eb4970ef1e7871657afec059e43 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 22:33:06 +0200 Subject: [PATCH 11/23] Remove broken and unnecessary check --- src/routes/voteOnSponsorTime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index 7b891a89..9d9b4583 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -203,7 +203,7 @@ async function voteOnSponsorTime(req, res) { webhookURL = config.discordCompletelyIncorrectReportWebhookURL; } - if (config.youtubeAPIKey !== null && (webhookURL !== null || config.webhooks.size !== 0)) { + if (config.youtubeAPIKey !== null) { YouTubeAPI.videos.list({ part: "snippet", id: submissionInfoRow.videoID From 16777c30ca92ee43c845b8d293f1e4ab7ec08e2a Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Sun, 23 Aug 2020 22:35:35 +0200 Subject: [PATCH 12/23] Change .size to .length --- src/utils/dispatchWebhooks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/dispatchWebhooks.js b/src/utils/dispatchWebhooks.js index 4872ef7c..625cbd7a 100644 --- a/src/utils/dispatchWebhooks.js +++ b/src/utils/dispatchWebhooks.js @@ -5,7 +5,7 @@ const request = require('request'); function dispatchEvent(scope, data) { let webhooks = config.webhooks; - if (webhooks === undefined || webhooks.size === 0) return; + if (webhooks === undefined || webhooks.length === 0) return; logger.debug("Dispatching webhooks"); webhooks.forEach(webhook => { let webhookURL = webhook.url; From aca431835130806b18bbe4b39a084bea54f60e07 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Mon, 24 Aug 2020 09:06:47 +0200 Subject: [PATCH 13/23] Move dispatchEvent to webhookUtils --- src/routes/voteOnSponsorTime.js | 5 ++--- src/utils/dispatchWebhooks.js | 22 ---------------------- src/utils/webhookUtils.js | 27 +++++++++++++++++++++++++-- 3 files changed, 27 insertions(+), 27 deletions(-) delete mode 100644 src/utils/dispatchWebhooks.js diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index 9d9b4583..458c914a 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -5,8 +5,7 @@ var getHash = require('../utils/getHash.js'); var getIP = require('../utils/getIP.js'); var getFormattedTime = require('../utils/getFormattedTime.js'); var isUserTrustworthy = require('../utils/isUserTrustworthy.js'); -const dispatchWebhooks = require('../utils/dispatchWebhooks.js'); -const {getVoteAuthor, getVoteAuthorRaw} = require('../utils/webhookUtils.js'); +const {getVoteAuthor, getVoteAuthorRaw, dispatchEvent} = require('../utils/webhookUtils.js'); var databases = require('../databases/databases.js'); @@ -214,7 +213,7 @@ async function voteOnSponsorTime(req, res) { } let isUpvote = incrementAmount > 0; // Send custom webhooks - dispatchWebhooks(isUpvote ? "vote.up" : "vote.down", { + dispatchEvent(isUpvote ? "vote.up" : "vote.down", { "user": { "status": getVoteAuthorRaw(userSubmissionCountRow.submissionCount, isVIP, isOwnSubmission) }, diff --git a/src/utils/dispatchWebhooks.js b/src/utils/dispatchWebhooks.js deleted file mode 100644 index 625cbd7a..00000000 --- a/src/utils/dispatchWebhooks.js +++ /dev/null @@ -1,22 +0,0 @@ -const config = require("../config.js"); -const logger = require('../utils/logger.js'); -const request = require('request'); - - -function dispatchEvent(scope, data) { - let webhooks = config.webhooks; - if (webhooks === undefined || webhooks.length === 0) return; - logger.debug("Dispatching webhooks"); - webhooks.forEach(webhook => { - let webhookURL = webhook.url; - let authKey = webhook.key; - let scopes = webhook.scopes || []; - if (!scopes.includes(scope.toLowerCase())) return; - request.post(webhookURL, {json: data, headers: { - "Authorization": authKey, - "Event-Type": scope // Maybe change this in the future? - }}); - }); -} - -module.exports = dispatchEvent; \ No newline at end of file diff --git a/src/utils/webhookUtils.js b/src/utils/webhookUtils.js index 34f86516..17383bf5 100644 --- a/src/utils/webhookUtils.js +++ b/src/utils/webhookUtils.js @@ -1,3 +1,7 @@ +const config = require('../config.js'); +const logger = require('../utils/logger.js'); +const request = require('request'); + function getVoteAuthorRaw(submissionCount, isVIP, isOwnSubmission) { if (isOwnSubmission) { return "self"; @@ -22,5 +26,24 @@ function getVoteAuthor(submissionCount, isVIP, isOwnSubmission) { return ""; } -module.exports.getVoteAuthorRaw = getVoteAuthorRaw; -module.exports.getVoteAuthor = getVoteAuthor; \ No newline at end of file +function dispatchEvent(scope, data) { + let webhooks = config.webhooks; + if (webhooks === undefined || webhooks.length === 0) return; + logger.debug("Dispatching webhooks"); + webhooks.forEach(webhook => { + let webhookURL = webhook.url; + let authKey = webhook.key; + let scopes = webhook.scopes || []; + if (!scopes.includes(scope.toLowerCase())) return; + request.post(webhookURL, {json: data, headers: { + "Authorization": authKey, + "Event-Type": scope // Maybe change this in the future? + }}); + }); +} + +module.exports = { + getVoteAuthorRaw, + getVoteAuthor, + dispatchEvent +} \ No newline at end of file From 2c70f87b93005ad369736d44a68f9d5451a900dd Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Mon, 24 Aug 2020 13:14:04 +0200 Subject: [PATCH 14/23] Add webhooks to postSkipSegments --- src/routes/postSkipSegments.js | 119 +++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 44 deletions(-) diff --git a/src/routes/postSkipSegments.js b/src/routes/postSkipSegments.js index 90866869..1aa513ad 100644 --- a/src/routes/postSkipSegments.js +++ b/src/routes/postSkipSegments.js @@ -11,59 +11,90 @@ var isoDurations = require('iso8601-duration'); var getHash = require('../utils/getHash.js'); var getIP = require('../utils/getIP.js'); var getFormattedTime = require('../utils/getFormattedTime.js'); -var isUserTrustworthy = require('../utils/isUserTrustworthy.js') +var isUserTrustworthy = require('../utils/isUserTrustworthy.js'); +const { dispatchEvent } = require('../utils/webhookUtils.js'); + +function sendWebhookNotification(userID, videoID, UUID, submissionCount, youtubeData, {submissionStart, submissionEnd}, segmentInfo) { + let row = db.prepare('get', "SELECT userName FROM userNames WHERE userID = ?", [userID]); + let userName = row !== undefined ? row.userName : null; + let video = youtubeData.items[0]; + + let scopeName = "submissions.other"; + if (submissionCount <= 1) { + scopeName = "submissions.new"; + } + + dispatchEvent(scopeName, { + "video": { + "id": videoID, + "title": video.snippet.title, + "thumbnail": video.snippet.thumbnails.maxres ? video.snippet.thumbnails.maxres : null, + "url": "https://www.youtube.com/watch?v=" + videoID + }, + "submission": { + "UUID": UUID, + "category": segmentInfo.category, + "startTime": submissionStart, + "endTime": submissionEnd, + "user": { + "UUID": userID, + "username": userName + } + } + }); +} function sendDiscordNotification(userID, videoID, UUID, segmentInfo) { //check if they are a first time user //if so, send a notification to discord - if (config.youtubeAPIKey !== null && config.discordFirstTimeSubmissionsWebhookURL !== null) { + if (config.youtubeAPIKey !== null) { let userSubmissionCountRow = db.prepare('get', "SELECT count(*) as submissionCount FROM sponsorTimes WHERE userID = ?", [userID]); - // If it is a first time submission - if (userSubmissionCountRow.submissionCount <= 1) { - YouTubeAPI.videos.list({ - part: "snippet", - id: videoID - }, function (err, data) { - if (err || data.items.length === 0) { - err && logger.error(err); - return; + YouTubeAPI.videos.list({ + part: "snippet", + id: videoID + }, function (err, data) { + if (err || data.items.length === 0) { + err && logger.error(err); + return; + } + + let startTime = parseFloat(segmentInfo.segment[0]); + let endTime = parseFloat(segmentInfo.segment[1]); + sendWebhookNotification(userID, videoID, UUID, userSubmissionCountRow.submissionCount, data, {submissionStart: startTime, submissionEnd: endTime}, segmentInfo); + + // If it is a first time submission + if (config.discordFirstTimeSubmissionsWebhookURL === null) return; + request.post(config.discordFirstTimeSubmissionsWebhookURL, { + json: { + "embeds": [{ + "title": data.items[0].snippet.title, + "url": "https://www.youtube.com/watch?v=" + videoID + "&t=" + (startTime.toFixed(0) - 2), + "description": "Submission ID: " + UUID + + "\n\nTimestamp: " + + getFormattedTime(startTime) + " to " + getFormattedTime(endTime) + + "\n\nCategory: " + segmentInfo.category, + "color": 10813440, + "author": { + "name": userID + }, + "thumbnail": { + "url": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "", + } + }] } - - let startTime = parseFloat(segmentInfo.segment[0]); - let endTime = parseFloat(segmentInfo.segment[1]); - - request.post(config.discordFirstTimeSubmissionsWebhookURL, { - json: { - "embeds": [{ - "title": data.items[0].snippet.title, - "url": "https://www.youtube.com/watch?v=" + videoID + "&t=" + (startTime.toFixed(0) - 2), - "description": "Submission ID: " + UUID + - "\n\nTimestamp: " + - getFormattedTime(startTime) + " to " + getFormattedTime(endTime) + - "\n\nCategory: " + segmentInfo.category, - "color": 10813440, - "author": { - "name": userID - }, - "thumbnail": { - "url": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "", - } - }] + }, (err, res) => { + if (err) { + logger.error("Failed to send first time submission Discord hook."); + logger.error(JSON.stringify(err)); + logger.error("\n"); + } else if (res && res.statusCode >= 400) { + logger.error("Error sending first time submission Discord hook"); + logger.error(JSON.stringify(res)); + logger.error("\n"); } - }, (err, res) => { - if (err) { - logger.error("Failed to send first time submission Discord hook."); - logger.error(JSON.stringify(err)); - logger.error("\n"); - } else if (res && res.statusCode >= 400) { - logger.error("Error sending first time submission Discord hook"); - logger.error(JSON.stringify(res)); - logger.error("\n"); - } - }); }); - } + }); } } From 5c9aa8c9cac54348d44baae4791090d551e5c927 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Mon, 24 Aug 2020 13:59:13 +0200 Subject: [PATCH 15/23] Cleaned up function names --- src/routes/postSkipSegments.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/routes/postSkipSegments.js b/src/routes/postSkipSegments.js index 1aa513ad..ec3342c0 100644 --- a/src/routes/postSkipSegments.js +++ b/src/routes/postSkipSegments.js @@ -44,9 +44,7 @@ function sendWebhookNotification(userID, videoID, UUID, submissionCount, youtube }); } -function sendDiscordNotification(userID, videoID, UUID, segmentInfo) { - //check if they are a first time user - //if so, send a notification to discord +function sendWebhooks(userID, videoID, UUID, segmentInfo) { if (config.youtubeAPIKey !== null) { let userSubmissionCountRow = db.prepare('get', "SELECT count(*) as submissionCount FROM sponsorTimes WHERE userID = ?", [userID]); @@ -64,6 +62,7 @@ function sendDiscordNotification(userID, videoID, UUID, segmentInfo) { sendWebhookNotification(userID, videoID, UUID, userSubmissionCountRow.submissionCount, data, {submissionStart: startTime, submissionEnd: endTime}, segmentInfo); // If it is a first time submission + // Then send a notification to discord if (config.discordFirstTimeSubmissionsWebhookURL === null) return; request.post(config.discordFirstTimeSubmissionsWebhookURL, { json: { @@ -293,7 +292,7 @@ module.exports = async function postSkipSegments(req, res) { //add to private db as well privateDB.prepare('run', "INSERT INTO sponsorTimes VALUES(?, ?, ?)", [videoID, hashedIP, timeSubmitted]); - } catch (err) { + } catch (err) {s //a DB change probably occurred res.sendStatus(502); logger.error("Error when putting sponsorTime in the DB: " + videoID + ", " + segmentInfo.segment[0] + ", " + @@ -302,8 +301,8 @@ module.exports = async function postSkipSegments(req, res) { return; } - // Discord notification - sendDiscordNotification(userID, videoID, UUID, segmentInfo); + // Webhooks + sendWebhooks(userID, videoID, UUID, segmentInfo); } } catch (err) { logger.error(err); From 3085b0e30c0d04c2a70a85845b135be2f5e2f217 Mon Sep 17 00:00:00 2001 From: TAG-Epic Date: Mon, 24 Aug 2020 22:45:47 +0200 Subject: [PATCH 16/23] Remove random s --- src/routes/postSkipSegments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/postSkipSegments.js b/src/routes/postSkipSegments.js index ec3342c0..ffcb29da 100644 --- a/src/routes/postSkipSegments.js +++ b/src/routes/postSkipSegments.js @@ -292,7 +292,7 @@ module.exports = async function postSkipSegments(req, res) { //add to private db as well privateDB.prepare('run', "INSERT INTO sponsorTimes VALUES(?, ?, ?)", [videoID, hashedIP, timeSubmitted]); - } catch (err) {s + } catch (err) { //a DB change probably occurred res.sendStatus(502); logger.error("Error when putting sponsorTime in the DB: " + videoID + ", " + segmentInfo.segment[0] + ", " + From 75a62a5729f3c89fbdd96df36a70d4e7936b2d87 Mon Sep 17 00:00:00 2001 From: Joe Dowd Date: Mon, 24 Aug 2020 22:04:18 +0100 Subject: [PATCH 17/23] make tests hit webhook code --- test.json | 9 ++++++++- test/mocks.js | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/test.json b/test.json index 0dbb51da..922bdd23 100644 --- a/test.json +++ b/test.json @@ -16,5 +16,12 @@ "privateDBSchema": "./databases/_private.db.sql", "mode": "test", "readOnly": false, - "webhooks": [] + "webhooks": [{ + "url": "http://127.0.0.1:8081/CustomWebhook", + "key": "superSecretKey", + "scopes": [ + "vote.up", + "vote.down" + ] + }] } diff --git a/test/mocks.js b/test/mocks.js index b58a47f9..aeaed4bc 100644 --- a/test/mocks.js +++ b/test/mocks.js @@ -15,6 +15,12 @@ app.post('/CompletelyIncorrectReportWebhook', (req, res) => { res.sendStatus(200); }); + +app.post('/CustomWebhook', (req, res) => { + res.sendStatus(200); +}); + + module.exports = function createMockServer(callback) { return app.listen(config.mockPort, callback); } \ No newline at end of file From 3066a077c7159227c7b6fdc176e373bc3b282194 Mon Sep 17 00:00:00 2001 From: Joe Dowd Date: Mon, 24 Aug 2020 22:10:49 +0100 Subject: [PATCH 18/23] added failed webhook call to tests --- test.json | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/test.json b/test.json index 922bdd23..4c36531b 100644 --- a/test.json +++ b/test.json @@ -16,12 +16,21 @@ "privateDBSchema": "./databases/_private.db.sql", "mode": "test", "readOnly": false, - "webhooks": [{ - "url": "http://127.0.0.1:8081/CustomWebhook", - "key": "superSecretKey", - "scopes": [ - "vote.up", - "vote.down" - ] - }] + "webhooks": [ + { + "url": "http://127.0.0.1:8081/CustomWebhook", + "key": "superSecretKey", + "scopes": [ + "vote.up", + "vote.down" + ] + }, { + "url": "http://127.0.0.1:8081/FailedWebhook", + "key": "superSecretKey", + "scopes": [ + "vote.up", + "vote.down" + ] + } +] } From eb9282c60aa027f4a24aab0ed020499beb2645cd Mon Sep 17 00:00:00 2001 From: Joe Dowd Date: Mon, 24 Aug 2020 22:22:02 +0100 Subject: [PATCH 19/23] add unresolvable host test - introduces tets faiulure --- test.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test.json b/test.json index 4c36531b..e1803542 100644 --- a/test.json +++ b/test.json @@ -31,6 +31,13 @@ "vote.up", "vote.down" ] + }, { + "url": "http://unresolvable.host:8081/FailedWebhook", + "key": "superSecretKey", + "scopes": [ + "vote.up", + "vote.down" + ] } -] + ] } From 3563924c6f3c2e21f355b3a778d63c510e34a2c0 Mon Sep 17 00:00:00 2001 From: Joe Dowd Date: Mon, 24 Aug 2020 22:40:02 +0100 Subject: [PATCH 20/23] Fixed undesolved test error --- src/utils/logger.js | 2 ++ src/utils/webhookUtils.js | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/utils/logger.js b/src/utils/logger.js index dd3f62cc..96f63607 100644 --- a/src/utils/logger.js +++ b/src/utils/logger.js @@ -45,6 +45,8 @@ const settings = { if (config.mode === 'development') { settings.INFO = true; settings.DEBUG = true; +} if (config.mode === 'test') { + settings.WARN = false; } function log(level, string) { diff --git a/src/utils/webhookUtils.js b/src/utils/webhookUtils.js index 17383bf5..41a2b13b 100644 --- a/src/utils/webhookUtils.js +++ b/src/utils/webhookUtils.js @@ -35,10 +35,13 @@ function dispatchEvent(scope, data) { let authKey = webhook.key; let scopes = webhook.scopes || []; if (!scopes.includes(scope.toLowerCase())) return; - request.post(webhookURL, {json: data, headers: { + let hookRequest = request.post(webhookURL, {json: data, headers: { "Authorization": authKey, "Event-Type": scope // Maybe change this in the future? - }}); + }}).on('error', (e) => { + logger.warn('Couldn\'t send webhook to ' + webhook.url); + logger.warn(e); + }); }); } From dc7dadd9a120ccf8d821d19bd99c9d977cde5948 Mon Sep 17 00:00:00 2001 From: Joe Dowd Date: Mon, 24 Aug 2020 22:43:36 +0100 Subject: [PATCH 21/23] tidy undesolved fix --- src/utils/logger.js | 2 +- src/utils/webhookUtils.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/logger.js b/src/utils/logger.js index 96f63607..731b5cf1 100644 --- a/src/utils/logger.js +++ b/src/utils/logger.js @@ -45,7 +45,7 @@ const settings = { if (config.mode === 'development') { settings.INFO = true; settings.DEBUG = true; -} if (config.mode === 'test') { +} else if (config.mode === 'test') { settings.WARN = false; } diff --git a/src/utils/webhookUtils.js b/src/utils/webhookUtils.js index 41a2b13b..6da1d624 100644 --- a/src/utils/webhookUtils.js +++ b/src/utils/webhookUtils.js @@ -35,7 +35,7 @@ function dispatchEvent(scope, data) { let authKey = webhook.key; let scopes = webhook.scopes || []; if (!scopes.includes(scope.toLowerCase())) return; - let hookRequest = request.post(webhookURL, {json: data, headers: { + request.post(webhookURL, {json: data, headers: { "Authorization": authKey, "Event-Type": scope // Maybe change this in the future? }}).on('error', (e) => { From 83ec23220c092c00099858ddc444db32bf357b03 Mon Sep 17 00:00:00 2001 From: Joe Dowd Date: Mon, 24 Aug 2020 22:50:27 +0100 Subject: [PATCH 22/23] added wrong port test --- test.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test.json b/test.json index e1803542..503aa5d8 100644 --- a/test.json +++ b/test.json @@ -31,6 +31,13 @@ "vote.up", "vote.down" ] + }, { + "url": "http://127.0.0.1:8099/WrongPort", + "key": "superSecretKey", + "scopes": [ + "vote.up", + "vote.down" + ] }, { "url": "http://unresolvable.host:8081/FailedWebhook", "key": "superSecretKey", From 800a3dff9d565b3831f3b1346076ccc93ee7da55 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Sat, 29 Aug 2020 19:22:44 -0400 Subject: [PATCH 23/23] Send webhooks after response --- src/routes/postSkipSegments.js | 10 +- src/routes/voteOnSponsorTime.js | 237 ++++++++++++++++++-------------- 2 files changed, 139 insertions(+), 108 deletions(-) diff --git a/src/routes/postSkipSegments.js b/src/routes/postSkipSegments.js index ffcb29da..f007b6f7 100644 --- a/src/routes/postSkipSegments.js +++ b/src/routes/postSkipSegments.js @@ -226,6 +226,9 @@ module.exports = async function postSkipSegments(req, res) { } } + // Will be filled when submitting + let UUIDs = []; + try { //check if this user is on the vip list let vipRow = db.prepare('get', "SELECT count(*) as userCount FROM vipUsers WHERE userID = ?", [userID]); @@ -301,8 +304,7 @@ module.exports = async function postSkipSegments(req, res) { return; } - // Webhooks - sendWebhooks(userID, videoID, UUID, segmentInfo); + UUIDs.push(UUID); } } catch (err) { logger.error(err); @@ -313,4 +315,8 @@ module.exports = async function postSkipSegments(req, res) { } res.sendStatus(200); + + for (let i = 0; i < segments.length; i++) { + sendWebhooks(userID, videoID, UUIDs[i], segments[i]); + } } diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index 458c914a..a2cefb3e 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -7,7 +7,6 @@ var getFormattedTime = require('../utils/getFormattedTime.js'); var isUserTrustworthy = require('../utils/isUserTrustworthy.js'); const {getVoteAuthor, getVoteAuthorRaw, dispatchEvent} = require('../utils/webhookUtils.js'); - var databases = require('../databases/databases.js'); var db = databases.db; var privateDB = databases.privateDB; @@ -15,6 +14,125 @@ var YouTubeAPI = require('../utils/youtubeAPI.js'); var request = require('request'); const logger = require('../utils/logger.js'); +const voteTypes = { + normal: 0, + incorrect: 1 +} + +/** + * @param {Object} voteData + * @param {string} voteData.UUID + * @param {string} voteData.nonAnonUserID + * @param {number} voteData.voteTypeEnum + * @param {boolean} voteData.isVIP + * @param {boolean} voteData.isOwnSubmission + * @param voteData.row + * @param {string} voteData.category + * @param {number} voteData.incrementAmount + * @param {number} voteData.oldIncrementAmount + */ +function sendWebhooks(voteData) { + let submissionInfoRow = db.prepare('get', "SELECT s.videoID, s.userID, s.startTime, s.endTime, s.category, u.userName, " + + "(select count(1) from sponsorTimes where userID = s.userID) count, " + + "(select count(1) from sponsorTimes where userID = s.userID and votes <= -2) disregarded " + + "FROM sponsorTimes s left join userNames u on s.userID = u.userID where s.UUID=?", + [voteData.UUID]); + + let userSubmissionCountRow = db.prepare('get', "SELECT count(*) as submissionCount FROM sponsorTimes WHERE userID = ?", [voteData.nonAnonUserID]); + + if (submissionInfoRow !== undefined && userSubmissionCountRow != undefined) { + let webhookURL = null; + if (voteData.voteTypeEnum === voteTypes.normal) { + webhookURL = config.discordReportChannelWebhookURL; + } else if (voteData.voteTypeEnum === voteTypes.incorrect) { + webhookURL = config.discordCompletelyIncorrectReportWebhookURL; + } + + if (config.youtubeAPIKey !== null) { + YouTubeAPI.videos.list({ + part: "snippet", + id: submissionInfoRow.videoID + }, function (err, data) { + if (err || data.items.length === 0) { + err && logger.error(err); + return; + } + let isUpvote = voteData.incrementAmount > 0; + // Send custom webhooks + dispatchEvent(isUpvote ? "vote.up" : "vote.down", { + "user": { + "status": getVoteAuthorRaw(userSubmissionCountRow.submissionCount, voteData.isVIP, voteData.isOwnSubmission) + }, + "video": { + "id": submissionInfoRow.videoID, + "title": data.items[0].snippet.title, + "url": "https://www.youtube.com/watch?v=" + submissionInfoRow.videoID, + "thumbnail": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "" + }, + "submission": { + "UUID": voteData.UUID, + "views": voteData.row.views, + "category": voteData.category, + "startTime": submissionInfoRow.startTime, + "endTime": submissionInfoRow.endTime, + "user": { + "UUID": submissionInfoRow.userID, + "username": submissionInfoRow.userName, + "submissions": { + "total": submissionInfoRow.count, + "ignored": submissionInfoRow.disregarded + } + } + }, + "votes": { + "before": voteData.row.votes, + "after": (voteData.row.votes + voteData.incrementAmount - voteData.oldIncrementAmount) + } + }); + + // Send discord message + if (webhookURL !== null && !isUpvote) { + request.post(webhookURL, { + json: { + "embeds": [{ + "title": data.items[0].snippet.title, + "url": "https://www.youtube.com/watch?v=" + submissionInfoRow.videoID + + "&t=" + (submissionInfoRow.startTime.toFixed(0) - 2), + "description": "**" + voteData.row.votes + " Votes Prior | " + + (voteData.row.votes + voteData.incrementAmount - voteData.oldIncrementAmount) + " Votes Now | " + voteData.row.views + + " Views**\n\n**Submission ID:** " + voteData.UUID + + "\n**Category:** " + submissionInfoRow.category + + "\n\n**Submitted by:** "+submissionInfoRow.userName+"\n " + submissionInfoRow.userID + + "\n\n**Total User Submissions:** "+submissionInfoRow.count + + "\n**Ignored User Submissions:** "+submissionInfoRow.disregarded + +"\n\n**Timestamp:** " + + getFormattedTime(submissionInfoRow.startTime) + " to " + getFormattedTime(submissionInfoRow.endTime), + "color": 10813440, + "author": { + "name": getVoteAuthor(userSubmissionCountRow.submissionCount, voteData.isVIP, voteData.isOwnSubmission) + }, + "thumbnail": { + "url": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "", + } + }] + } + }, (err, res) => { + if (err) { + logger.error("Failed to send reported submission Discord hook."); + logger.error(JSON.stringify(err)); + logger.error("\n"); + } else if (res && res.statusCode >= 400) { + logger.error("Error sending reported submission Discord hook"); + logger.error(JSON.stringify(res)); + logger.error("\n"); + } + }); + } + + }); + } + } +} function categoryVote(UUID, userID, isVIP, category, hashedIP, res) { // Check if they've already made a vote @@ -117,11 +235,6 @@ async function voteOnSponsorTime(req, res) { } } - let voteTypes = { - normal: 0, - incorrect: 1 - } - let voteTypeEnum = (type == 0 || type == 1) ? voteTypes.normal : voteTypes.incorrect; try { @@ -185,106 +298,6 @@ async function voteOnSponsorTime(req, res) { } } - // Get video ID - let submissionInfoRow = db.prepare('get', "SELECT s.videoID, s.userID, s.startTime, s.endTime, s.category, u.userName, " + - "(select count(1) from sponsorTimes where userID = s.userID) count, " + - "(select count(1) from sponsorTimes where userID = s.userID and votes <= -2) disregarded " + - "FROM sponsorTimes s left join userNames u on s.userID = u.userID where s.UUID=?", - [UUID]); - - let userSubmissionCountRow = db.prepare('get', "SELECT count(*) as submissionCount FROM sponsorTimes WHERE userID = ?", [nonAnonUserID]); - - if (submissionInfoRow !== undefined && userSubmissionCountRow != undefined) { - let webhookURL = null; - if (voteTypeEnum === voteTypes.normal) { - webhookURL = config.discordReportChannelWebhookURL; - } else if (voteTypeEnum === voteTypes.incorrect) { - webhookURL = config.discordCompletelyIncorrectReportWebhookURL; - } - - if (config.youtubeAPIKey !== null) { - YouTubeAPI.videos.list({ - part: "snippet", - id: submissionInfoRow.videoID - }, function (err, data) { - if (err || data.items.length === 0) { - err && logger.error(err); - return; - } - let isUpvote = incrementAmount > 0; - // Send custom webhooks - dispatchEvent(isUpvote ? "vote.up" : "vote.down", { - "user": { - "status": getVoteAuthorRaw(userSubmissionCountRow.submissionCount, isVIP, isOwnSubmission) - }, - "video": { - "id": submissionInfoRow.videoID, - "title": data.items[0].snippet.title, - "url": "https://www.youtube.com/watch?v=" + submissionInfoRow.videoID, - "thumbnail": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "" - }, - "submission": { - "UUID": UUID, - "views": row.views, - "category": category, - "startTime": submissionInfoRow.startTime, - "endTime": submissionInfoRow.endTime, - "user": { - "UUID": submissionInfoRow.userID, - "username": submissionInfoRow.userName, - "submissions": { - "total": submissionInfoRow.count, - "ignored": submissionInfoRow.disregarded - } - } - }, - "votes": { - "before": row.votes, - "after": (row.votes + incrementAmount - oldIncrementAmount) - } - }); - // Send discord message - if (webhookURL !== null && !isUpvote) { - request.post(webhookURL, { - json: { - "embeds": [{ - "title": data.items[0].snippet.title, - "url": "https://www.youtube.com/watch?v=" + submissionInfoRow.videoID - + "&t=" + (submissionInfoRow.startTime.toFixed(0) - 2), - "description": "**" + row.votes + " Votes Prior | " + (row.votes + incrementAmount - oldIncrementAmount) + " Votes Now | " + row.views - + " Views**\n\n**Submission ID:** " + UUID - + "\n**Category:** " + submissionInfoRow.category - + "\n\n**Submitted by:** "+submissionInfoRow.userName+"\n " + submissionInfoRow.userID - + "\n\n**Total User Submissions:** "+submissionInfoRow.count - + "\n**Ignored User Submissions:** "+submissionInfoRow.disregarded - +"\n\n**Timestamp:** " + - getFormattedTime(submissionInfoRow.startTime) + " to " + getFormattedTime(submissionInfoRow.endTime), - "color": 10813440, - "author": { - "name": getVoteAuthor(userSubmissionCountRow.submissionCount, isVIP, isOwnSubmission) - }, - "thumbnail": { - "url": data.items[0].snippet.thumbnails.maxres ? data.items[0].snippet.thumbnails.maxres.url : "", - } - }] - } - }, (err, res) => { - if (err) { - logger.error("Failed to send reported submission Discord hook."); - logger.error(JSON.stringify(err)); - logger.error("\n"); - } else if (res && res.statusCode >= 400) { - logger.error("Error sending reported submission Discord hook"); - logger.error(JSON.stringify(res)); - logger.error("\n"); - } - }); - } - - }); - } - } - // Only change the database if they have made a submission before and haven't voted recently let ableToVote = isVIP || (db.prepare("get", "SELECT userID FROM sponsorTimes WHERE userID = ?", [nonAnonUserID]) !== undefined @@ -337,6 +350,18 @@ async function voteOnSponsorTime(req, res) { } res.sendStatus(200); + + sendWebhooks({ + UUID, + nonAnonUserID, + voteTypeEnum, + isVIP, + isOwnSubmission, + row, + category, + incrementAmount, + oldIncrementAmount + }); } catch (err) { logger.error(err);