Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

twitch-toolkit

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

twitch-toolkit - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

.esdoc.json

0

.eslintrc.js

@@ -0,0 +0,0 @@ module.exports = {

@@ -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 {

9

package.json
{
"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;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc