From 581a173112a0270db98903a240293d02d664ea07 Mon Sep 17 00:00:00 2001 From: Mittelblut9 Date: Sat, 8 Jul 2023 23:44:40 +0200 Subject: [PATCH 1/4] refactor: remove unused translation check script --- package.json | 1 - scripts/translationCheck.js | 65 ------------------------------------- 2 files changed, 66 deletions(-) delete mode 100644 scripts/translationCheck.js diff --git a/package.json b/package.json index 36e7ee5f7..b4584442e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "format": "npm run stop && docker run --rm -v $(pwd):/app -w /app node:18.8 sh -c \"npm install -g prettier && prettier --config .tools/prettier/.prettierrc --ignore-path .tools/prettier/.prettierignore --write .\"", "check": "docker run --rm -v $(pwd):/app -w /app node:18.8 sh -c \"npm install -g prettier && prettier --config .tools/prettier/.prettierrc --ignore-path .tools/prettier/.prettierignore --check .\"", "postinstall": "patch-package && husky install", - "transCheck": "node ./scripts/translationCheck.js", "alias-build": "link-module-alias", "test": "jest", "bash": "docker compose exec bot bash" diff --git a/scripts/translationCheck.js b/scripts/translationCheck.js deleted file mode 100644 index 3219969f1..000000000 --- a/scripts/translationCheck.js +++ /dev/null @@ -1,65 +0,0 @@ -(() => { - const fs = require('fs'); - const path = require('path'); - - function compareJSONKeys(json1, json2) { - const keys1 = Object.keys(json1); - const keys2 = Object.keys(json2); - - const missingKeysInJson2 = keys1.filter((key) => !keys2.includes(key)); - const missingKeysInJson1 = keys2.filter((key) => !keys1.includes(key)); - - for (let key in json1) { - if ( - json1.hasOwnProperty(key) && - json2.hasOwnProperty(key) && - typeof json1[key] === 'object' && - typeof json2[key] === 'object' - ) { - const nestedDifferences = compareJSONKeys(json1[key], json2[key]); - missingKeysInJson2.push( - ...nestedDifferences.missingKeysInJson2.map( - (nestedKey) => `${key}.${nestedKey}` - ) - ); - missingKeysInJson1.push( - ...nestedDifferences.missingKeysInJson1.map( - (nestedKey) => `${key}.${nestedKey}` - ) - ); - } - } - - return { - missingKeysInJson2, - missingKeysInJson1, - }; - } - - const transFilesPath = '~assets/json/translations/'; - - const defaultTranslationPath = path.resolve(__dirname, transFilesPath + '_default.json'); - const defaultTranslation = JSON.parse(fs.readFileSync(defaultTranslationPath, 'utf8')); - - const translationFiles = fs - .readdirSync(path.resolve(__dirname, transFilesPath)) - .filter((file) => file !== '_default.json'); - - translationFiles.forEach((file) => { - const translationPath = path.resolve(__dirname, transFilesPath + file); - const translation = JSON.parse(fs.readFileSync(translationPath, 'utf8')); - - const differences = compareJSONKeys(defaultTranslation, translation); - - if (differences.missingKeysInJson2.length > 0) { - console.info( - `Translation file ${file} is not up to date with the default translation file. Missing keys:` - ); - console.info(differences.missingKeysInJson2); - } else { - console.info( - `Translation file ${file} is up to date with the default translation file` - ); - } - }); -})(); From 5700f9457388ada361c7dc46a994ac135d1e8b1a Mon Sep 17 00:00:00 2001 From: Mittelblut9 Date: Sun, 9 Jul 2023 13:35:10 +0200 Subject: [PATCH 2/4] feat: add statistics to views and subs to youtube notificaton embed --- src/db/Models/guildUploads.model.js | 8 ++++ .../Notifications/YouTube/YouTubeLogic.js | 32 +++++++++++++++- .../YouTube/YouTubeNotification.js | 38 +++++++++++++++---- 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/db/Models/guildUploads.model.js b/src/db/Models/guildUploads.model.js index 2befc0059..79cb3079d 100644 --- a/src/db/Models/guildUploads.model.js +++ b/src/db/Models/guildUploads.model.js @@ -30,6 +30,14 @@ GuildUploads.init( type: DataTypes.BIGINT, defaultValue: 0, }, + views: { + type: DataTypes.BIGINT, + defaultValue: 0, + }, + subs: { + type: DataTypes.BIGINT, + defaultValue: 0, + }, }, { sequelize: database, diff --git a/utils/classes/Notifications/YouTube/YouTubeLogic.js b/utils/classes/Notifications/YouTube/YouTubeLogic.js index 61bce499a..e0af2ea27 100644 --- a/utils/classes/Notifications/YouTube/YouTubeLogic.js +++ b/utils/classes/Notifications/YouTube/YouTubeLogic.js @@ -37,15 +37,19 @@ module.exports = class YouTubeLogic { constructor() {} - updateUploads({ guildId, channelId, uploads, messageId, ytChannelId }) { + updateUploads({ guildId, channelId, uploads, messageId, ytChannelId, views, subs }) { return new Promise(async (resolve) => { const update = uploads ? { uploads: uploads, messageId: messageId, + views: views, + subs: subs, } : { updateCount: Math.floor(Math.random() * 200) + 1, + views: views, + subs: subs, }; const whereCond = ytChannelId @@ -128,4 +132,30 @@ module.exports = class YouTubeLogic { return resolve(response.data.items[0].id.channelId); }); } + + getViews(channel_id, guild_id) { + return new Promise(async (resolve) => { + const uploads = await guildUploads.findOne({ + where: { + guild_id: guild_id, + channel_id: channel_id, + }, + }); + + return resolve(uploads.views); + }); + } + + getSubs(channel_id, guild_id) { + return new Promise(async (resolve) => { + const uploads = await guildUploads.findOne({ + where: { + guild_id: guild_id, + channel_id: channel_id, + }, + }); + + return resolve(uploads.subs); + }); + } }; diff --git a/utils/classes/Notifications/YouTube/YouTubeNotification.js b/utils/classes/Notifications/YouTube/YouTubeNotification.js index ea3c83db3..85a6ed48c 100644 --- a/utils/classes/Notifications/YouTube/YouTubeNotification.js +++ b/utils/classes/Notifications/YouTube/YouTubeNotification.js @@ -80,8 +80,7 @@ module.exports = class YouTubeNotification extends YouTubeLogic { premiereStartsIn, ping ); - - const embed = await this.generateEmbed(videoDetails); + const embed = await this.generateEmbed(videoDetails, upload.channel_id, guild.id); try { const message = await this.notificationApi.sendNotification({ @@ -92,15 +91,17 @@ module.exports = class YouTubeNotification extends YouTubeLogic { if (message instanceof Message) { await this.updateUploads({ - guildId: upload.guild_id, + guildId: guild.id, channelId: upload.channel_id, uploads: uploadedVideos, messageId: message.id, + views: videoDetails.viewCount, + subs: videoDetails.author.subscriber_count, }); } console.info( - `📥 New upload sent! GUILD: ${upload.guild_id} CHANNEL ID: ${upload.info_channel_id} YOUTUBE LINK: ${feed.items[0].link}` + `📥 New upload sent! GUILD: ${guild.id} CHANNEL ID: ${upload.info_channel_id} YOUTUBE LINK: ${feed.items[0].link}` ); } catch (err) { console.error( @@ -178,8 +179,15 @@ module.exports = class YouTubeNotification extends YouTubeLogic { ); } - generateEmbed(videoDetails) { + generateEmbed(videoDetails, channel, guild_id) { return new Promise(async (resolve) => { + const subs = await this.getSubsDiff( + videoDetails.author.subscriber_count, + channel, + guild_id + ); + const views = await this.getViewsDiff(videoDetails.viewCount, channel, guild_id); + const embed = await new Notification().geneateNotificationEmbed({ title: videoDetails.title ? videoDetails.title.substring(0, 250) : 'No title', description: videoDetails.description @@ -190,7 +198,7 @@ module.exports = class YouTubeNotification extends YouTubeLogic { thumbnail: videoDetails?.author.thumbnails?.splice(-1)[0]?.url, color: '#ff0000', footer: { - text: `Subscribers ${videoDetails.author.subscriber_count} | Views ${videoDetails.viewCount} | Length ${videoDetails.lengthSeconds}s | ${videoDetails.author.name}`, + text: `Subscribers ${subs} | Views ${views} | Length ${videoDetails.lengthSeconds}s | ${videoDetails.author.name}`, }, author: { name: `${videoDetails.author.name} just uploaded a new video!`, @@ -202,6 +210,22 @@ module.exports = class YouTubeNotification extends YouTubeLogic { }); } + getViewsDiff(newViews, channel_id, guild_id) { + return new Promise(async (resolve) => { + const oldViews = await this.getViews(channel_id, guild_id); + const diff = newViews - oldViews; + resolve(`${newViews} (${diff > 0 ? '+' : ''}${diff})`); + }); + } + + getSubsDiff(newSubs, channel_id, guild_id) { + return new Promise(async (resolve) => { + const oldSubs = await this.getSubs(channel_id, guild_id); + const diff = newSubs - oldSubs; + resolve(`${newSubs} (${diff > 0 ? '+' : ''}${diff})`); + }); + } + updateEmbed(video, messageId, guildId, channelId, ytChannelId) { return new Promise(async (resolve) => { const videoDetails = await this.getVideoInfos(video.link); @@ -209,7 +233,7 @@ module.exports = class YouTubeNotification extends YouTubeLogic { if (!channel) return resolve(false); const message = await channel.messages.fetch(messageId); - const embed = await this.generateEmbed(videoDetails); + const embed = await this.generateEmbed(videoDetails, ytChannelId, guildId); await this.notificationApi .updateNotification({ From cdc3f5d213c82fd95d30bc6a85c0c0bb51731d88 Mon Sep 17 00:00:00 2001 From: Mittelblut9 Date: Sun, 9 Jul 2023 14:27:27 +0200 Subject: [PATCH 3/4] feat: add statistics to views in twitch notificaton embed --- src/db/Models/twitchStreams.model.js | 4 +++ .../Notifications/Twitch/TwitchLogic.js | 32 +++++++++++++++-- .../Twitch/TwitchNotification.js | 36 +++++++++++++------ 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/db/Models/twitchStreams.model.js b/src/db/Models/twitchStreams.model.js index 160cdb6dd..98e2cdaf3 100644 --- a/src/db/Models/twitchStreams.model.js +++ b/src/db/Models/twitchStreams.model.js @@ -33,6 +33,10 @@ TwitchStreams.init( embedUpdatedAt: { type: DataTypes.DATE, }, + views: { + type: DataTypes.BIGINT, + defaultValue: 0, + }, }, { sequelize: database, diff --git a/utils/classes/Notifications/Twitch/TwitchLogic.js b/utils/classes/Notifications/Twitch/TwitchLogic.js index e15e072df..7954790d1 100644 --- a/utils/classes/Notifications/Twitch/TwitchLogic.js +++ b/utils/classes/Notifications/Twitch/TwitchLogic.js @@ -282,7 +282,7 @@ module.exports = class TwitchNotifier { return new Promise(async (resolve, reject) => { const twitchChannel = await this.getTwitchFromChannelName(channel); if (!twitchChannel) { - return reject(global.t.trans(['error.notifications.twitch.notFound'], guild.id)); + return reject(global.t.trans(['error.notifications.twitch.notFound'], guild_id)); } await twitchStreams @@ -293,11 +293,37 @@ module.exports = class TwitchNotifier { }, }) .then(() => { - resolve(global.t.trans(['success.notifications.twitch.removed'], guild.id)); + resolve(global.t.trans(['success.notifications.twitch.removed'], guild_id)); + }) + .catch((err) => { + reject(global.t.trans(['error.notifications.twitch.removeChannel'], guild_id)); + }); + }); + } + + getViews(twitch_id, guild_id) { + return new Promise(async (resolve, reject) => { + await twitchStreams + .findOne({ + where: { + guild_id, + twitch_id, + }, + }) + .then((res) => { + resolve(res.views); }) .catch((err) => { - reject(global.t.trans(['error.notifications.twitch.removeChannel'], guild.id)); + reject(0); }); }); } + + getViewsDiff(newViews, guild_id, twitch_id) { + return new Promise(async (resolve) => { + const oldViews = await this.getViews(guild_id, twitch_id); + const diff = newViews - oldViews; + resolve(`${newViews} (${diff > 0 ? '+' : ''}${diff})`); + }); + } }; diff --git a/utils/classes/Notifications/Twitch/TwitchNotification.js b/utils/classes/Notifications/Twitch/TwitchNotification.js index d9d44e2c3..80cfb9d8a 100644 --- a/utils/classes/Notifications/Twitch/TwitchNotification.js +++ b/utils/classes/Notifications/Twitch/TwitchNotification.js @@ -24,10 +24,16 @@ module.exports = class TwitchNotification extends TwitchNotifier { if (!wasLive) return; const uptime = this.#getUptime(data.streamStartedAt); - const embed = await this.#generateEmbed(streamer, stream, { - isLive: false, - uptime, - }); + const embed = await this.#generateEmbed( + streamer, + stream, + { + isLive: false, + uptime, + }, + data.twitch_id, + data.guild_id + ); const dcChannel = await this.bot.channels.fetch(data.dc_channel_id); const dcMessage = await dcChannel.messages.fetch(data.message); @@ -63,10 +69,16 @@ module.exports = class TwitchNotification extends TwitchNotifier { const isEveryone = data.pingrole === data.guild_id; const messageContent = this.#generateMessageContent(data.pingrole, isEveryone); - const embed = await this.#generateEmbed(streamer, stream, { - uptime, - isLive: true, - }); + const embed = await this.#generateEmbed( + streamer, + stream, + { + uptime, + isLive: true, + }, + data.twitch_id, + data.guild_id + ); const dcChannel = await this.bot.channels.fetch(data.dc_channel_id); let message; @@ -138,7 +150,7 @@ module.exports = class TwitchNotification extends TwitchNotifier { return pingrole ? (isEveryone ? '@everyone' : `<@&${pingrole}>`) : ''; } - #generateEmbed(streamer, stream, { isLive, uptime }) { + #generateEmbed(streamer, stream, { isLive, uptime }, twitch_id, guild_id) { return new Promise(async (resolve, reject) => { const embed = await this.notificationApi .geneateNotificationEmbed({ @@ -185,7 +197,11 @@ module.exports = class TwitchNotification extends TwitchNotifier { 'info.notifications.twitch.fields.viewers', streamer.displayName, ]), - value: stream.viewers.toString(), + value: await this.getViewsDiff( + stream.viewers.toString(), + twitch_id, + guild_id + ), inline: true, }, { From 21b176fde7348c8c83137616c60df26e8482d061 Mon Sep 17 00:00:00 2001 From: Mittelblut9 Date: Sun, 9 Jul 2023 17:22:25 +0200 Subject: [PATCH 4/4] chore: v0.65.14 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b6c953ab7..9e281736c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mittelbot", - "version": "0.65.13", + "version": "0.65.14", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mittelbot", - "version": "0.65.13", + "version": "0.65.14", "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { diff --git a/package.json b/package.json index b4584442e..50f4481b7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mittelbot", - "version": "0.65.13", + "version": "0.65.14", "description": "A Discord Bot written in Node.js", "main": "bot/core/shard.js", "private": true,