twitch-toolkit
Advanced tools
Comparing version 0.0.5 to 0.0.6
@@ -0,0 +0,0 @@ module.exports = { |
23
index.js
@@ -8,2 +8,7 @@ 'use strict'; | ||
/** | ||
* @class Twitch | ||
* Create the toolkit with its modules. | ||
* @param {object} config | ||
*/ | ||
function Twitch(config) { | ||
@@ -37,2 +42,5 @@ this.config = config || {}; | ||
/** | ||
* Connect to twitch chat. | ||
*/ | ||
Twitch.prototype.connect = async function () { | ||
@@ -46,2 +54,5 @@ try { | ||
/** | ||
* Disconnect from the twitch chat. | ||
*/ | ||
Twitch.prototype.disconnect = async function () { | ||
@@ -55,2 +66,6 @@ try { | ||
/** | ||
* Check if the stream is live. | ||
* @return {bool} True if the stream is live and false otherwise. | ||
*/ | ||
Twitch.prototype.isLive = async function () { | ||
@@ -67,2 +82,6 @@ try { | ||
/** | ||
* Get the bot user data. | ||
* @return {object} The bot user data object. | ||
*/ | ||
Twitch.prototype.getBotUser = async function () { | ||
@@ -79,2 +98,6 @@ try { | ||
/** | ||
* Get the stream user data. | ||
* @return {object} The stream user data object. | ||
*/ | ||
Twitch.prototype.getStreamUser = async function () { | ||
@@ -81,0 +104,0 @@ try { |
{ | ||
"name": "twitch-toolkit", | ||
"version": "0.0.5", | ||
"description": "A set of tools to integrate with Twitch API, Twitch Chat and Twitch WebHooks.", | ||
"version": "0.0.6", | ||
"description": | ||
"A set of tools to integrate with Twitch API, Twitch Chat and Twitch WebHooks.", | ||
"keywords": [ | ||
@@ -21,3 +22,4 @@ "twitch", | ||
"scripts": { | ||
"test": "node_modules/.bin/mocha" | ||
"test": "node_modules/.bin/mocha", | ||
"generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose" | ||
}, | ||
@@ -44,4 +46,5 @@ "author": "chriteixeira", | ||
"jsdoc": "3.5.5", | ||
"minami": "1.2.3", | ||
"mocha": "3.0.0" | ||
} | ||
} |
@@ -5,6 +5,8 @@ # twitch-toolkit | ||
A set of tools to integrate with Twitch API, Twitch Chat and Twitch WebHooks. | ||
A set of tools to integrate with Twitch API, Twitch Chat and Twitch WebHooks. | ||
[![NPM](https://nodei.co/npm/twitch-toolkit.png?downloads=true&downloadRank=true)](https://nodei.co/npm/twitch-toolkit/) | ||
To start to use this module, check the [project documentation](https://chriteixeira.github.io/twitch-toolkit/0.0.6/) | ||
## Installation | ||
@@ -27,5 +29,5 @@ | ||
```javascript | ||
const Twitch = require('twitch-toolkit'); | ||
const twitch = require('twitch-toolkit'); | ||
let twitch = new Twitch(config); | ||
var twitch = new Twitch(config); | ||
``` | ||
@@ -37,15 +39,15 @@ | ||
| ------------- | ------------------- | --------------- | | ||
| logger | logger object | The logger instance. | | ||
| debug | Boolean | A flag to enable the debug mode. `Default: false` | | ||
| client_id | String | The Twitch.tv client ID to be used to access the services. | | ||
| client_secret | String | The Twitch.tv client secret to be used to use the private services. | | ||
| chatOptions | Object | The chat configuration object | | ||
| chatOptions.reconnect | Boolean | A flag to enable the auto-reconnect mode. `Default: false` | | ||
| chatOptions.ignoreSelf | Boolean | A flag to ignore the bots own messages. `Default: false` | | ||
| chatOptions.username | String | The bot's username. | | ||
| chatOptions.password | String | The bot's OAuth Token. You can get it at http://twitchapps.com/tmi/ | | ||
| chatOptions.channels | Array[String] | The list os channels the bot will join and listen. | | ||
| chatOptions.chatCommands | Object | The object with the chatCommands, described below | | ||
| chatOptions.whisperCommands | Object | The object with the whisperCommands, described below | | ||
| chatOptions.wordTriggers | Object | The object with the wordTriggers, described below | | ||
| logger | object | The logger instance. | | ||
| debug | bool | A flag to enable the debug mode. `Default: false` | | ||
| client_id | string | The Twitch.tv client ID to be used to access the services. | | ||
| client_secret | string | The Twitch.tv client secret to be used to use the private services. | | ||
| chatOptions | object | The chat configuration object | | ||
| chatOptions.reconnect | bool | A flag to enable the auto-reconnect mode. `Default: false` | | ||
| chatOptions.ignoreSelf | bool | A flag to ignore the bots own messages. `Default: false` | | ||
| chatOptions.username | string | The bot's username. | | ||
| chatOptions.password | string | The bot's OAuth Token. You can get it at http://twitchapps.com/tmi/ | | ||
| chatOptions.channels | array[string] | The list os channels the bot will join and listen. | | ||
| chatOptions.chatCommands | object | The object with the chatCommands, described below | | ||
| chatOptions.whisperCommands | object | The object with the whisperCommands, described below | | ||
| chatOptions.wordTriggers | object | The object with the wordTriggers, described below | | ||
@@ -56,21 +58,37 @@ ### API | ||
```javascript | ||
let twitchAPI = twitch.api; | ||
var twitchAPI = twitch.api; | ||
``` | ||
The methods are described in the [TwitchApi documentation page](https://chriteixeira.github.io/twitch-toolkit/0.0.6/TwitchApi.html) | ||
### Chat | ||
The chat module will be created with the toolkit object and can be acessed by its name: | ||
The chat module will be created with the toolkit new instance but, the user will only join and list to the chat when connect is executed: | ||
```javascript | ||
let twitchChat = twitch.chat; | ||
var twitchChat = twitch.chat; | ||
twitch.connect(); | ||
``` | ||
The module will be ready to use but the user won't join the chat until you explicitly connect to it: | ||
After that, you'll be able to listen to channel and chat events. You can also disconnect from the chat, if you wish: | ||
```javascript | ||
twitch.connect(); | ||
twitch.disconnect | ||
``` | ||
#### Chat Commands | ||
#### Whisper Commands | ||
#### Word Triggers | ||
The methods and events are described in the [TwitchChatEmitter documentation page](https://chriteixeira.github.io/twitch-toolkit/0.0.6/TwitchChatEmitter.html) | ||
### WebSub | ||
### Webhooks | ||
The Twitch Webhooks implementation, as described in https://dev.twitch.tv/docs/api/webhooks-guide/ . | ||
To access the Webhook module: | ||
The API module will be created with the toolkit object and can be acessed by its name: | ||
```javascript | ||
var twitchWebSub = twitch.websub; | ||
``` | ||
The Webhook/WebSub requires a public endpoint on the running express server/application to receive the data from the hub. Without this, its impossible to make this work. | ||
The methods and events are described in the [TwitchWebSub documentation page](https://chriteixeira.github.io/twitch-toolkit/0.0.6/TwitchWebSub.html) |
@@ -17,23 +17,3 @@ 'use strict'; | ||
TwitchApi.prototype.auth = async function() { | ||
try { | ||
var response = await request({ | ||
url: 'https://api.twitch.tv/kraken/oauth2/token', | ||
method: 'POST', | ||
form: { | ||
client_id: this.config.client_id, | ||
client_secret: this.config.client_secret, | ||
grant_type: 'client_credentials', | ||
scope: 'user:edit user:read:email' | ||
}, | ||
json: true | ||
}); | ||
this.accessToken = response.access_token; | ||
return this.accessToken; | ||
} catch (err) { | ||
throw err; | ||
} | ||
}; | ||
TwitchApi.prototype.authValidateToken = async function(token) { | ||
@@ -49,3 +29,3 @@ try { | ||
return response; | ||
return JSON.parse(response); | ||
} catch (err) { | ||
@@ -60,11 +40,11 @@ throw err; | ||
* | ||
* @param {object} parameters The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-games | ||
* @param {object} options The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-games | ||
* @returns {Promise<Object[]>} The data object in the API response. The response is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-games | ||
*/ | ||
TwitchApi.prototype.getGames = async function(parameters) { | ||
TwitchApi.prototype.getGames = async function(options) { | ||
try { | ||
return await performGetRequest( | ||
return await _performGetRequest( | ||
this, | ||
'https://api.twitch.tv/helix/games', | ||
parameters | ||
options | ||
); | ||
@@ -80,3 +60,3 @@ } catch (err) { | ||
* | ||
* @param {object} parameters The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-streams | ||
* @param {object} options The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-streams | ||
* @returns {Promise<Object[]>} The data object in the API response. The response is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-streams | ||
@@ -86,3 +66,3 @@ */ | ||
try { | ||
return await performGetRequest( | ||
return await _performGetRequest( | ||
this, | ||
@@ -105,3 +85,3 @@ 'https://api.twitch.tv/helix/streams', | ||
try { | ||
return await performGetRequest( | ||
return await _performGetRequest( | ||
this, | ||
@@ -123,3 +103,3 @@ 'https://api.twitch.tv/helix/streams/metadata', | ||
* | ||
* @param {object} parameters The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-users | ||
* @param {object} options The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-users | ||
* @returns {Promise<Object[]>} The data object in the API response. The response is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-users | ||
@@ -129,3 +109,3 @@ */ | ||
try { | ||
return await performGetRequest( | ||
return await _performGetRequest( | ||
this, | ||
@@ -144,3 +124,3 @@ 'https://api.twitch.tv/helix/users', | ||
* | ||
* @param {object} parameters The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-users-follows | ||
* @param {object} options The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-users-follows | ||
* @returns {Promise<Object[]>} The data object in the API response. The response is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-users-follows | ||
@@ -150,3 +130,3 @@ */ | ||
try { | ||
return await performGetRequest( | ||
return await _performGetRequest( | ||
this, | ||
@@ -165,3 +145,3 @@ 'https://api.twitch.tv/helix/users/follows', | ||
* | ||
* @param {object} parameters The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-videos | ||
* @param {object} options The parameters to the api call. The parameter object is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-videos | ||
* @returns {Promise<Object[]>} The data object in the API response. The response is defined in the Twitch documentation: https://dev.twitch.tv/docs/api/reference#get-videos | ||
@@ -171,3 +151,3 @@ */ | ||
try { | ||
return await performGetRequest( | ||
return await _performGetRequest( | ||
this, | ||
@@ -191,3 +171,3 @@ 'https://api.twitch.tv/helix/videos', | ||
try { | ||
return await performPutRequest( | ||
return await _performPutRequest( | ||
this, | ||
@@ -203,3 +183,29 @@ 'https://api.twitch.tv/helix/users', | ||
/** | ||
* | ||
* Authenticate the current user and get the access token to be used in the private calls. | ||
* @return The access token. | ||
*/ | ||
TwitchApi.prototype.auth = async function() { | ||
try { | ||
var response = await request({ | ||
url: 'https://api.twitch.tv/kraken/oauth2/token', | ||
method: 'POST', | ||
form: { | ||
client_id: this.config.client_id, | ||
client_secret: this.config.client_secret, | ||
grant_type: 'client_credentials', | ||
scope: 'user:edit user:read:email' | ||
}, | ||
json: true | ||
}); | ||
this.accessToken = response.access_token; | ||
return this.accessToken; | ||
} catch (err) { | ||
throw err; | ||
} | ||
}; | ||
/** | ||
* @private | ||
* Perform the get request | ||
* @param {object} api The API object. | ||
@@ -211,3 +217,3 @@ * @param {string} url The request URL. | ||
*/ | ||
async function performGetRequest(api, url, qs, requireAuth, accessToken) { | ||
async function _performGetRequest(api, url, qs, requireAuth, accessToken) { | ||
try { | ||
@@ -218,3 +224,3 @@ let headers = { | ||
await validePeformAuth(requireAuth, api, headers, accessToken); | ||
await validePerformAuth(requireAuth, api, headers, accessToken); | ||
@@ -239,3 +245,3 @@ var response = await request({ | ||
async function performPutRequest(api, url, body) { | ||
async function _performPutRequest(api, url, body) { | ||
try { | ||
@@ -247,3 +253,3 @@ let headers = { | ||
await validePeformAuth(true, api, headers); | ||
await validePerformAuth(true, api, headers); | ||
@@ -268,7 +274,7 @@ var response = await request({ | ||
async function validePeformAuth(requireAuth, api, headers, token) { | ||
async function validePerformAuth(requireAuth, api, headers, token) { | ||
try { | ||
if (requireAuth) { | ||
if (!api.config.isAuthenticated) { | ||
await api.auth(); | ||
await api._auth(); | ||
} | ||
@@ -275,0 +281,0 @@ let accessToken = token || api.access_token; |
@@ -9,4 +9,10 @@ 'use strict'; | ||
//var textVars = ['@user']; | ||
/** | ||
* @class TwitchChatEmitter | ||
* The Twitch chat implementation, based on the already existing module tmi.js (tmijs.org), adding more features and handlers to chat interation. | ||
* | ||
* @param {object} options | ||
* @param {object} logger The logger object. | ||
*/ | ||
function TwitchChatEmitter(options, logger) { | ||
@@ -20,2 +26,5 @@ tmi.Client.call(this, options); | ||
/** | ||
* Connect to the chat. | ||
*/ | ||
TwitchChatEmitter.prototype.connect = async function () { | ||
@@ -34,2 +43,10 @@ tmi.Client.prototype.connect.call(this); | ||
/** | ||
* Handle a chat message, firing the specific events. | ||
* @private | ||
* @param {string} channel The channel in which the message was sent. | ||
* @param {object} userstate The userstate object as described in the tmi 'chat 'event. | ||
* @param {string} message The chat message. | ||
* @param {bool} self Whether is the bot user or not. | ||
*/ | ||
function _handleChatMessage(channel, userstate, message, self) { | ||
@@ -46,4 +63,12 @@ | ||
if (this.getOptions().chatCommands.basic[command]) { | ||
this.say(channel, replaceTextVars(this.getOptions().chatCommands.basic[command], '@' + userstate.username)); | ||
this.say(channel, _replaceTextVars(this.getOptions().chatCommands.basic[command], '@' + userstate.username)); | ||
} else { | ||
/** | ||
* The chat command event, triggered when the specified command is sent. This event is dynamic and the name will change according to the options passed to the toolkit. | ||
* @event TwitchChatEmitter#Chat:chat_cmd_COMMAND | ||
* @param {string} channel The channel in which the command was sent. | ||
* @param {string} username The name of the user who sent the command. | ||
* @param {string} command The triggered command. | ||
* @param {bool} self Whether the command was sent to the user bot or not. | ||
*/ | ||
this.emit('chat_cmd_' + command.toLowerCase(), channel, userstate.username, command, self); | ||
@@ -56,3 +81,3 @@ } | ||
if (this.getOptions().wordTriggers.basic[word]) { | ||
this.say(channel, replaceTextVars(this.getOptions().wordTriggers.basic[word], userstate.username)); | ||
this.say(channel, _replaceTextVars(this.getOptions().wordTriggers.basic[word], userstate.username)); | ||
} | ||
@@ -65,2 +90,10 @@ if (this.chatEmotes[word]) { | ||
} | ||
/** | ||
* The chat message parsed to html, with twitch emotes. | ||
* @event TwitchChatEmitter#Chat:chat_parsed | ||
* @param {string} channel The channel in which the command was sent. | ||
* @param {object} userstate The userstate object. | ||
* @param {string} message The parsed message. | ||
* @param {bool} self Whether the command was sent to the user bot or not. | ||
*/ | ||
this.emit('chat_parsed', channel, userstate, finalMessage, self); | ||
@@ -70,4 +103,11 @@ } | ||
/** | ||
* Handle a whisper message sent to the bot user. | ||
* @private | ||
* @param {string} from The username who sent the whisper. | ||
* @param {object} userstate The userstate object who sent the whisper. | ||
* @param {string} message The whispered message. | ||
* @param {bool} self Whether the command was sent to the user bot or not. | ||
*/ | ||
function _handleWhisperMessage(from, userstate, message, self) { | ||
if (!this.getOptions().options.ignoreSelf || (!self && userstate.username.toLowerCase() != this.getOptions().username.toLowerCase())) { | ||
@@ -80,5 +120,13 @@ message = message.trim(); | ||
if (this.getOptions().whisperCommands.basic[command]) { | ||
this.whisper(from, replaceTextVars(this.getOptions().whisperCommands.basic[command], '@' + userstate.username)); | ||
this.whisper(from, _replaceTextVars(this.getOptions().whisperCommands.basic[command], '@' + userstate.username)); | ||
} else { | ||
let commandMessage = message.substring(command.length + 2).trim(); | ||
/** | ||
* The whisper command event, triggered when the specified command is sent. This event is dynamic and the name will change according to the options passed to the toolkit. | ||
* @event TwitchChatEmitter#Chat:whisper_cmd_COMMAND | ||
* @param {string} userstate The userstate object for the user who sent the whisper. | ||
* @param {string} command The triggered command. | ||
* @param {string} commandMessage The message sent with the command. | ||
* @param {bool} self Whether the command was sent to the user bot or not. | ||
*/ | ||
this.emit('whisper_cmd_' + command.toLowerCase(), userstate, command, commandMessage, self); | ||
@@ -90,3 +138,3 @@ } | ||
function replaceTextVars(text, username) { | ||
function _replaceTextVars(text, username) { | ||
return helpers.replaceAllOccurrences(text, '@user', username); | ||
@@ -93,0 +141,0 @@ } |
'use strict'; | ||
const request = require('request-promise'); | ||
const util = require('util'); | ||
const eventemitter = require('eventemitter3'); | ||
const _ = require('./helpers'); | ||
@@ -8,3 +10,14 @@ | ||
/** | ||
* @class TwitchWebSub | ||
* The Twitch Webhooks implementation, as described in https://dev.twitch.tv/docs/api/webhooks-guide/ . | ||
* The Webhook/WebSub requires a public endpoint on the running express server/application to receive the data from the hub. Without this, its impossible to make this work. | ||
* | ||
* @param {object} config The config object. | ||
* @param {string} config.client_id The client ID of the user to be passed to the Hub (un)subscribe requests. | ||
* @param {string} config.callbackUrl The callback URL that will receive the Hub requests. These requests should be forwarded to the handleRequest method to properly handle these data. | ||
* @param {object} logger The logger object. | ||
*/ | ||
function TwitchWebSub(config, logger) { | ||
eventemitter.call(this); | ||
this.config = config; | ||
@@ -17,14 +30,28 @@ this.logger = logger; | ||
TwitchWebSub.prototype.topicUserFollowsSubscribe = async function (fromId, toId, cb) { | ||
/** | ||
* Notifies when a follows event occurs. The response mimics the Get Users Follows endpoint. (https://dev.twitch.tv/docs/api/reference/#get-users-follows) | ||
* | ||
* @param {number} fromId The ID of the user who starts following someone. | ||
* @param {number} toId The ID of the user who has a new follower. | ||
* @return {string} The subscription ID, used to identify the active topic. | ||
* @fires TwitchWebSub#WebSub:user_follows | ||
*/ | ||
TwitchWebSub.prototype.topicUserFollowsSubscribe = async function( | ||
fromId, | ||
toId | ||
) { | ||
/** | ||
* Stream User Follows Event | ||
* @event TwitchWebSub#WebSub:user_follows | ||
* @param {object} data The data object received from the Hub. | ||
* @param {string} id The subscription ID. | ||
*/ | ||
try { | ||
let topic = API_BASE_URL + '/users/follows?'; | ||
if (fromId && toId) { | ||
topic += 'from_id=' + fromId + '&to_id=' + toId; | ||
} else if (fromId) { | ||
topic += 'from_id=' + fromId; | ||
let topic = API_BASE_URL + '/users/follows?first=1'; | ||
if (fromId) { | ||
topic += '&from_id=' + fromId; | ||
} else if (toId) { | ||
topic += 'to_id=' + toId; | ||
topic += '&to_id=' + toId; | ||
} | ||
return this.subscribe(topic, cb); | ||
return this.subscribe(topic, 'user_follows'); | ||
} catch (err) { | ||
@@ -35,6 +62,21 @@ throw err; | ||
TwitchWebSub.prototype.topicStreamUpDownSubscribe = async function (streamUserId, cb) { | ||
/** | ||
* Notifies when a stream goes online or offline. The response mimics the Get Streams endpoint. (https://dev.twitch.tv/docs/api/reference/#get-streams) | ||
* | ||
* @param {number} streamUserId The ID of the user whose stream is monitored. | ||
* @return {string} The subscription ID, used to identify the active topic. | ||
* @fires TwitchWebSub#WebSub:stream_up_down | ||
*/ | ||
TwitchWebSub.prototype.topicStreamUpDownSubscribe = async function( | ||
streamUserId | ||
) { | ||
/** | ||
* Stream Up/Down Event | ||
* @event TwitchWebSub#WebSub:stream_up_down | ||
* @param {object} data The data object received from the Hub. | ||
* @param {string} id The subscription ID. | ||
*/ | ||
try { | ||
let topic = API_BASE_URL + '/streams?user_id=' + streamUserId; | ||
return this.subscribe(topic, cb); | ||
return this.subscribe(topic, 'stream_up_down'); | ||
} catch (err) { | ||
@@ -45,3 +87,10 @@ throw err; | ||
TwitchWebSub.prototype.subscribe = async function (topic, cb) { | ||
/** | ||
* Subscribe to a specific topic that will fires an event when new data is received from the hub. | ||
* The event handler will receive the data object and the subscription ID. | ||
* @param {string} topic The topic name/URL. | ||
* @param {string} eventName The event name that will be fired when new data is received. | ||
* @return {string} The subscription ID, used to identify the active topic. | ||
*/ | ||
TwitchWebSub.prototype.subscribe = async function(topic, eventName) { | ||
try { | ||
@@ -52,3 +101,3 @@ this.logger.debug('Subscribing WebSub with topic: ' + topic); | ||
topic: topic, | ||
cb: cb, | ||
eventName: eventName, | ||
subscribedAt: new Date(), | ||
@@ -70,3 +119,3 @@ secret: _.generateRandomKey() | ||
'hub.lease_seconds': 864000, | ||
'hub.secret': item.secret, | ||
'hub.secret': item.secret | ||
}, | ||
@@ -78,3 +127,2 @@ json: true | ||
return item.id; | ||
} catch (err) { | ||
@@ -85,5 +133,9 @@ throw err; | ||
//TwitchWebSub.prototype.refresh = async function (id) {}; | ||
TwitchWebSub.prototype.handleRequest = function (request, response) { | ||
/** | ||
* @private | ||
* This method will handle the request received by the express server and validate the subscriptions or properly emit the events with the received data. | ||
* @param {object} request The express request object. | ||
* @param {object} response The express response object. | ||
*/ | ||
TwitchWebSub.prototype.handleRequest = function(request, response) { | ||
try { | ||
@@ -97,10 +149,10 @@ this.logger.debug('Receiving new WebSub request'); | ||
let item = this.subscribersMap[id]; | ||
let data = (request.body) ? request.body.data : null; | ||
let data = request.body ? request.body.data : null; | ||
//TODO Validate secret | ||
response.sendStatus(200); | ||
item.cb(data); | ||
} else{ | ||
this.emit(item.eventName, data, id); | ||
} else { | ||
response.sendStatus(400); | ||
} | ||
} | ||
@@ -113,3 +165,7 @@ } catch (err) { | ||
TwitchWebSub.prototype.unsubscribe = async function (id) { | ||
/** | ||
* Unsubscribe from a topic by its ID. | ||
* @param {string} id The subscription ID. | ||
*/ | ||
TwitchWebSub.prototype.unsubscribe = async function(id) { | ||
try { | ||
@@ -122,7 +178,12 @@ this.logger.debug('Requesting WebSub unsubscription with id: ' + id); | ||
method: 'POST', | ||
headers: { | ||
'Client-ID': this.config.client_id, | ||
'Content-Type': 'application/json' | ||
}, | ||
form: { | ||
'hub.callback': this.options.callbackUrl + '?item.id=' + item.id, | ||
'hub.callback': | ||
this.config.callbackUrl + '?item.id=' + item.id, | ||
'hub.mode': 'unsubscribe', | ||
'hub.topic': item.topic, | ||
'hub.secret': item.secret, | ||
'hub.secret': item.secret | ||
}, | ||
@@ -140,3 +201,6 @@ json: true | ||
TwitchWebSub.prototype.destroy = async function () { | ||
/** | ||
* Destroy the WebSub, unsubscribing every active subscription. | ||
*/ | ||
TwitchWebSub.prototype.destroy = async function() { | ||
try { | ||
@@ -147,6 +211,9 @@ this.logger.info('Destroying TwitchWebSub...'); | ||
let item = this.subscribersMap[key]; | ||
this.logger.debug('Unsubscribing user with topic: ' + item.topic); | ||
this.logger.debug( | ||
'Unsubscribing user with topic: ' + item.topic | ||
); | ||
await this.unsubscribe(item.id); | ||
} | ||
} | ||
this.subscribersMap = {}; | ||
this.logger.info('TwitchWebSub destroyed.'); | ||
@@ -158,2 +225,3 @@ } catch (err) { | ||
module.exports = TwitchWebSub; | ||
util.inherits(TwitchWebSub, eventemitter); | ||
module.exports = TwitchWebSub; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 28 instances in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3134852
111
5371
91
6
2
80
28