simple-helix-api
Advanced tools
Comparing version 1.1.3 to 1.2.0
222
index.js
const fetch = require("node-fetch"); | ||
const { encode } = require("querystring"); | ||
const syncRequest = params => { | ||
return new Promise((resolve, reject) => { | ||
fetch(params.url, params) | ||
.then(result => { | ||
if (result.status === 200) { | ||
return result.json(); | ||
} else { | ||
return reject({ | ||
status: result.status, | ||
statusText: result.statusText | ||
}); | ||
} | ||
}) | ||
.then(resolve) | ||
.catch(reject) | ||
}); | ||
const syncRequest = async params => { | ||
const response = await fetch(params.url, params); | ||
if (response.status === 200) { | ||
return response.json(); | ||
} else { | ||
return new Error(response.statusText); | ||
} | ||
}; | ||
class Helix { | ||
constructor(params) { | ||
constructor (params) { | ||
if (!params.client_id) { | ||
@@ -28,25 +20,19 @@ return console.error({ error: "Client ID is required" }); | ||
Helix.prototype.client_id = params.client_id; | ||
Helix.prototype.headers = { | ||
this.client_id = params.client_id; | ||
this.headers = { | ||
"Client-ID": params.client_id, | ||
"Accept": "application/vnd.twitchtv.v5+json" | ||
}; | ||
Helix.prototype.disableWarns = params.disableWarns; | ||
this.disableWarns = params.disableWarns; | ||
this.redirect_uri = params.redirect_uri || ""; | ||
if (params.access_token) { | ||
Helix.prototype.access_token = params.access_token; | ||
Helix.prototype.auth = { | ||
this.access_token = params.access_token; | ||
this.auth = { | ||
OAuth: `OAuth ${params.access_token}`, | ||
Bearer: `Bearer ${params.access_token}` | ||
}; | ||
if (params.increaseRate) { | ||
Helix.prototype.increaseRate = true; | ||
Helix.prototype.headers = Object.assign(Helix.prototype.headers, { | ||
Authorization: Helix.prototype.auth.Bearer | ||
}); | ||
} else { | ||
Helix.prototype.headers = Object.assign(Helix.prototype.headers, { | ||
Authorization: Helix.prototype.auth.OAuth | ||
}); | ||
} | ||
this.headers.Authorization = this.auth.Bearer; | ||
} | ||
@@ -57,6 +43,2 @@ else { | ||
} | ||
if (params.increaseRate) { | ||
console.warn("To increase the rate you need to provide access_token"); | ||
} | ||
} | ||
@@ -77,3 +59,39 @@ }; | ||
async requestEndpoint (endpoint, query, params) { | ||
getAuthLink (client_id = this.client_id, redirect_uri = this.redirect_uri, scopes = "all") { | ||
if (client_id.length === 0 || redirect_uri.length === 0) { | ||
console.error("You must to specify client_id and redirect_uri"); | ||
return; | ||
} | ||
if (scopes === "all") { | ||
scopes = [ | ||
"analytics:read:extensions", "analytics:read:games", "bits:read", | ||
"channel:edit:commercial", "channel:manage:broadcast", "channel:manage:extensions", | ||
"channel:manage:redemptions", "channel:read:hype_train", "channel:read:redemptions", | ||
"channel:read:stream_key", "channel:read:subscriptions", "clips:edit", | ||
"moderation:read", "user:edit", "user:edit:follows", "user:read:broadcast", | ||
"user:read:email" | ||
]; | ||
} else { | ||
if (!Array.isArray(scopes)) { | ||
this.handleError("Scopes list must be an array or 'all' value"); | ||
return; | ||
} | ||
} | ||
const params = { | ||
client_id, | ||
redirect_uri, | ||
response_type: "token" | ||
}; | ||
if (scopes.length > 0) { | ||
params.scope = scopes.join(" "); | ||
} | ||
const query = encode(params); | ||
return `https://id.twitch.tv/oauth2/authorize?${query}`; | ||
} | ||
async requestEndpoint (endpoint, query = "", params = {}) { | ||
query = typeof query === "object" | ||
@@ -83,3 +101,3 @@ ? encode(query) | ||
return await syncRequest({ | ||
const response = await syncRequest({ | ||
url: `https://api.twitch.tv/helix/${endpoint}?${query}`, | ||
@@ -89,2 +107,4 @@ headers: this.headers, | ||
}).catch(this.handleError); | ||
return response; | ||
} | ||
@@ -105,3 +125,4 @@ | ||
const url = `https://api.twitch.tv/kraken/channels/${user_id}`; | ||
return await syncRequest({ url, headers: this.headers }).catch(this.handleError);; | ||
const response = await syncRequest({ url, headers: this.headers }).catch(this.handleError); | ||
return response; | ||
} | ||
@@ -117,3 +138,3 @@ | ||
const response = await this.requestEndpoint("streams", query).catch(this.handleError); | ||
return response.data[0] || { error: "You must start stream to get stream data or wait for Twitch to announce you online" }; | ||
return response.data[0] || this.handleError("You must start stream to get stream data or wait for Twitch to announce you online"); | ||
} | ||
@@ -136,3 +157,3 @@ | ||
const response = await this.requestEndpoint("streams/metadata", query).catch(this.handleError); | ||
return response.data[0] || { error: "You must start stream to get stream data or wait for Twitch to announce you online" }; | ||
return response.data[0] || this.handleError("You must start stream to get stream data or wait for Twitch to announce you online"); | ||
} | ||
@@ -162,29 +183,22 @@ | ||
return await this.requestEndpoint("users/follows", query); | ||
const response = await this.requestEndpoint("users/follows", query); | ||
return response; | ||
} | ||
getAllFollowers (user_id) { | ||
return new Promise(async (resolve, reject) => { | ||
const count = await this.getFollowersCount(user_id); | ||
let list = []; | ||
let cursor = ""; | ||
async getAllFollowers (user_id) { | ||
const count = await this.getFollowersCount(user_id); | ||
let list = []; | ||
let cursor = ""; | ||
while (list.length < count) { | ||
const response = await this.getFollowers(user_id, 100, cursor).catch(this.handleError); | ||
cursor = response.pagination.cursor; | ||
const get = async () => { | ||
const response = await this.getFollowers(user_id, 100, cursor).catch(reject); | ||
cursor = response.pagination.cursor; | ||
list = [ | ||
...list, | ||
...response.data | ||
]; | ||
if (list.length < count) { | ||
return get(); | ||
} | ||
else { | ||
return resolve(list); | ||
} | ||
}; | ||
list = [ | ||
...list, | ||
...response.data | ||
]; | ||
} | ||
return get(); | ||
}); | ||
return list; | ||
} | ||
@@ -201,5 +215,5 @@ | ||
user = user.toLowerCase(); | ||
return await syncRequest({ | ||
url: `https://tmi.twitch.tv/group/user/${user}/chatters` | ||
}).catch(this.handleError); | ||
const url = `https://tmi.twitch.tv/group/user/${user}/chatters`; | ||
const response = await syncRequest({ url }).catch(this.handleError); | ||
return response; | ||
} | ||
@@ -266,8 +280,5 @@ | ||
async getStreamKey (user_id) { | ||
const query = encode({ | ||
broadcaster_id: user_id | ||
}); | ||
const query = encode({ broadcaster_id: user_id }); | ||
const { data } = await this.requestEndpoint("streams/key", query).catch(this.handleError); | ||
return data.stream_key; | ||
return data[0].stream_key; | ||
} | ||
@@ -304,5 +315,3 @@ | ||
const { data } = await this.requestEndpoint("clips", query, { method: "POST" }).catch(this.handleError); | ||
const [clip] = data; | ||
return clip; | ||
return data[0]; | ||
} | ||
@@ -324,27 +333,25 @@ | ||
getAllClips (user_id) { | ||
return new Promise(async resolve => { | ||
let cursor = ""; | ||
async getAllClips (user_id) { | ||
let cursor = ""; | ||
const get = async () => { | ||
const { data, pagination } = await this.getClips(user_id, { | ||
first: 100, | ||
after: cursor | ||
}).catch(this.handleError); | ||
cursor = pagination.cursor; | ||
return data; | ||
}; | ||
const get = async () => { | ||
const { data, pagination } = await this.getClips(user_id, { | ||
first: 100, | ||
after: cursor | ||
}).catch(this.handleError); | ||
cursor = pagination.cursor; | ||
return data; | ||
}; | ||
let clips = await get(); | ||
let clips = await get(); | ||
while (cursor) { | ||
clips = [ | ||
...clips, | ||
...await get().catch(this.handleError) | ||
]; | ||
} | ||
while (cursor) { | ||
clips = [ | ||
...clips, | ||
...await get().catch(this.handleError) | ||
]; | ||
} | ||
return resolve(clips); | ||
}); | ||
return clips; | ||
} | ||
@@ -357,4 +364,3 @@ | ||
const response = await syncRequest({ | ||
url: "https://api.twitch.tv/helix/streams/markers", | ||
const response = await this.requestEndpoint("streams/markers", null, { | ||
method: "PUT", | ||
@@ -366,4 +372,4 @@ body: JSON.stringify({ | ||
headers: this.oauth() | ||
}).catch(this.handleError); | ||
}); | ||
if (response.error) { | ||
@@ -387,4 +393,3 @@ return { | ||
return await syncRequest({ | ||
url: "https://api.twitch.tv/helix/streams/markers", | ||
const response = await this.requestEndpoint("streams/markers", null, { | ||
method: "GET", | ||
@@ -397,7 +402,8 @@ body: JSON.stringify({ | ||
}).catch(this.handleError); | ||
return response; | ||
} | ||
async getTopGames (count = 100) { | ||
const url = `https://api.twitch.tv/helix/games/top?first=${count}`; | ||
const { data } = await syncRequest({ url, headers: this.headers }).catch(this.handleError); | ||
const { data } = await this.requestEndpoint("games/top", { first: count }).catch(this.handleError); | ||
return data; | ||
@@ -420,4 +426,3 @@ } | ||
return await syncRequest({ | ||
url: "https://api.twitch.tv/helix/channels/commercial", | ||
const response = await this.requestEndpoint("channels/commercial", null, { | ||
method: "POST", | ||
@@ -429,3 +434,5 @@ body: JSON.stringify({ | ||
headers: this.headers | ||
}).catch(this.handleError); | ||
}); | ||
return response; | ||
} | ||
@@ -440,2 +447,3 @@ | ||
}); | ||
client.connect(); | ||
@@ -442,0 +450,0 @@ return client; |
{ | ||
"name": "simple-helix-api", | ||
"version": "1.1.3", | ||
"version": "1.2.0", | ||
"description": "The Simple Helix API allows developers to easily develop applications for Twitch", | ||
@@ -9,4 +9,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"node-fetch": "^2.6.0", | ||
"tmi.js": "^1.5.0" | ||
"node-fetch": "^2.6.1", | ||
"tmi.js": "^1.7.1" | ||
}, | ||
@@ -23,3 +23,6 @@ "repository": { | ||
"Streams" | ||
] | ||
], | ||
"devDependencies": { | ||
"jest": "^26.6.3" | ||
} | ||
} |
@@ -15,9 +15,25 @@ # About | ||
**Get link to fetching access token if you haven't** | ||
```javascript | ||
const params = { | ||
client_id: "xxx", | ||
redirect_uri: "xxx" | ||
}; | ||
const scopes = "all"; // You can use an array of scopes | ||
const HelixAPI = require("simple-helix-api"); | ||
const Helix = new HelixAPI(params); | ||
const link = Helix.getAuthLink(params.client_id, params.redirect_uri, scopes); | ||
console.log(link); | ||
``` | ||
**Creating Helix object** | ||
```javascript | ||
const HelixAPI = require("simple-helix-api"); // also you can user es6 import | ||
const HelixAPI = require("simple-helix-api"); | ||
const Helix = new HelixAPI({ | ||
access_token: "xxx", | ||
cliend_id: "xxx" | ||
client_id: "xxx" | ||
}); | ||
@@ -32,3 +48,2 @@ ``` | ||
| client_id | true | null | Client ID of application | | ||
| increaseRate | false | false | Use Bearer instead of OAuth to increase Rate Limit | | ||
| disableWarns | false | false | Disabled warnings in console | | ||
@@ -42,8 +57,2 @@ | ||
## Increase Rate | ||
This option uses Bearer authorization instead of OAuth, which allows you to increase the number of requests per minute to 800 instead of 30. | ||
If you want to use this, you need to know that methods like ```updateStream(), createMarker()``` force OAuth authorization. | ||
## Common methods | ||
@@ -71,3 +80,3 @@ | ||
### Get Clips | ||
Gets clip information by clip ID (one or more), broadcaster ID (one only), or game ID (one only) | ||
Get clip information by clip ID (one or more), broadcaster ID (one only), or game ID (one only) | ||
@@ -79,3 +88,3 @@ ```javascript | ||
### Get All Clips | ||
Gets all clips of channel | ||
Get all clips of channel | ||
@@ -96,3 +105,3 @@ ```javascript | ||
Gets information about active streams. Streams are returned sorted by number of current viewers, in descending order. Across multiple pages of results, there may be duplicate or missing streams, as viewers join and leave streams. | ||
Get information about active streams. Streams are returned sorted by number of current viewers, in descending order. Across multiple pages of results, there may be duplicate or missing streams, as viewers join and leave streams. | ||
@@ -204,3 +213,3 @@ ```javascript | ||
Gets the channel stream key for a user | ||
Get the channel stream key for a user | ||
@@ -213,3 +222,3 @@ ```javascript | ||
Gets a ranked list of Bits leaderboard information for an authorized broadcaster | ||
Get a ranked list of Bits leaderboard information for an authorized broadcaster | ||
@@ -216,0 +225,0 @@ ```javascript |
23489
325
1
352
Updatednode-fetch@^2.6.1
Updatedtmi.js@^1.7.1