From eabf05908c7ba79d0f1192a4cca776cc0254d024 Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Mon, 18 Jan 2021 17:12:44 -0300 Subject: [PATCH 01/18] Remove global variables from all places possibles now --- src/client/Client.js | 18 ++++------ src/sleept/SLEEPTMethods.js | 71 ++++++++++++++++++------------------- src/structures/channels.js | 2 +- 3 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/client/Client.js b/src/client/Client.js index 9a91f9e..30c8ad3 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -27,10 +27,6 @@ class Client extends EventEmmiter { global.twitchApis = { client: { option: this.options, - methods: { - joinQueueTimeout: [], - leaveQueueTimeout: [], - }, }, }; @@ -43,13 +39,6 @@ class Client extends EventEmmiter { logger.debug('Debug is active!'); - /** - * The SLEEPT manager of the client - * @type {SLEEPTManager} - * @private - */ - this.sleept = new SLEEPTManager(this); - Object.defineProperty(this, 'token', { writable: true }); if (!this.token && 'CLIENT_TOKEN' in process.env) { /** @@ -122,6 +111,13 @@ class Client extends EventEmmiter { if (options.messageSweepInterval > 0) { setInterval(this.sweepMessages.bind(this), options.messageSweepInterval * 1000); } + + /** + * The SLEEPT manager of the client + * @type {SLEEPTManager} + * @private + */ + this.sleept = new SLEEPTManager(this); } /** diff --git a/src/sleept/SLEEPTMethods.js b/src/sleept/SLEEPTMethods.js index 2d9bc91..32874e5 100644 --- a/src/sleept/SLEEPTMethods.js +++ b/src/sleept/SLEEPTMethods.js @@ -17,6 +17,8 @@ class SLEEPTMethods { this.getChatter = getChatter; this.connected = 0; this.isAnonymous = false; + this.joinQueueTimeout = []; + this.leaveQueueTimeout = []; } isConnected() { @@ -37,7 +39,7 @@ class SLEEPTMethods { this.userName = 'twitchjs'; // Just to start the connection after that, twitch sends back the bot name and we replace it this.id = ''; } - this.server = global.twitchApis.client.option.http.host; + this.server = this.client.options.http.host; this.ws = new WebSocket(`wss://${this.server}:443`); this.ws.onmessage = this.onMessage.bind(this); this.ws.onerror = this.onError.bind(this); @@ -132,7 +134,7 @@ class SLEEPTMethods { case '372': logger.debug('Connected to the server'); this.readyAt = Date.now(); - global.twitchApis.client.option.readyAt = this.readyAt; + this.client.options.readyAt = this.readyAt; this.onConnected(); this.pingLoop = setInterval(() => { if (this.isConnected()) { @@ -152,7 +154,7 @@ class SLEEPTMethods { }, 60000); break; case 'ROOMSTATE': - var channel = global.twitchApis.client.channels.get(messageObject.params[0]); + var channel = this.client.channels.get(messageObject.params[0]); channel.emoteOnly = messageObject.tags['emote-only'] ? Number(messageObject.tags['emote-only']) === 1 : channel.emoteOnly; channel.followersOnly = messageObject.tags['followers-only'] ? Number(messageObject.tags['followers-only']) >= 0 : channel.followersOnly; channel.followersOnlyCooldown = messageObject.tags['followers-only'] @@ -183,19 +185,17 @@ class SLEEPTMethods { switch (messageObject.command) { case 'JOIN': this.client.eventEmmiter('Method.Joined.' + messageObject.params[0]); - this.client.eventEmmiter('join', global.twitchApis.client.channels.get(messageObject.params[0])); + this.client.eventEmmiter('join', this.client.channels.get(messageObject.params[0])); this.generateUser(messageObject.params[0]); - this.client.channels = global.twitchApis.client.channels; break; case 'PART': - if (global.twitchApis.client.channels.get(messageObject.params[0]).users.get(messageObject.prefix.slice(0, messageObject.prefix.indexOf('!')))) { - global.twitchApis.client.channels + if (this.client.channels.get(messageObject.params[0]).users.get(messageObject.prefix.slice(0, messageObject.prefix.indexOf('!')))) { + this.client.channels .get(messageObject.params[0]) .users.delete(messageObject.prefix.slice(0, messageObject.prefix.indexOf('!'))); } this.client.eventEmmiter('Method.Leaved.' + messageObject.params[0]); this.client.eventEmmiter('leave', messageObject.params[0]); - this.client.channels = global.twitchApis.client.channels; break; case 'PRIVMSG': this.updateUser(messageObject); @@ -210,7 +210,7 @@ class SLEEPTMethods { onConnected() { // Once connected connect the user to the servers he parsed on client inicialization - global.twitchApis.client.option.channels.forEach((element, index) => { + this.client.options.channels.forEach((element, index) => { setTimeout(() => { this.join(element, index); }, index * 100); @@ -229,14 +229,14 @@ class SLEEPTMethods { if (!channel.startsWith('#')) { channel = '#' + channel; } - if (global.twitchApis.client.channels.get(channel) && global.twitchApis.client.channels.get(channel).connected === true) { + if (this.client.channels.get(channel) && this.client.channels.get(channel).connected === true) { logger.warn('Already connected with this channel!'); return reject('Already connected with this channel!'); } this.ws.send(`JOIN ${channel.toLowerCase()}`); logger.debug('Connecting to: ' + channel.toLowerCase()); this.client.on('Method.Joined.' + channel.toLowerCase(), listener); - global.twitchApis.client.methods.joinQueueTimeout.push([ + this.joinQueueTimeout.push([ setTimeout(() => { reject('Couldn\'t connect with twitch'); }, 10000), @@ -244,11 +244,11 @@ class SLEEPTMethods { ]); function listener() { logger.debug('Connected to: ' + channel.toLowerCase()); - if (!global.twitchApis.client.channels.get(channel)) { - global.twitchApis.client.channels.set(channel, new channels(this, { channel: channel })); + if (!this.channels.get(channel)) { + this.channels.set(channel, new channels(this, { channel: channel })); } - global.twitchApis.client.channels.get(channel).connected = true; - global.twitchApis.client.methods.joinQueueTimeout.forEach((element) => { + this.channels.get(channel).connected = true; + this.sleept.methods.joinQueueTimeout.forEach((element) => { if (element[1] === channel.toLowerCase()) { clearTimeout(element[0]); return; @@ -269,14 +269,14 @@ class SLEEPTMethods { if (!channel.startsWith('#')) { channel = '#' + channel; } - if (global.twitchApis.client.channels.get(channel.toLowerCase()) && !global.twitchApis.client.channels.get(channel.toLowerCase()).isConnected()) { + if (this.client.channels.get(channel.toLowerCase()) && !this.client.channels.get(channel.toLowerCase()).isConnected()) { logger.error('Already not connected to the channel: ' + channel); return reject('Already not connected to the channel: ' + channel); } this.ws.send(`PART ${channel.toLowerCase()}`); logger.debug('Disconnecting from: ' + channel.toLowerCase()); this.client.on('Method.Leaved.' + channel.toLowerCase(), listener); - global.twitchApis.client.methods.leaveQueueTimeout.push([ + this.leaveQueueTimeout.push([ setTimeout(() => { logger.fatal('Couldn\'t connect with twitch'); reject('Couldn\'t connect with twitch'); @@ -285,10 +285,10 @@ class SLEEPTMethods { ]); function listener() { logger.debug('Disconnected from: ' + channel.toLowerCase()); - if (global.twitchApis.client.channels.get(channel.toLowerCase()) && global.twitchApis.client.channels.get(channel.toLowerCase()).isConnected()) { - global.twitchApis.client.channels.delete(channel.toLowerCase()); + if (this.channels.get(channel.toLowerCase()) && this.channels.get(channel.toLowerCase()).isConnected()) { + this.channels.delete(channel.toLowerCase()); } - global.twitchApis.client.methods.leaveQueueTimeout.forEach((element) => { + this.sleept.methods.leaveQueueTimeout.forEach((element) => { if (element[1] === channel.toLowerCase()) { clearTimeout(element[0]); return; @@ -347,46 +347,46 @@ class SLEEPTMethods { } generateUser(channelName) { this.getChatter(channelName).then((Users) => { - if (!global.twitchApis.client.channels.get(channelName)) {return;} + if (!this.client.channels.get(channelName)) {return;} Users.chatters.broadcaster.forEach((broadcaster) => { - if (!global.twitchApis.client.channels.get(channelName).users.get(broadcaster)) { - global.twitchApis.client.channels.get(channelName).users.set(broadcaster, + if (!this.client.channels.get(channelName).users.get(broadcaster)) { + this.client.channels.get(channelName).users.set(broadcaster, new users(this.client, {userName: broadcaster,self: broadcaster === this.userName,broadcaster: true,})); } }); Users.chatters.vips.forEach((vips) => { - if (!global.twitchApis.client.channels.get(channelName).users.get(vips)) { - global.twitchApis.client.channels.get(channelName).users.set(vips, + if (!this.client.channels.get(channelName).users.get(vips)) { + this.client.channels.get(channelName).users.set(vips, new users(this.client, {userName: vips,self: vips === this.userName,vip: true})); } }); Users.chatters.moderators.forEach((moderators) => { - if (!global.twitchApis.client.channels.get(channelName).users.get(moderators)) { - global.twitchApis.client.channels.get(channelName).users.set(moderators, + if (!this.client.channels.get(channelName).users.get(moderators)) { + this.client.channels.get(channelName).users.set(moderators, new users(this.client, {userName: moderators,self: moderators === this.userName,mod: true})); } }); Users.chatters.staff.forEach((staff) => { - if (!global.twitchApis.client.channels.get(channelName).users.get(staff)) { - global.twitchApis.client.channels.get(channelName).users.set(staff, + if (!this.client.channels.get(channelName).users.get(staff)) { + this.client.channels.get(channelName).users.set(staff, new users(this.client, {userName: staff,self: staff === this.userName,staff: true})); } }); Users.chatters.admins.forEach((admins) => { - if (!global.twitchApis.client.channels.get(channelName).users.get(admins)) { - global.twitchApis.client.channels.get(channelName).users.set(admins, + if (!this.client.channels.get(channelName).users.get(admins)) { + this.client.channels.get(channelName).users.set(admins, new users(this.client, {userName: admins,self: admins === this.userName,admin: true})); } }); Users.chatters.global_mods.forEach((global_mods) => { - if (!global.twitchApis.client.channels.get(channelName).users.get(global_mods)) { - global.twitchApis.client.channels.get(channelName).users.set(global_mods, + if (!this.client.channels.get(channelName).users.get(global_mods)) { + this.client.channels.get(channelName).users.set(global_mods, new users(this.client, {userName: global_mods,self: global_mods === this.userName,globalMod: true})); } }); Users.chatters.viewers.forEach((viewers) => { - if (!global.twitchApis.client.channels.get(channelName).users.get(viewers)) { - global.twitchApis.client.channels.get(channelName).users.set(viewers, + if (!this.client.channels.get(channelName).users.get(viewers)) { + this.client.channels.get(channelName).users.set(viewers, new users(this.client, {userName: viewers,self: viewers === this.userName})); } }); @@ -413,7 +413,6 @@ class SLEEPTMethods { user.self = user.userName === this.userName; user.broadcaster = user.badges.toString().includes('broadcaster'); user.id = user.self ? this.id : data.tags['user-id'] ? data.tags['user-id'] : user.id; - this.client.channels = global.twitchApis.client.channels; } disconnect() { diff --git a/src/structures/channels.js b/src/structures/channels.js index c9f9f25..d5ac00b 100644 --- a/src/structures/channels.js +++ b/src/structures/channels.js @@ -43,7 +43,7 @@ class channels { * Client.channels.get('channelName').send('message', ['replacer', 'replacer2', ...]) */ send(message, replacer) { - if (this.isConnected() && global.twitchApis.client.channels.get(this.name)) { + if (this.isConnected() && this.client.channels.get(this.name)) { return this.client.sleept.methods.sendMessage(this.name, message, replacer); } else { logger.error('Not connected to the channel: ' + this.name); From f461bec827d1f539007b87f789b7f55e5352e29d Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Mon, 18 Jan 2021 22:14:51 -0300 Subject: [PATCH 02/18] Implements onUserJoin event --- src/sleept/SLEEPTMethods.js | 27 +++++++++++++++++++++++---- src/utils/util.js | 22 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/sleept/SLEEPTMethods.js b/src/sleept/SLEEPTMethods.js index 32874e5..d317d03 100644 --- a/src/sleept/SLEEPTMethods.js +++ b/src/sleept/SLEEPTMethods.js @@ -1,7 +1,7 @@ /* eslint-disable indent */ const path = require('path'); const WebSocket = require('ws'); -const { constants, logger, parser } = require(path.resolve(__dirname,'..','utils')); +const { constants, logger, parser, Util } = require(path.resolve(__dirname,'..','utils')); const { channels, users } = require(path.resolve(__dirname,'..','structures')); /** @@ -184,9 +184,28 @@ class SLEEPTMethods { } else { switch (messageObject.command) { case 'JOIN': - this.client.eventEmmiter('Method.Joined.' + messageObject.params[0]); - this.client.eventEmmiter('join', this.client.channels.get(messageObject.params[0])); - this.generateUser(messageObject.params[0]); + this.getChatter(messageObject.params[0]).then((users) => { + var allUsers = []; + var catUsers = []; + var diffUsers = []; + users.chatters.broadcaster.forEach((name)=>{allUsers.push(name);}); + users.chatters.vips.forEach((name)=>{allUsers.push(name);}); + users.chatters.moderators.forEach((name)=>{allUsers.push(name);}); + users.chatters.staff.forEach((name)=>{allUsers.push(name);}); + users.chatters.admins.forEach((name)=>{allUsers.push(name);}); + users.chatters.global_mods.forEach((name)=>{allUsers.push(name);}); + users.chatters.viewers.forEach((name)=>{allUsers.push(name);}); + this.client.channels.get(messageObject.params[0]).users.forEach(user => catUsers.push(user.userName)); + diffUsers = Util.arr_diff(allUsers, catUsers); + diffUsers.forEach((User) => { + if (User !== this.userName) { + this.client.eventEmmiter('userJoin', User); + } + }); + this.client.eventEmmiter('Method.Joined.' + messageObject.params[0]); + this.client.eventEmmiter('join', this.client.channels.get(messageObject.params[0])); + this.generateUser(messageObject.params[0]); + }); break; case 'PART': if (this.client.channels.get(messageObject.params[0]).users.get(messageObject.prefix.slice(0, messageObject.prefix.indexOf('!')))) { diff --git a/src/utils/util.js b/src/utils/util.js index e763519..1075018 100644 --- a/src/utils/util.js +++ b/src/utils/util.js @@ -20,6 +20,28 @@ class util { } return given; } + static arr_diff(a1, a2) { + + var a = [], diff = []; + + for (var i = 0; i < a1.length; i++) { + a[a1[i]] = true; + } + + for (var o = 0; o < a2.length; o++) { + if (a[a2[o]]) { + delete a[a2[o]]; + } else { + a[a2[o]] = true; + } + } + + for (var k in a) { + diff.push(k); + } + + return diff; + } } module.exports = util; From f55f57a01ae5d4d9d0726bad88200cb2ea8ceadb Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Mon, 18 Jan 2021 22:48:10 -0300 Subject: [PATCH 03/18] Revert "Implements onUserJoin event" This reverts commit f461bec827d1f539007b87f789b7f55e5352e29d. --- src/sleept/SLEEPTMethods.js | 27 ++++----------------------- src/utils/util.js | 22 ---------------------- 2 files changed, 4 insertions(+), 45 deletions(-) diff --git a/src/sleept/SLEEPTMethods.js b/src/sleept/SLEEPTMethods.js index d317d03..32874e5 100644 --- a/src/sleept/SLEEPTMethods.js +++ b/src/sleept/SLEEPTMethods.js @@ -1,7 +1,7 @@ /* eslint-disable indent */ const path = require('path'); const WebSocket = require('ws'); -const { constants, logger, parser, Util } = require(path.resolve(__dirname,'..','utils')); +const { constants, logger, parser } = require(path.resolve(__dirname,'..','utils')); const { channels, users } = require(path.resolve(__dirname,'..','structures')); /** @@ -184,28 +184,9 @@ class SLEEPTMethods { } else { switch (messageObject.command) { case 'JOIN': - this.getChatter(messageObject.params[0]).then((users) => { - var allUsers = []; - var catUsers = []; - var diffUsers = []; - users.chatters.broadcaster.forEach((name)=>{allUsers.push(name);}); - users.chatters.vips.forEach((name)=>{allUsers.push(name);}); - users.chatters.moderators.forEach((name)=>{allUsers.push(name);}); - users.chatters.staff.forEach((name)=>{allUsers.push(name);}); - users.chatters.admins.forEach((name)=>{allUsers.push(name);}); - users.chatters.global_mods.forEach((name)=>{allUsers.push(name);}); - users.chatters.viewers.forEach((name)=>{allUsers.push(name);}); - this.client.channels.get(messageObject.params[0]).users.forEach(user => catUsers.push(user.userName)); - diffUsers = Util.arr_diff(allUsers, catUsers); - diffUsers.forEach((User) => { - if (User !== this.userName) { - this.client.eventEmmiter('userJoin', User); - } - }); - this.client.eventEmmiter('Method.Joined.' + messageObject.params[0]); - this.client.eventEmmiter('join', this.client.channels.get(messageObject.params[0])); - this.generateUser(messageObject.params[0]); - }); + this.client.eventEmmiter('Method.Joined.' + messageObject.params[0]); + this.client.eventEmmiter('join', this.client.channels.get(messageObject.params[0])); + this.generateUser(messageObject.params[0]); break; case 'PART': if (this.client.channels.get(messageObject.params[0]).users.get(messageObject.prefix.slice(0, messageObject.prefix.indexOf('!')))) { diff --git a/src/utils/util.js b/src/utils/util.js index 1075018..e763519 100644 --- a/src/utils/util.js +++ b/src/utils/util.js @@ -20,28 +20,6 @@ class util { } return given; } - static arr_diff(a1, a2) { - - var a = [], diff = []; - - for (var i = 0; i < a1.length; i++) { - a[a1[i]] = true; - } - - for (var o = 0; o < a2.length; o++) { - if (a[a2[o]]) { - delete a[a2[o]]; - } else { - a[a2[o]] = true; - } - } - - for (var k in a) { - diff.push(k); - } - - return diff; - } } module.exports = util; From 99919376de8e45d2732b7e1451c29a321c122bfe Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Wed, 20 Jan 2021 20:44:37 -0300 Subject: [PATCH 04/18] Convert api/functions/chatters.js and api/twitchWebAPI.js into classes --- src/sleept/SLEEPTMethods.js | 5 +- src/sleept/api/functions/chatters.js | 37 ++++++++----- src/sleept/api/twitchWebAPI.js | 80 +++++++++++++++------------- 3 files changed, 70 insertions(+), 52 deletions(-) diff --git a/src/sleept/SLEEPTMethods.js b/src/sleept/SLEEPTMethods.js index 32874e5..9014744 100644 --- a/src/sleept/SLEEPTMethods.js +++ b/src/sleept/SLEEPTMethods.js @@ -3,6 +3,7 @@ const path = require('path'); const WebSocket = require('ws'); const { constants, logger, parser } = require(path.resolve(__dirname,'..','utils')); const { channels, users } = require(path.resolve(__dirname,'..','structures')); +const { getChatter } = require(path.resolve(__dirname,'api')); /** * The main file. Connect with twitch websocket and provide access to irc. @@ -10,11 +11,11 @@ const { channels, users } = require(path.resolve(__dirname,'..','structures')); */ class SLEEPTMethods { constructor(sleeptMananger) { - const { getChatter } = require(path.resolve(__dirname,'api')); this.sleept = sleeptMananger; this.client = sleeptMananger.client; + var chatter = new getChatter(this.client.options); this._ackToken = null; - this.getChatter = getChatter; + this.getChatter = chatter.getChattersInfo; this.connected = 0; this.isAnonymous = false; this.joinQueueTimeout = []; diff --git a/src/sleept/api/functions/chatters.js b/src/sleept/api/functions/chatters.js index 0cf0aba..f406bf7 100644 --- a/src/sleept/api/functions/chatters.js +++ b/src/sleept/api/functions/chatters.js @@ -1,19 +1,28 @@ const path = require('path'); -const TwitchWebAPI = require(path.resolve(__dirname,'..','twitchWebAPI')); +const TwitchWebAPIC = require(path.resolve(__dirname,'..','twitchWebAPI')); -/** - * Get chatter info - */ -function getChattersInfo(channelName) { - return new Promise((resolve, reject) => { - if (channelName.startsWith('#')) {channelName = channelName.slice(1);} - const path = `/group/user/${channelName}/chatters`; - TwitchWebAPI.request('get', path).then(result => { - return resolve(result); - }).catch(err => { - return reject(err); +var request; + +class chatters { + constructor(options) { + const TwitchWebAPI = new TwitchWebAPIC(options); + request = TwitchWebAPI.request; + } + + /** + * Get chatter info + */ + getChattersInfo(channelName) { + return new Promise((resolve, reject) => { + if (channelName.startsWith('#')) {channelName = channelName.slice(1);} + const path = `/group/user/${channelName}/chatters`; + request('get', path).then(result => { + return resolve(result); + }).catch(err => { + return reject(err); + }); }); - }); + } } -module.exports = getChattersInfo; \ No newline at end of file +module.exports = chatters; \ No newline at end of file diff --git a/src/sleept/api/twitchWebAPI.js b/src/sleept/api/twitchWebAPI.js index cad06d5..e8f8373 100644 --- a/src/sleept/api/twitchWebAPI.js +++ b/src/sleept/api/twitchWebAPI.js @@ -1,51 +1,59 @@ const path = require('path'); const axios = require('axios'); -const apiUrl = global.twitchApis.client.option.http.api; -const headers = global.twitchApis.client.option.http.headers; const { logger } = require(path.resolve(__dirname,'..','..','utils')); -/** - * Do a http request to twitch web api - * @param {String} path - * @param {Object} options - */ -async function twitchRequest(method, path, options) { - return new Promise((resolve, reject) => { - const finalUrl = apiUrl + path; - - var hasParam = false; +var apiUrl; +var headers; - if (options) { - if (options.params) { - hasParam = true; - } - } +class twitchRequest { + constructor(options) { + apiUrl = options.http.api; + headers = options.http.headers; + } - if (method === 'get') { - if (hasParam) { - axios.get(finalUrl, { params: options.params, headers: headers }).then(result => { - return resolve(result.data); - }).catch(err => { - logger.error(err); - return reject(err); - }); + /** + * Do a http request to twitch web api + * @param {String} path + * @param {Object} options + */ + request(method, path, options) { + return new Promise((resolve, reject) => { + const finalUrl = apiUrl + path; + + var hasParam = false; + + if (options) { + if (options.params) { + hasParam = true; + } + } + + if (method === 'get') { + if (hasParam) { + axios.get(finalUrl, { params: options.params, headers: headers }).then(result => { + return resolve(result.data); + }).catch(err => { + logger.error(err); + return reject(err); + }); + } else { + axios.get(finalUrl, { headers: headers }).then(result => { + return resolve(result.data); + }).catch(err => { + logger.error(err); + return reject(err); + }); + } } else { - axios.get(finalUrl, { headers: headers }).then(result => { + axios.post(finalUrl, options.data, { headers: headers }).then(result => { return resolve(result.data); }).catch(err => { logger.error(err); return reject(err); }); } - } else { - axios.post(finalUrl, options.data, { headers: headers }).then(result => { - return resolve(result.data); - }).catch(err => { - logger.error(err); - return reject(err); - }); - } - }); + }); + } } -exports.request = twitchRequest; +module.exports = twitchRequest; From 347daabad64733808d0b1efe44b289b94abf1695 Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Wed, 20 Jan 2021 21:45:34 -0300 Subject: [PATCH 05/18] Remove unecessary global variables from client --- src/client/Client.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/client/Client.js b/src/client/Client.js index 30c8ad3..74e5ce0 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -21,15 +21,6 @@ class Client extends EventEmmiter { this.options = Util.mergeDefault(constants.defaultOptions, options); this._validateOptions(); - /** - * Defines the options as a organized global variable to use in - */ - global.twitchApis = { - client: { - option: this.options, - }, - }; - /** * Active Debug if Debug have to be activate */ @@ -100,8 +91,6 @@ class Client extends EventEmmiter { }; }); - global.twitchApis.client.channels = this.channels; - /** * Intervals set by {@link Client#setInterval} that are still active * @type {Set} From f35f0029f21e27cdbc20e595066deaf3656e0774 Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Fri, 22 Jan 2021 18:11:39 -0300 Subject: [PATCH 06/18] Adds and improve documentation on code for Client and SLEEPTMethods --- src/client/Client.js | 20 +++++++++- src/sleept/SLEEPTMethods.js | 77 +++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/client/Client.js b/src/client/Client.js index 74e5ce0..16a64e5 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -28,9 +28,16 @@ class Client extends EventEmmiter { logger.activeDebug(); } + /** + * Display a message saying debug is active is debug is active + */ logger.debug('Debug is active!'); Object.defineProperty(this, 'token', { writable: true }); + + /** + * Load client token from process enviroment if its not passed on login + */ if (!this.token && 'CLIENT_TOKEN' in process.env) { /** * Authorization token for the logged in user/bot @@ -62,6 +69,10 @@ class Client extends EventEmmiter { */ this.autoLogEnd = options.autoLogEnd; + /** + * Disable autoLogEnd if debug is actived for complete stacktraces + * also display a warn saying that + */ if (this.options.debug && this.autoLogEnd) { logger.warn('AutoLogEnd disabled because debug is enabled'); } @@ -74,10 +85,13 @@ class Client extends EventEmmiter { } /** - * Creates a collecion to each channel + * A collection with all channels * @type {Collection} */ this.channels = new collection(); + /** + * Create the channel collection for each channel + */ options.channels.forEach((channelName) => { if (channelName.slice(0, 1) !== '#') { channelName = '#' + channelName; @@ -97,6 +111,10 @@ class Client extends EventEmmiter { * @private */ this._intervals = new Set(); + + /** + * If messageSweepInterval is bigger than 0 start a interval of this time to run the sweepMessage function + */ if (options.messageSweepInterval > 0) { setInterval(this.sweepMessages.bind(this), options.messageSweepInterval * 1000); } diff --git a/src/sleept/SLEEPTMethods.js b/src/sleept/SLEEPTMethods.js index 9014744..21df025 100644 --- a/src/sleept/SLEEPTMethods.js +++ b/src/sleept/SLEEPTMethods.js @@ -22,10 +22,19 @@ class SLEEPTMethods { this.leaveQueueTimeout = []; } + /** + * @returns {Boolean} if websocket is connected + */ isConnected() { return this.ws !== null && this.ws.readyState === 1; } + /** + * Connects with websocket and auth with IRC + * @param {String} [token] the bot token + * @param {Boolean} [false] Connect with IRC in anonymous mode + * @returns {Promise} when connected with IRC + */ login(token) { return new Promise((resolve, reject) => { // eslint-disable-next-line max-len @@ -54,6 +63,10 @@ class SLEEPTMethods { }); } + /** + * Called every time a websocket message is received by IRC + * @param {String} [event] the raw message event to be parsed + */ onMessage(event) { this.MessageRawSplited = event.data.toString().split('\r\n'); this.MessageRawSplited.forEach((str) => { @@ -63,10 +76,17 @@ class SLEEPTMethods { }); } + /** + * Called when websocket went a error + * @param {String} [event] the raw error object to be parsed + */ onError(event) { logger.fatal(JSON.stringify(event.error)); } + /** + * Called when websocket connection close + */ onClose() { if (this.connected || this.connected === 0) { logger.fatal('Conection finished ;-;'); @@ -77,6 +97,9 @@ class SLEEPTMethods { this.client.eventEmmiter('_IRCDisconnect'); } + /** + * Called when websocket connection opens + */ onOpen() { if (this.ws.readyState !== 1) { return; @@ -97,6 +120,10 @@ class SLEEPTMethods { } } + /** + * Called when websocket connection close + * @param {Object} [messageObject] the object parsed by parser on onMessage + */ handlerMessage(messageObject) { if (messageObject === null) { return; @@ -119,6 +146,7 @@ class SLEEPTMethods { default: break; } + // Message with prefix tmi.twitch.tv } else if (messageObject.prefix === 'tmi.twitch.tv') { switch (messageObject.command) { case '002': @@ -177,11 +205,13 @@ class SLEEPTMethods { default: break; } + // Message with prefix username.tmi.twitch.tv } else if (messageObject.prefix === this.userName + '.tmi.twitch.tv') { switch (messageObject.command) { default: break; } + // Message with prefix don't match with anything above } else { switch (messageObject.command) { case 'JOIN': @@ -209,6 +239,9 @@ class SLEEPTMethods { } } + /** + * Called after websocket successfully connect with IRC and be on ready state + */ onConnected() { // Once connected connect the user to the servers he parsed on client inicialization this.client.options.channels.forEach((element, index) => { @@ -221,6 +254,12 @@ class SLEEPTMethods { this.connected = true; } + /** + * Connects with a twitch channel chat + * @param {String} [channel] the channel name who will be connected + * @param {Number=} [index] the index of channels list of element + * @return {Promise} Resolved when sucessfull connect with channel + */ join(channel, index) { return new Promise((resolve, reject) => { if (channel.includes(' ')) { @@ -261,6 +300,11 @@ class SLEEPTMethods { }); } + /** + * Leave from a twitch channel chat + * @param {String} [channel] the channel name who will be leaved + * @return {Promise} Resolved when sucessfull leave of the channel + */ leave(channel) { return new Promise((resolve, reject) => { if (channel.includes(' ')) { @@ -301,6 +345,10 @@ class SLEEPTMethods { }); } + /** + * Send a ping message to websocket + * @return {Promise} The ping in milliseconds with IRC + */ ping() { return new Promise((resolve, reject) => { var ping = new Date(); @@ -320,6 +368,13 @@ class SLEEPTMethods { }); } + /** + * Send a message to channel + * @param {String} [channel] The channel name where the message will be delivered + * @param {String} [message] The message content who will be sended + * @param {Array} [replacer] The replacements for %s on message content + * @return {Promise} returns when the message is sended + */ sendMessage(channel, message, ...replacer) { return new Promise((resolve, reject) => { if (typeof channel !== 'string') { @@ -346,6 +401,11 @@ class SLEEPTMethods { resolve(this.ws.send(`PRIVMSG ${channel} :${message}`)); }); } + + /** + * Generate users collections and added it to channel user collection + * @param {String} [channelName] The name of the channel to search for users + */ generateUser(channelName) { this.getChatter(channelName).then((Users) => { if (!this.client.channels.get(channelName)) {return;} @@ -393,6 +453,11 @@ class SLEEPTMethods { }); }); } + + /** + * Updates a user collection with the new data + * @param {Object} [data] The messageObject returned from twitch with a user data + */ async updateUser(data) { if (data.prefix === 'tmi.twitch.tv') data.prefix = this.userName + '!'; var user = this.client.channels.get(data.params[0]).users.get(data.prefix.slice(0, data.prefix.indexOf('!'))); @@ -416,6 +481,10 @@ class SLEEPTMethods { user.id = user.self ? this.id : data.tags['user-id'] ? data.tags['user-id'] : user.id; } + /** + * Disconnect from IRC + * @return {Promise} returns when IRC sucessfull disconnect + */ disconnect() { return new Promise((resolve, reject) => { if (this.ws && this.ws.readyState !== 3) { @@ -436,6 +505,14 @@ class SLEEPTMethods { }); } + /** + * Reply a message sended on channel + * @param {String} [msgId] The id of the message who will be responded + * @param {String} [channel] The channel name where the message will be delivered + * @param {String} [message] The message content who will be sended + * @param {Array} [replacer] The replacements for %s on message content + * @return {Promise} returns when the message is sended + */ replyMessage(msgId, channel, message, replacer) { return new Promise((resolve, reject) => { if (typeof channel !== 'string') { From e49fedde8e386bc338fd6e505d88dab5692d716e Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Sat, 23 Jan 2021 20:19:00 -0300 Subject: [PATCH 07/18] Add comments --- src/sleept/SLEEPTMananger.js | 16 ++++++++++++++++ src/sleept/api/functions/chatters.js | 3 +++ src/sleept/api/twitchWebAPI.js | 3 +++ src/structures/channels.js | 3 +++ src/structures/users.js | 3 +++ 5 files changed, 28 insertions(+) diff --git a/src/sleept/SLEEPTMananger.js b/src/sleept/SLEEPTMananger.js index d824c2c..219817f 100644 --- a/src/sleept/SLEEPTMananger.js +++ b/src/sleept/SLEEPTMananger.js @@ -5,6 +5,9 @@ const SequentialRequestHandler = require(path.resolve(__dirname,'RequestHandlers const BurstRequestHandler = require(path.resolve(__dirname,'RequestHandlers','Burst')); const { constants, logger } = require(path.resolve(__dirname,'..','utils')); +/** + * The manager for all things than envolve Sleept + */ class SLEEPTMananger { constructor(client) { this.client = client; @@ -15,6 +18,9 @@ class SLEEPTMananger { this.globallyRateLimited = false; } + /** + * Destroy all Sleept handlers + */ destroy() { for (const handlerKey of Object.keys(this.handlers)) { const handler = this.handlers[handlerKey]; @@ -22,6 +28,12 @@ class SLEEPTMananger { } } + /** + * push request to a handler + * @param {} [handler] the handler who will receive the request + * @param {} [apiRequest] the requrest who will be added to the handler + * @return {Promise} returned once the request is solved or rejected + */ push(handler, apiRequest) { return new Promise((resolve, reject) => { handler.push({ @@ -33,6 +45,10 @@ class SLEEPTMananger { }); } + /** + * Gets a hequest handler + * @return {'SequentialRequestHandler'|'BurstRequestHandler'} + */ getRequestHandler() { switch (this.client.options.apiRequestMethod) { case 'sequential': diff --git a/src/sleept/api/functions/chatters.js b/src/sleept/api/functions/chatters.js index f406bf7..578a6d2 100644 --- a/src/sleept/api/functions/chatters.js +++ b/src/sleept/api/functions/chatters.js @@ -3,6 +3,9 @@ const TwitchWebAPIC = require(path.resolve(__dirname,'..','twitchWebAPI')); var request; +/** + * The class for the getChattersInfo function + */ class chatters { constructor(options) { const TwitchWebAPI = new TwitchWebAPIC(options); diff --git a/src/sleept/api/twitchWebAPI.js b/src/sleept/api/twitchWebAPI.js index e8f8373..5e83100 100644 --- a/src/sleept/api/twitchWebAPI.js +++ b/src/sleept/api/twitchWebAPI.js @@ -5,6 +5,9 @@ const { logger } = require(path.resolve(__dirname,'..','..','utils')); var apiUrl; var headers; +/** + * Api for making http requests to twitch + */ class twitchRequest { constructor(options) { apiUrl = options.http.api; diff --git a/src/structures/channels.js b/src/structures/channels.js index d5ac00b..0b9258b 100644 --- a/src/structures/channels.js +++ b/src/structures/channels.js @@ -1,6 +1,9 @@ const path = require('path'); const { logger, collection } = require(path.resolve(__dirname,'..','utils')); +/** + * Channel collection template for creating all channels collections + */ class channels { constructor(client, data) { /** diff --git a/src/structures/users.js b/src/structures/users.js index fd6e77f..6ee4f72 100644 --- a/src/structures/users.js +++ b/src/structures/users.js @@ -1,3 +1,6 @@ +/** + * User collection template for creating all Users collections + */ class Users { constructor(client, data) { /** From 1f60644abb7e9922d4b708c7988d1161dfe56100 Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Sun, 24 Jan 2021 11:21:22 -0300 Subject: [PATCH 08/18] Reduce generateUser method size on SleeptMethods --- src/sleept/SLEEPTMethods.js | 59 +++++++++++-------------------------- 1 file changed, 18 insertions(+), 41 deletions(-) diff --git a/src/sleept/SLEEPTMethods.js b/src/sleept/SLEEPTMethods.js index 21df025..c85d95c 100644 --- a/src/sleept/SLEEPTMethods.js +++ b/src/sleept/SLEEPTMethods.js @@ -5,6 +5,15 @@ const { constants, logger, parser } = require(path.resolve(__dirname,'..','utils const { channels, users } = require(path.resolve(__dirname,'..','structures')); const { getChatter } = require(path.resolve(__dirname,'api')); +const twitchUserRolesNameParser = { + broadcaster: 'broadcaster', + vips: 'vip', + moderators: 'mod', + staff: 'staff', + admins: 'admin', + global_mods: 'globalMod', +}; + /** * The main file. Connect with twitch websocket and provide access to irc. * @private @@ -409,47 +418,15 @@ class SLEEPTMethods { generateUser(channelName) { this.getChatter(channelName).then((Users) => { if (!this.client.channels.get(channelName)) {return;} - Users.chatters.broadcaster.forEach((broadcaster) => { - if (!this.client.channels.get(channelName).users.get(broadcaster)) { - this.client.channels.get(channelName).users.set(broadcaster, - new users(this.client, {userName: broadcaster,self: broadcaster === this.userName,broadcaster: true,})); - } - }); - Users.chatters.vips.forEach((vips) => { - if (!this.client.channels.get(channelName).users.get(vips)) { - this.client.channels.get(channelName).users.set(vips, - new users(this.client, {userName: vips,self: vips === this.userName,vip: true})); - } - }); - Users.chatters.moderators.forEach((moderators) => { - if (!this.client.channels.get(channelName).users.get(moderators)) { - this.client.channels.get(channelName).users.set(moderators, - new users(this.client, {userName: moderators,self: moderators === this.userName,mod: true})); - } - }); - Users.chatters.staff.forEach((staff) => { - if (!this.client.channels.get(channelName).users.get(staff)) { - this.client.channels.get(channelName).users.set(staff, - new users(this.client, {userName: staff,self: staff === this.userName,staff: true})); - } - }); - Users.chatters.admins.forEach((admins) => { - if (!this.client.channels.get(channelName).users.get(admins)) { - this.client.channels.get(channelName).users.set(admins, - new users(this.client, {userName: admins,self: admins === this.userName,admin: true})); - } - }); - Users.chatters.global_mods.forEach((global_mods) => { - if (!this.client.channels.get(channelName).users.get(global_mods)) { - this.client.channels.get(channelName).users.set(global_mods, - new users(this.client, {userName: global_mods,self: global_mods === this.userName,globalMod: true})); - } - }); - Users.chatters.viewers.forEach((viewers) => { - if (!this.client.channels.get(channelName).users.get(viewers)) { - this.client.channels.get(channelName).users.set(viewers, - new users(this.client, {userName: viewers,self: viewers === this.userName})); - } + Object.keys(Users.chatters).forEach((type) => { + Users.chatters[type].forEach(async (User) => { + if (!this.client.channels.get(channelName).users.get(User)) { + await this.client.channels.get(channelName).users.set(User, + new users(this.client, {userName: User,self: User === this.userName})); + // Add adictional infomartion + this.client.channels.get(channelName).users.get(User)[twitchUserRolesNameParser[type]] = true; + } + }); }); }); } From ec8b5855d3e24c3659d35c5b2d6a9e0e861badaa Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Mon, 25 Jan 2021 13:10:15 -0300 Subject: [PATCH 09/18] Transform logger in class --- src/client/Client.js | 11 ++--- src/sleept/SLEEPTMananger.js | 5 ++- src/sleept/SLEEPTMethods.js | 4 +- src/sleept/api/twitchWebAPI.js | 5 ++- src/utils/AutoEndLog.js | 1 + src/utils/logger.js | 77 ++++++++++++---------------------- 6 files changed, 41 insertions(+), 62 deletions(-) diff --git a/src/client/Client.js b/src/client/Client.js index 16a64e5..f1daf2e 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -1,9 +1,11 @@ const path = require('path'); const EventEmmiter = require('events'); const SLEEPTManager = require(path.resolve(__dirname,'..','sleept','SLEEPTMananger')); -const { autoEndLog, constants, logger, Util, collection } = require(path.resolve(__dirname,'..','utils')); +const { autoEndLog, constants, logger: LoggerC, Util, collection } = require(path.resolve(__dirname,'..','utils')); const channel = require(path.resolve(__dirname,'..','structures','channels')); +var logger; + /** * Creates the main class to generate clients. * @extends {EventEmmiter} @@ -21,12 +23,7 @@ class Client extends EventEmmiter { this.options = Util.mergeDefault(constants.defaultOptions, options); this._validateOptions(); - /** - * Active Debug if Debug have to be activate - */ - if (this.options.debug) { - logger.activeDebug(); - } + logger = new LoggerC({debug:this.options.debug}); /** * Display a message saying debug is active is debug is active diff --git a/src/sleept/SLEEPTMananger.js b/src/sleept/SLEEPTMananger.js index 219817f..de16960 100644 --- a/src/sleept/SLEEPTMananger.js +++ b/src/sleept/SLEEPTMananger.js @@ -3,8 +3,8 @@ const UserAgentManager = require(path.resolve(__dirname,'UserAgentManager')); const SLEEPTMethods = require(path.resolve(__dirname,'SLEEPTMethods')); const SequentialRequestHandler = require(path.resolve(__dirname,'RequestHandlers','Sequential')); const BurstRequestHandler = require(path.resolve(__dirname,'RequestHandlers','Burst')); -const { constants, logger } = require(path.resolve(__dirname,'..','utils')); - +const { constants, logger: LoggerC } = require(path.resolve(__dirname,'..','utils')); +var logger; /** * The manager for all things than envolve Sleept */ @@ -16,6 +16,7 @@ class SLEEPTMananger { this.methods = new SLEEPTMethods(this); this.rateLimitedEndpoints = {}; this.globallyRateLimited = false; + logger = new LoggerC({debug: this.client.options.debug}); } /** diff --git a/src/sleept/SLEEPTMethods.js b/src/sleept/SLEEPTMethods.js index c85d95c..98d0d23 100644 --- a/src/sleept/SLEEPTMethods.js +++ b/src/sleept/SLEEPTMethods.js @@ -1,9 +1,10 @@ /* eslint-disable indent */ const path = require('path'); const WebSocket = require('ws'); -const { constants, logger, parser } = require(path.resolve(__dirname,'..','utils')); +const { constants, logger: LoggerC, parser } = require(path.resolve(__dirname,'..','utils')); const { channels, users } = require(path.resolve(__dirname,'..','structures')); const { getChatter } = require(path.resolve(__dirname,'api')); +var logger; const twitchUserRolesNameParser = { broadcaster: 'broadcaster', @@ -29,6 +30,7 @@ class SLEEPTMethods { this.isAnonymous = false; this.joinQueueTimeout = []; this.leaveQueueTimeout = []; + logger = new LoggerC({debug: this.client.options.debug}); } /** diff --git a/src/sleept/api/twitchWebAPI.js b/src/sleept/api/twitchWebAPI.js index 5e83100..3f8c635 100644 --- a/src/sleept/api/twitchWebAPI.js +++ b/src/sleept/api/twitchWebAPI.js @@ -1,7 +1,7 @@ const path = require('path'); const axios = require('axios'); -const { logger } = require(path.resolve(__dirname,'..','..','utils')); - +const { logger: LoggerC } = require(path.resolve(__dirname,'..','..','utils')); +var logger; var apiUrl; var headers; @@ -12,6 +12,7 @@ class twitchRequest { constructor(options) { apiUrl = options.http.api; headers = options.http.headers; + logger = new LoggerC({debug: options.debug}); } /** diff --git a/src/utils/AutoEndLog.js b/src/utils/AutoEndLog.js index 3b8d4c8..6c2936c 100644 --- a/src/utils/AutoEndLog.js +++ b/src/utils/AutoEndLog.js @@ -1,5 +1,6 @@ const path = require('path'); var logger = require(path.resolve(__dirname,'logger')); +logger = new logger(); var Exited; function exitHandler(options, exitCode) { diff --git a/src/utils/logger.js b/src/utils/logger.js index 25ca847..95670c9 100644 --- a/src/utils/logger.js +++ b/src/utils/logger.js @@ -1,59 +1,36 @@ const path = require('path'); var dateParser = require(path.resolve(__dirname,'DateParser')); var chalk = require('chalk'); -var debug; -function activeDebug() { - debug = true; - this.debug = logger('debug'); -} +class logger { + constructor(options) { + this.debugActive = options ? options.debug : false; + } -function log(Gravity) { - return function (Message) { - var Chalker; - var Msg = `[${dateParser.getTime()}] ${Gravity}: ${Message}`; - switch (Gravity) { - case 'fatal': - if (Message.toString().split(' ')[0].toLowerCase().includes('error')) { - Msg = `[${dateParser.getTime()}] ${Gravity} ${Message}`; - } else { - Msg = `[${dateParser.getTime()}] ${Gravity}: ${Message}`; - } - console.trace(chalk.bgWhite(chalk.red(Msg))); - process.exit(5); - break; - case 'error': - Chalker = chalk.red(Msg); - break; - case 'warn': - Chalker = chalk.keyword('orange')(Msg); - break; - case 'info': - Msg = `${Gravity}: ${Message}`; - Chalker = chalk.blueBright(`[${dateParser.getTime()}] `) + Msg; - break; - case 'debug': - Msg = `${Message}`; - Chalker = chalk.gray(`[${dateParser.getTime()}] ${Gravity}: `) + chalk.hex('#AAA')(Msg); - break; - } - console[Gravity](Chalker); - }; -} + fatal(Message) { + // eslint-disable-next-line max-len + console.trace(chalk.bgWhite(chalk.red(Message.toString().split(' ')[0].toLowerCase().includes('error') ? `[${dateParser.getTime()}] Fatal ${Message}` : `[${dateParser.getTime()}] Fatal: ${Message}`))); + process.exit(5); + } + + error(Message) { + // eslint-disable-next-line max-len + console.error(chalk.red(Message.toString().split(' ')[0].toLowerCase().includes('error') ? `[${dateParser.getTime()}] ${Message}` : `[${dateParser.getTime()}] Error: ${Message}`)); + } + + warn(Message) { + console.warn(chalk.keyword('orange')(`[${dateParser.getTime()}] Warn: ${Message}`)); + } -function logger(Gravity) { - if ((Gravity === 'debug' && debug) || Gravity !== 'debug') { - return log(Gravity); - } else { - return () => {}; + info(Message) { + console.info(chalk.blueBright(`[${dateParser.getTime()}] `) + `Info: ${Message}`); + } + + debug(Message) { + if (this.debugActive) { + console.debug(chalk.gray(`[${dateParser.getTime()}] Debug: `) + chalk.hex('#AAA')(Message)); + } } } -module.exports = { - activeDebug: activeDebug, - fatal: logger('fatal'), - error: logger('error'), - warn: logger('warn'), - info: logger('info'), - debug: logger('debug'), -}; +module.exports = logger; From 812266e6ebc1fc8b8a915ea93113bda434d643a7 Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Wed, 27 Jan 2021 21:53:18 -0300 Subject: [PATCH 10/18] Update todos --- README.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e69005a..dc9f302 100644 --- a/README.md +++ b/README.md @@ -36,21 +36,27 @@ ## TODO -- [x] | Make a auto updated list of users of channels +- [x] Make a auto updated list of users of channels - [x] | Create automatizated tests. - [x] | Disconnect IRC function. - [x] | Make reply uses new thread system of twitch. (beta ⚙️) - [x] | FanMode (Anonymous mode). +- [x] | Remove global variables. +- [x] | Convert api/functions/chatters.js into class +- [x] | Convert api/twitchWebAPI.js into class +- [x] | Reduce generateUser method size +- [x] | Organize annotations. (not sure enough ⚙️) +- [x] | Transform logger in class - [ ] | Create onUserJoin event. (Emitted everytime someone new enter in the chat) - [ ] | Create onUserLeave event. (Emitted everytime someone leaves the chat) - [ ] | Create Shard system. -- [ ] | Implement other types of connections with twitch (To alloy the bot to make things like follow someone, get stream details, ...) -- [ ] | Remove global variables. -- [ ] | Organize annotations. -- [ ] | Reduce generateUser function size +- [ ] | Implement other http methods (To make things like follow, get stream details, ...) - [ ] | Split SleeptMethods because it is too much dirty -- [ ] | Convert api/getChatter.js into class -- [ ] | Create own parser +- [ ] | [Create own parser](#create-own-parser) +#### Create own parser +- [ ] | Plan the new object structure +- [ ] | Code the new parser +- [ ] | Replace old parser code ## About From fb80742a7db1270a0d85afd95dec7976f71af0af Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Fri, 29 Jan 2021 17:48:32 -0300 Subject: [PATCH 11/18] Update Logo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc9f302..183e11b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[]() +[]()

From 8cb8c3f44cf721c913c41a2f69f05bd401125fa9 Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Fri, 29 Jan 2021 17:57:03 -0300 Subject: [PATCH 12/18] Update Logo 2 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 183e11b..f5cdaa4 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@

-[](https://twitchapis.org/discord) [
](https://www.npmjs.com/package/@twitchapis/twitch.js) +[](https://twitchapis.org/discord) [
](https://www.npmjs.com/package/@twitchapis/twitch.js)

From f95ddb2ad0c4a3b2b613a71af11ed522d8b64b0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 07:50:39 +0000 Subject: [PATCH 13/18] Bump eslint from 7.18.0 to 7.19.0 Bumps [eslint](https://github.com/eslint/eslint) from 7.18.0 to 7.19.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v7.18.0...v7.19.0) Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index be40088..40def55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -274,9 +274,9 @@ "dev": true }, "eslint": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz", - "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.19.0.tgz", + "integrity": "sha512-CGlMgJY56JZ9ZSYhJuhow61lMPPjUzWmChFya71Z/jilVos7mR/jPgaEfVGgMBY5DshbKdG8Ezb8FDCHcoMEMg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -460,9 +460,9 @@ } }, "flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, "follow-redirects": { From deef8ddb8778e39f723e0742f35b0704583415dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Feb 2021 06:17:03 +0000 Subject: [PATCH 14/18] Bump ws from 7.4.2 to 7.4.3 Bumps [ws](https://github.com/websockets/ws) from 7.4.2 to 7.4.3. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/7.4.2...7.4.3) Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40def55..368f066 100644 --- a/package-lock.json +++ b/package-lock.json @@ -951,9 +951,9 @@ "dev": true }, "ws": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", - "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==" + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", + "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==" }, "yallist": { "version": "4.0.0", From dcf17de2d5fb8f174d99e25a82f64b2093ad74e0 Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Fri, 12 Feb 2021 21:41:39 -0300 Subject: [PATCH 15/18] =?UTF-8?q?=F0=9F=95=B8=EF=B8=8F=20Add=20twitch=20to?= =?UTF-8?q?ken=20verification=20endpoint=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sleept/SLEEPTMethods.js | 23 ++++++++++++---- src/sleept/api/functions/validator.js | 39 +++++++++++++++++++++++++++ src/sleept/api/index.js | 1 + src/sleept/api/twitchWebAPI.js | 15 +++++++---- 4 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 src/sleept/api/functions/validator.js diff --git a/src/sleept/SLEEPTMethods.js b/src/sleept/SLEEPTMethods.js index 98d0d23..6fb3af6 100644 --- a/src/sleept/SLEEPTMethods.js +++ b/src/sleept/SLEEPTMethods.js @@ -3,7 +3,7 @@ const path = require('path'); const WebSocket = require('ws'); const { constants, logger: LoggerC, parser } = require(path.resolve(__dirname,'..','utils')); const { channels, users } = require(path.resolve(__dirname,'..','structures')); -const { getChatter } = require(path.resolve(__dirname,'api')); +const { getChatter, validator } = require(path.resolve(__dirname,'api')); var logger; const twitchUserRolesNameParser = { @@ -24,8 +24,10 @@ class SLEEPTMethods { this.sleept = sleeptMananger; this.client = sleeptMananger.client; var chatter = new getChatter(this.client.options); + var validate = new validator(this.client.options); this._ackToken = null; this.getChatter = chatter.getChattersInfo; + this.validate = validate.validate; this.connected = 0; this.isAnonymous = false; this.joinQueueTimeout = []; @@ -47,7 +49,8 @@ class SLEEPTMethods { * @returns {Promise} when connected with IRC */ login(token) { - return new Promise((resolve, reject) => { + // eslint-disable-next-line no-async-promise-executor + return new Promise(async (resolve, reject) => { // eslint-disable-next-line max-len if ((typeof token !== 'string' && typeof token !== 'boolean') || (typeof token === 'string' && !token.startsWith('oauth:')) || (typeof token === 'string' && token.includes(' ')) || (typeof token === 'boolean' && token !== false)) { reject(constants.errors.INVALID_TOKEN); @@ -56,10 +59,20 @@ class SLEEPTMethods { if (token === false) { this.isAnonymous = true; } else { - this.client.token = token; - this.userName = 'twitchjs'; // Just to start the connection after that, twitch sends back the bot name and we replace it - this.id = ''; + this.client.token = token; + } + if (!this.isAnonymous) { + await this.validate(this.client.token).then((results) => { + this.client.clientId = results.client_id; + this.userName = results.login.toString(); + this.id = results.user_id; + this.scopes = results.scopes; + }).catch(() => { + reject(constants.errors.INVALID_TOKEN); + logger.fatal(constants.errors.INVALID_TOKEN); + }); } + this.server = this.client.options.http.host; this.ws = new WebSocket(`wss://${this.server}:443`); this.ws.onmessage = this.onMessage.bind(this); diff --git a/src/sleept/api/functions/validator.js b/src/sleept/api/functions/validator.js new file mode 100644 index 0000000..8166155 --- /dev/null +++ b/src/sleept/api/functions/validator.js @@ -0,0 +1,39 @@ +const path = require('path'); +const TwitchWebAPIC = require(path.resolve(__dirname,'..','twitchWebAPI')); + +var request; + +/** + * The class for the validator function + */ +class validator { + constructor(options) { + const TwitchWebAPI = new TwitchWebAPIC(options); + request = TwitchWebAPI.request; + } + + /** + * validate + */ + validate(token) { + return new Promise((resolve, reject) => { + const path = 'https://id.twitch.tv/oauth2/validate'; + if (token.startsWith('oauth:')) { + token = token.split(':'); + token[0] = 'OAuth'; + token = token.join(' '); + } else { + token = 'OAuth ' + token; + } + const header = {'Authorization': token}; + + request('get', path, {headers: header}).then(result => { + return resolve(result); + }).catch(err => { + return reject(err); + }); + }); + } +} + +module.exports = validator; \ No newline at end of file diff --git a/src/sleept/api/index.js b/src/sleept/api/index.js index 84fa6f9..5bb8cf8 100644 --- a/src/sleept/api/index.js +++ b/src/sleept/api/index.js @@ -2,4 +2,5 @@ const path = require('path'); module.exports = { getChatter: require(path.resolve(__dirname,'functions','chatters')), + validator: require(path.resolve(__dirname,'functions','validator')) }; diff --git a/src/sleept/api/twitchWebAPI.js b/src/sleept/api/twitchWebAPI.js index 3f8c635..d727114 100644 --- a/src/sleept/api/twitchWebAPI.js +++ b/src/sleept/api/twitchWebAPI.js @@ -22,7 +22,12 @@ class twitchRequest { */ request(method, path, options) { return new Promise((resolve, reject) => { - const finalUrl = apiUrl + path; + var finalUrl; + if (!path.startsWith('http')) { + finalUrl = apiUrl + path; + } else { + finalUrl = path; + } var hasParam = false; @@ -31,17 +36,17 @@ class twitchRequest { hasParam = true; } } - + if (method === 'get') { if (hasParam) { - axios.get(finalUrl, { params: options.params, headers: headers }).then(result => { + axios.get(finalUrl, { params: options.params, headers: options.params || headers }).then(result => { return resolve(result.data); }).catch(err => { logger.error(err); return reject(err); }); } else { - axios.get(finalUrl, { headers: headers }).then(result => { + axios.get(finalUrl, { headers: (options ? (options.headers || headers) : headers) }).then(result => { return resolve(result.data); }).catch(err => { logger.error(err); @@ -49,7 +54,7 @@ class twitchRequest { }); } } else { - axios.post(finalUrl, options.data, { headers: headers }).then(result => { + axios.post(finalUrl, options.data, { headers: options.headers || headers }).then(result => { return resolve(result.data); }).catch(err => { logger.error(err); From 38d0bc1adc32e2a82e9de7753b75e46fe4fa6bd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Feb 2021 08:16:23 +0000 Subject: [PATCH 16/18] Bump eslint from 7.19.0 to 7.20.0 Bumps [eslint](https://github.com/eslint/eslint) from 7.19.0 to 7.20.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v7.19.0...v7.20.0) Signed-off-by: dependabot[bot] --- package-lock.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 368f066..e7a2616 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,12 +20,12 @@ "dev": true }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -274,12 +274,12 @@ "dev": true }, "eslint": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.19.0.tgz", - "integrity": "sha512-CGlMgJY56JZ9ZSYhJuhow61lMPPjUzWmChFya71Z/jilVos7mR/jPgaEfVGgMBY5DshbKdG8Ezb8FDCHcoMEMg==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.20.0.tgz", + "integrity": "sha512-qGi0CTcOGP2OtCQBgWZlQjcTuP0XkIpYFj25XtRTQSHC+umNnp7UMshr2G8SLsRFYDdAPFeHOsiteadmMH02Yw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", + "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.3.0", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -291,7 +291,7 @@ "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", - "esquery": "^1.2.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", @@ -377,9 +377,9 @@ "dev": true }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -874,9 +874,9 @@ }, "dependencies": { "ajv": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", - "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.0.tgz", + "integrity": "sha512-svS9uILze/cXbH0z2myCK2Brqprx/+JJYK5pHicT/GQiBfzzhUVAIT6MwqJg8y4xV/zoGsUeuPuwtoiKSGE15g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", From f060c9dd55e91f3d586f381b8e56121b6b57e74b Mon Sep 17 00:00:00 2001 From: Space_Inteprise Date: Wed, 17 Feb 2021 20:06:13 -0300 Subject: [PATCH 17/18] Backwards compatibility --- src/structures/users.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/structures/users.js b/src/structures/users.js index 6ee4f72..94518b8 100644 --- a/src/structures/users.js +++ b/src/structures/users.js @@ -12,6 +12,7 @@ class Users { Object.defineProperty(this, 'client', { value: client }); this.userName = data.userName; + this.username = this.userName; this.haveBadges = data.haveBadges ? data.haveBadges : false; this.badges = data.badges ? data.badges : ''; From a9265d86e23a61f3c7faf4387898404089c63905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lobo=20Metal=C3=BArgico?= <43734867+LoboMetalurgico@users.noreply.github.com> Date: Wed, 17 Feb 2021 20:23:27 -0300 Subject: [PATCH 18/18] Beta 13 release --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e7a2616..119cae7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@twitchapis/twitch.js", - "version": "1.0.0-beta.12", + "version": "1.0.0-beta.13", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index cef4b7e..f84e1ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@twitchapis/twitch.js", - "version": "1.0.0-beta.12", + "version": "1.0.0-beta.13", "description": "twitch.js is a powerful Node.js module that allows you to easily interact with the TwitchTV making easy the way to make a TwitchTV bot, for a custom chat overlay for you OBS, or a moderation bot for you chat, or you just want a easy interface to TwitchTV.", "main": "./src/index", "scripts": {