streamer-emotes 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,8 @@
1
1
  # streamer-emotes
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+
2
6
  A library to get Twitch, BTTV, FFZ and 7TV emotes for a given Twitch channel.
3
7
 
4
8
  ## Usage
@@ -15,3 +19,47 @@ const emotes = await getStreamerEmotes("rubius", {
15
19
 
16
20
  console.info(emotes);
17
21
  ```
22
+
23
+ ## Output example
24
+ ```jsonc
25
+ {
26
+ "<provider>": { // Provider prop
27
+ "channel": [ // Channel Emotes
28
+ {
29
+ "animated": true,
30
+ "id": "string",
31
+ "images": [
32
+ {
33
+ "url": "string",
34
+ "version": "string"
35
+ }
36
+ ],
37
+ "name": "string",
38
+ "provider": "string",
39
+ "zeroWidth": true // 7TV zero width emotes only
40
+ }
41
+ ],
42
+ "global": [ // Global Emotes
43
+ {
44
+ "animated": false,
45
+ "id": "string",
46
+ "images": [
47
+ {
48
+ "url": "string",
49
+ "version": "string"
50
+ }
51
+ ],
52
+ "name": "string",
53
+ "provider": "string",
54
+ }
55
+ ]
56
+ }
57
+ }
58
+ ```
59
+
60
+ <!-- Badges -->
61
+ [npm-version-src]: https://img.shields.io/npm/v/streamer-emotes.svg?style=flat
62
+ [npm-version-href]: https://npmjs.com/package/streamer-emotes
63
+
64
+ [npm-downloads-src]: https://img.shields.io/npm/dm/streamer-emotes.svg?style=flat
65
+ [npm-downloads-href]: https://npmjs.com/package/streamer-emotes
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/types/index.d.ts
2
- interface StreamerEmotesProps {
2
+ interface StreamerEmotesProps<T> {
3
3
  animated: boolean;
4
4
  id: string;
5
5
  images: {
@@ -7,18 +7,62 @@ interface StreamerEmotesProps {
7
7
  version: string;
8
8
  }[];
9
9
  name: string;
10
- provider: "7tv" | "bttv" | "ffz" | "twitch";
10
+ provider: T;
11
11
  zeroWidth?: boolean;
12
12
  }
13
- interface StreamerEmotesProviderResponse {
14
- channel: StreamerEmotesProps[];
15
- global?: StreamerEmotesProps[];
13
+ interface StreamerEmotesProviderResponse<T> {
14
+ channel: StreamerEmotesProps<T>[];
15
+ global?: StreamerEmotesProps<T>[];
16
16
  }
17
17
  //#endregion
18
- //#region src/index.d.ts
18
+ //#region src/providers/7tv.d.ts
19
+ /**
20
+ *
21
+ * @param twitchLogin Twitch channel login.
22
+ * @param {boolean} options.globals Include global Twitch emotes in the response. Defaults to `true`.
23
+ * @returns
24
+ */
25
+ declare const get7tvEmotes: (channelLogin: string, options?: {
26
+ globals?: boolean;
27
+ }) => Promise<StreamerEmotesProviderResponse<"7tv">>;
28
+ //#endregion
29
+ //#region src/providers/bttv.d.ts
30
+ /**
31
+ *
32
+ * @param twitchLogin Twitch channel login.
33
+ * @param {boolean} options.globals Include global Twitch emotes in the response. Defaults to `true`.
34
+ * @returns
35
+ */
36
+ declare const getBttvEmotes: (channelLogin: string, options?: {
37
+ globals?: boolean;
38
+ }) => Promise<StreamerEmotesProviderResponse<"bttv">>;
39
+ //#endregion
40
+ //#region src/providers/ffz.d.ts
19
41
  /**
20
42
  *
21
- * @param channelLogin
43
+ * @param twitchLogin Twitch channel login.
44
+ * @param {boolean} options.globals Include global Twitch emotes in the response. Defaults to `true`.
45
+ * @returns
46
+ */
47
+ declare const getFfzEmotes: (channelLogin: string, options?: {
48
+ globals?: boolean;
49
+ }) => Promise<StreamerEmotesProviderResponse<"ffz">>;
50
+ //#endregion
51
+ //#region src/providers/twitch.d.ts
52
+ /**
53
+ *
54
+ * @param twitchLogin Twitch channel login.
55
+ * @param {boolean} options.globals Include global Twitch emotes in the response. Defaults to `true`.
56
+ * @returns
57
+ */
58
+ declare const getTwitchEmotes: (channelLogin: string, options?: {
59
+ globals?: boolean;
60
+ }) => Promise<StreamerEmotesProviderResponse<"twitch">>;
61
+ //#endregion
62
+ //#region src/index.d.ts
63
+ /**
64
+ * Get Twitch channel emotes from multiple providers.
65
+ * @param channelLogin Twitch channel login.
22
66
  * @param options.bttv Get emotes from BetterTTV if `true`. Defaults to `false`.
23
67
  * @param options.ffz Get emotes from FrankerFaceZ if `true`. Defaults to `false`.
24
68
  * @param options.sevenTV Get emotes from 7TV if `true`. Defaults to `false`.
@@ -32,13 +76,13 @@ declare const getStreamerEmotes: (channelLogin: string, options: {
32
76
  sevenTV?: boolean | StreamerEmotesProviderOptions;
33
77
  twitch?: boolean | StreamerEmotesProviderOptions;
34
78
  }) => Promise<{
35
- bttv?: StreamerEmotesProviderResponse;
36
- ffz?: StreamerEmotesProviderResponse;
37
- sevenTV?: StreamerEmotesProviderResponse;
38
- twitch?: StreamerEmotesProviderResponse;
79
+ bttv?: StreamerEmotesProviderResponse<"bttv">;
80
+ ffz?: StreamerEmotesProviderResponse<"ffz">;
81
+ sevenTV?: StreamerEmotesProviderResponse<"7tv">;
82
+ twitch?: StreamerEmotesProviderResponse<"twitch">;
39
83
  }>;
40
84
  interface StreamerEmotesProviderOptions {
41
85
  globals: boolean;
42
86
  }
43
87
  //#endregion
44
- export { getStreamerEmotes };
88
+ export { get7tvEmotes, getBttvEmotes, getFfzEmotes, getStreamerEmotes, getTwitchEmotes };
package/dist/index.mjs CHANGED
@@ -7,24 +7,27 @@ const providersURL = {
7
7
  ffz: "https://api.frankerfacez.com/v1",
8
8
  twitch: "https://gql.twitch.tv/gql"
9
9
  };
10
- let twitchIdMemory = {};
11
- const getTwitchIdByLogin = async (login) => {
12
- login = login.toLowerCase();
13
- if (twitchIdMemory[login]) return twitchIdMemory[login];
14
- const { data } = await $fetch(providersURL.twitch, {
10
+ const callTwitchGQL = async (...args) => {
11
+ return $fetch(providersURL.twitch, {
15
12
  method: "POST",
16
13
  headers: {
17
14
  "Client-ID": "kimne78kx3ncx6brgo4mv6wki5h1ko",
18
15
  "Content-Type": "application/json"
19
16
  },
20
- body: gqlQuery({
21
- operation: "user",
22
- variables: { login: {
23
- value: login,
24
- type: "String!"
25
- } },
26
- fields: ["id"]
27
- })
17
+ body: gqlQuery(...args)
18
+ });
19
+ };
20
+ let twitchIdMemory = {};
21
+ const getTwitchIdByLogin = async (login) => {
22
+ login = login.toLowerCase();
23
+ if (twitchIdMemory[login]) return twitchIdMemory[login];
24
+ const { data } = await callTwitchGQL({
25
+ operation: "user",
26
+ variables: { login: {
27
+ value: login,
28
+ type: "String!"
29
+ } },
30
+ fields: ["id"]
28
31
  });
29
32
  const channelId = data?.user?.id;
30
33
  if (!channelId) throw new Error(`Twitch channel with login '${login}' not found.`);
@@ -45,15 +48,9 @@ const get7tvEmotes = async (channelLogin, options) => {
45
48
  const channelId = await getTwitchIdByLogin(channelLogin);
46
49
  const channel = [];
47
50
  const global = [];
48
- const channelDataPromise = $fetch(`/users/twitch/${channelId}`, {
49
- baseURL: providersURL.sevenTV,
50
- method: "GET"
51
- }).catch(() => null);
51
+ const channelDataPromise = $fetch(`/users/twitch/${channelId}`, { baseURL: providersURL.sevenTV }).catch(() => null);
52
52
  let globalDataPromise;
53
- if (globals) globalDataPromise = $fetch("/emote-sets/global", {
54
- baseURL: providersURL.sevenTV,
55
- method: "GET"
56
- });
53
+ if (globals) globalDataPromise = $fetch("/emote-sets/global", { baseURL: providersURL.sevenTV });
57
54
  const [channelData, globalData] = await Promise.all([channelDataPromise, globalDataPromise]);
58
55
  if (channelData) channel.push(...channelData.emote_set.emotes);
59
56
  if (globalData) global.push(...globalData.emotes);
@@ -93,34 +90,29 @@ const getBttvEmotes = async (channelLogin, options) => {
93
90
  const channelId = await getTwitchIdByLogin(channelLogin);
94
91
  const channel = [];
95
92
  const global = [];
96
- const channelDataPromise = $fetch(`/cached/users/twitch/${channelId}`, {
97
- baseURL: providersURL.bttv,
98
- method: "GET"
99
- }).catch(() => null);
93
+ const channelDataPromise = $fetch(`/cached/users/twitch/${channelId}`, { baseURL: providersURL.bttv }).catch(() => null);
100
94
  let globalDataPromise;
101
- if (globals) globalDataPromise = $fetch("/cached/emotes/global", {
102
- baseURL: providersURL.bttv,
103
- method: "GET"
104
- });
95
+ if (globals) globalDataPromise = $fetch("/cached/emotes/global", { baseURL: providersURL.bttv });
105
96
  const [channelData, globalData] = await Promise.all([channelDataPromise, globalDataPromise]);
106
97
  if (channelData) channel.push(...channelData.channelEmotes, ...channelData.sharedEmotes);
107
98
  if (globalData) global.push(...globalData);
108
99
  const normalizeData = (data) => {
109
100
  if (!data?.length) return [];
101
+ const getBTTVEmoticonsURL = (id, version) => `https://cdn.betterttv.net/emote/${id}/${version}`;
110
102
  return data.map((emote) => ({
111
103
  animated: emote.animated,
112
104
  id: emote.id,
113
105
  images: [
114
106
  {
115
- url: `https://cdn.betterttv.net/emote/${emote.id}/1x`,
107
+ url: getBTTVEmoticonsURL(emote.id, "1x"),
116
108
  version: "1x"
117
109
  },
118
110
  {
119
- url: `https://cdn.betterttv.net/emote/${emote.id}/2x`,
111
+ url: getBTTVEmoticonsURL(emote.id, "2x"),
120
112
  version: "2x"
121
113
  },
122
114
  {
123
- url: `https://cdn.betterttv.net/emote/${emote.id}/3x`,
115
+ url: getBTTVEmoticonsURL(emote.id, "3x"),
124
116
  version: "3x"
125
117
  }
126
118
  ],
@@ -147,15 +139,9 @@ const getFfzEmotes = async (channelLogin, options) => {
147
139
  const channelId = await getTwitchIdByLogin(channelLogin);
148
140
  const channel = [];
149
141
  const global = [];
150
- const channelDataPromise = $fetch(`/room/id/${channelId}`, {
151
- baseURL: providersURL.ffz,
152
- method: "GET"
153
- }).catch(() => null);
142
+ const channelDataPromise = $fetch(`/room/id/${channelId}`, { baseURL: providersURL.ffz }).catch(() => null);
154
143
  let globalDataPromise;
155
- if (globals) globalDataPromise = $fetch("/set/global", {
156
- baseURL: providersURL.ffz,
157
- method: "GET"
158
- });
144
+ if (globals) globalDataPromise = $fetch("/set/global", { baseURL: providersURL.ffz });
159
145
  const [channelData, globalData] = await Promise.all([channelDataPromise, globalDataPromise]);
160
146
  if (channelData) channel.push(...channelData.sets[channelData.room.set].emoticons);
161
147
  if (globalData) global.push(...globalData.default_sets.flatMap((setId) => globalData.sets[setId].emoticons));
@@ -226,30 +212,24 @@ const getTwitchEmotes = async (channelLogin, options) => {
226
212
  if (globals) toQuery.push(globalQuery);
227
213
  toQuery.push(channelQuery);
228
214
  toQuery.push(localEmotesQuery);
229
- const { data } = await $fetch(providersURL.twitch, {
230
- method: "POST",
231
- headers: {
232
- "Client-ID": "kimne78kx3ncx6brgo4mv6wki5h1ko",
233
- "Content-Type": "application/json"
234
- },
235
- body: gqlQuery(toQuery)
236
- });
215
+ const { data } = await callTwitchGQL(toQuery);
237
216
  const normalizeData = (data) => {
238
217
  if (!data?.length) return [];
218
+ const getTwitchEmoticonsURL = (id, version) => `https://static-cdn.jtvnw.net/emoticons/v2/${id}/default/dark/${version}`;
239
219
  return data.map((emote) => ({
240
220
  animated: emote.assetType === "ANIMATED",
241
221
  id: emote.id,
242
222
  images: [
243
223
  {
244
- url: `https://static-cdn.jtvnw.net/emoticons/v2/${emote.id}/default/dark/1.0`,
224
+ url: getTwitchEmoticonsURL(emote.id, "1.0"),
245
225
  version: "1.0"
246
226
  },
247
227
  {
248
- url: `https://static-cdn.jtvnw.net/emoticons/v2/${emote.id}/default/dark/2.0`,
228
+ url: getTwitchEmoticonsURL(emote.id, "2.0"),
249
229
  version: "2.0"
250
230
  },
251
231
  {
252
- url: `https://static-cdn.jtvnw.net/emoticons/v2/${emote.id}/default/dark/3.0`,
232
+ url: getTwitchEmoticonsURL(emote.id, "3.0"),
253
233
  version: "3.0"
254
234
  }
255
235
  ],
@@ -265,8 +245,8 @@ const getTwitchEmotes = async (channelLogin, options) => {
265
245
  //#endregion
266
246
  //#region src/index.ts
267
247
  /**
268
- *
269
- * @param channelLogin
248
+ * Get Twitch channel emotes from multiple providers.
249
+ * @param channelLogin Twitch channel login.
270
250
  * @param options.bttv Get emotes from BetterTTV if `true`. Defaults to `false`.
271
251
  * @param options.ffz Get emotes from FrankerFaceZ if `true`. Defaults to `false`.
272
252
  * @param options.sevenTV Get emotes from 7TV if `true`. Defaults to `false`.
@@ -275,15 +255,15 @@ const getTwitchEmotes = async (channelLogin, options) => {
275
255
  * @returns
276
256
  */
277
257
  const getStreamerEmotes = async (channelLogin, options) => {
278
- if (!Object.keys(options).length) throw new Error("At least one provider must be enabled");
258
+ if (!Object.keys(options).length || !Object.values(options).some((value) => value)) throw new Error("At least one provider must be enabled.");
279
259
  const { bttv, ffz, sevenTV, twitch } = options;
280
260
  const data = {};
281
261
  let bttvPromise, ffzPromise, sevenTvPromise, twitchPromise;
282
- if (bttv || ffz || sevenTV || twitch) await getTwitchIdByLogin(channelLogin);
283
262
  if (bttv) bttvPromise = getBttvEmotes(channelLogin, { globals: typeof bttv === "boolean" ? true : bttv?.globals ?? true }).catch(() => null);
284
263
  if (ffz) ffzPromise = getFfzEmotes(channelLogin, { globals: typeof ffz === "boolean" ? true : ffz?.globals ?? true }).catch(() => null);
285
264
  if (sevenTV) sevenTvPromise = get7tvEmotes(channelLogin, { globals: typeof sevenTV === "boolean" ? true : sevenTV?.globals ?? true }).catch(() => null);
286
265
  if (twitch) twitchPromise = getTwitchEmotes(channelLogin, { globals: typeof twitch === "boolean" ? true : twitch?.globals ?? true }).catch(() => null);
266
+ await getTwitchIdByLogin(channelLogin);
287
267
  const [bttvEmotes, ffzEmotes, sevenTvEmotes, twitchEmotes] = await Promise.all([
288
268
  bttvPromise,
289
269
  ffzPromise,
@@ -297,4 +277,4 @@ const getStreamerEmotes = async (channelLogin, options) => {
297
277
  return data;
298
278
  };
299
279
  //#endregion
300
- export { getStreamerEmotes };
280
+ export { get7tvEmotes, getBttvEmotes, getFfzEmotes, getStreamerEmotes, getTwitchEmotes };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "streamer-emotes",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.1.2",
5
5
  "description": "A library to get Twitch, BTTV, FFZ and 7TV emotes for a given Twitch channel.",
6
6
  "keywords": [
7
7
  "streamer",