diff --git a/src/config.ts b/src/config.ts index 4aa3c8ee..f6d6a8bc 100644 --- a/src/config.ts +++ b/src/config.ts @@ -45,6 +45,7 @@ addDefaults(config, { discordFailedReportChannelWebhookURL: null, discordReportChannelWebhookURL: null, discordMaliciousReportWebhookURL: null, + discordDeArrowLockedWebhookURL: null, minReputationToSubmitChapter: 0, minReputationToSubmitFiller: 0, getTopUsersCacheTimeMinutes: 240, diff --git a/src/routes/postBranding.ts b/src/routes/postBranding.ts index d0eca740..009af56e 100644 --- a/src/routes/postBranding.ts +++ b/src/routes/postBranding.ts @@ -15,6 +15,9 @@ import { QueryCacher } from "../utils/queryCacher"; import { acquireLock } from "../utils/redisLock"; import { hasFeature } from "../utils/features"; import { checkBanStatus } from "../utils/checkBan"; +import axios from "axios"; +import { getMaxResThumbnail } from "../utils/youtubeApi"; +import { getVideoDetails } from "../utils/getVideoDetails"; enum BrandingType { Title, @@ -88,6 +91,8 @@ export async function postBranding(req: Request, res: Response) { // unlock all other titles await db.prepare("run", `UPDATE "titleVotes" as tv SET "locked" = 0 FROM "titles" t WHERE tv."UUID" = t."UUID" AND tv."UUID" != ? AND t."videoID" = ?`, [UUID, videoID]); } + + sendWebhooks(videoID, UUID).catch((e) => Logger.error(e)); } })(), (async () => { if (thumbnail) { @@ -201,3 +206,44 @@ export async function verifyOldSubmissions(hashedUserID: HashedUserID, verificat } } } + +async function sendWebhooks(videoID: VideoID, UUID: BrandingUUID) { + const lockedSubmission = await db.prepare("get", `SELECT "titleVotes"."votes", "titles"."title", "titles"."userID" FROM "titles" JOIN "titleVotes" ON "titles"."UUID" = "titleVotes"."UUID" WHERE "titles"."videoID" = ? AND "titles"."UUID" != ? AND "titleVotes"."locked" = 1`, [videoID, UUID]); + + if (lockedSubmission) { + const currentSubmission = await db.prepare("get", `SELECT "titleVotes"."votes", "titles"."title" FROM "titles" JOIN "titleVotes" ON "titles"."UUID" = "titleVotes"."UUID" WHERE "titles"."UUID" = ?`, [UUID]); + + // Time to warn that there may be an issue + if (currentSubmission.votes - lockedSubmission.votes > 2) { + const usernameRow = await db.prepare("get", `SELECT "userName" FROM "userNames" WHERE "userID" = ?`, [lockedSubmission.userID]); + + const data = await getVideoDetails(videoID); + axios.post(config.discordDeArrowLockedWebhookURL, { + "embeds": [{ + "title": data?.title, + "url": `https://www.youtube.com/watch?v=${videoID}`, + "description": `**${lockedSubmission.votes}** Votes vs **${currentSubmission.votes}**\ + \n\n**Locked title:** ${lockedSubmission.title}\ + \n**New title:** ${currentSubmission.title}\ + \n\n**Submitted by:** ${usernameRow?.userName ?? ""}\n${lockedSubmission.userID}`, + "color": 10813440, + "thumbnail": { + "url": getMaxResThumbnail(videoID), + }, + }], + }) + .then(res => { + if (res.status >= 400) { + Logger.error("Error sending reported submission Discord hook"); + Logger.error(JSON.stringify((res.data))); + Logger.error("\n"); + } + }) + .catch(err => { + Logger.error("Failed to send reported submission Discord hook."); + Logger.error(JSON.stringify(err)); + Logger.error("\n"); + }); + } + } +} \ No newline at end of file diff --git a/src/types/config.model.ts b/src/types/config.model.ts index 092da2d1..94a9f00b 100644 --- a/src/types/config.model.ts +++ b/src/types/config.model.ts @@ -48,6 +48,7 @@ export interface SBSConfig { discordFirstTimeSubmissionsWebhookURL?: string; discordCompletelyIncorrectReportWebhookURL?: string; discordMaliciousReportWebhookURL?: string; + discordDeArrowLockedWebhookURL?: string, neuralBlockURL?: string; discordNeuralBlockRejectWebhookURL?: string; minReputationToSubmitChapter: number;