glitch-javascript-sdk 1.8.0 → 1.8.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.
@@ -0,0 +1,308 @@
1
+ import WebsiteAnalyticsRoute from "../routes/WebsiteAnalyticsRoute";
2
+ import Requests from "../util/Requests";
3
+ import Response from "../util/Response";
4
+ import { AxiosPromise } from "axios";
5
+
6
+ class WebsiteAnalytics {
7
+ /**
8
+ * List website analytics sessions with comprehensive filtering
9
+ *
10
+ * @param params Filtering options:
11
+ * - title_id?: string - Filter by title ID
12
+ * - start_date?: string - Start date (YYYY-MM-DD)
13
+ * - end_date?: string - End date (YYYY-MM-DD)
14
+ * - device_type?: 'desktop'|'mobile'|'tablet'|'bot'|'other'
15
+ * - country_code?: string - 2-letter country code
16
+ * - is_bot?: boolean - Filter by bot status
17
+ * - sort?: 'started_at'|'total_duration'|'pageview_count' - Sort field
18
+ * - order?: 'asc'|'desc' - Sort order
19
+ * - per_page?: number - Items per page (max 100)
20
+ * @returns Promise with paginated sessions data
21
+ */
22
+ public static listSessions<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
23
+ return Requests.processRoute(
24
+ WebsiteAnalyticsRoute.routes.listSessions,
25
+ {},
26
+ undefined,
27
+ params
28
+ );
29
+ }
30
+
31
+ /**
32
+ * Get a paginated list of pageviews with filtering options
33
+ *
34
+ * @param params Filtering options:
35
+ * - title_id?: string - Filter by title ID
36
+ * - analytics_session_id?: string - Filter by session ID
37
+ * - start_date?: string - Start date (YYYY-MM-DD)
38
+ * - end_date?: string - End date (YYYY-MM-DD)
39
+ * - is_exit?: boolean - Filter by exit pageviews
40
+ * - sort?: 'occurred_at'|'load_time_ms'|'dom_complete_ms' - Sort field
41
+ * - order?: 'asc'|'desc' - Sort order
42
+ * - per_page?: number - Items per page (max 100)
43
+ * @returns Promise with paginated pageviews data
44
+ */
45
+ public static listPageviews<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
46
+ return Requests.processRoute(
47
+ WebsiteAnalyticsRoute.routes.listPageviews,
48
+ {},
49
+ undefined,
50
+ params
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Get a paginated list of events with filtering options
56
+ *
57
+ * @param params Filtering options:
58
+ * - title_id?: string - Filter by title ID
59
+ * - analytics_session_id?: string - Filter by session ID
60
+ * - event_name?: string - Filter by event name
61
+ * - event_category?: string - Filter by event category
62
+ * - start_date?: string - Start date (YYYY-MM-DD)
63
+ * - end_date?: string - End date (YYYY-MM-DD)
64
+ * - sort?: 'occurred_at'|'event_name' - Sort field
65
+ * - order?: 'asc'|'desc' - Sort order
66
+ * - per_page?: number - Items per page (max 100)
67
+ * @returns Promise with paginated events data
68
+ */
69
+ public static listEvents<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
70
+ return Requests.processRoute(
71
+ WebsiteAnalyticsRoute.routes.listEvents,
72
+ {},
73
+ undefined,
74
+ params
75
+ );
76
+ }
77
+
78
+ /**
79
+ * Get an analytics overview with summarized metrics
80
+ *
81
+ * @param params Overview options:
82
+ * - title_id: string - Required title ID
83
+ * - start_date?: string - Start date (YYYY-MM-DD)
84
+ * - end_date?: string - End date (YYYY-MM-DD)
85
+ * - group_by?: 'day'|'week'|'month'|'year' - Grouping period
86
+ * - include_breakdowns?: boolean - Include detailed breakdowns
87
+ * @returns Promise with overview data
88
+ */
89
+ public static overview<T>(params: Record<string, any>): AxiosPromise<Response<T>> {
90
+ return Requests.processRoute(
91
+ WebsiteAnalyticsRoute.routes.overview,
92
+ {},
93
+ undefined,
94
+ params
95
+ );
96
+ }
97
+
98
+ /**
99
+ * Single ingestion endpoint for sessions, pageviews and events
100
+ *
101
+ * @param data Analytics data payload with type property:
102
+ * - type: 'session'|'pageview'|'event' - Type of analytics data
103
+ * - title_id: string - Title ID
104
+ * - tracking_token: string - HMAC token for verification
105
+ * - plus type-specific fields
106
+ * @returns Promise with acceptance response
107
+ */
108
+ public static collect<T>(data: object): AxiosPromise<Response<T>> {
109
+ return Requests.processRoute(
110
+ WebsiteAnalyticsRoute.routes.collect,
111
+ data
112
+ );
113
+ }
114
+
115
+ /**
116
+ * Get average session length data with optional grouping
117
+ *
118
+ * @param params Filtering options:
119
+ * - title_id?: string - Filter by title ID
120
+ * - start_date?: string - Start date (YYYY-MM-DD)
121
+ * - end_date?: string - End date (YYYY-MM-DD)
122
+ * - group_by?: 'day'|'week'|'month' - Grouping period
123
+ * - device_type?: string - Filter by device type
124
+ * - country_code?: string - Filter by country
125
+ * @returns Promise with average session data
126
+ */
127
+ public static sessionsAverage<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
128
+ return Requests.processRoute(
129
+ WebsiteAnalyticsRoute.routes.sessionsAverage,
130
+ {},
131
+ undefined,
132
+ params
133
+ );
134
+ }
135
+
136
+ /**
137
+ * Get session duration histogram data
138
+ *
139
+ * @param params Filtering options:
140
+ * - title_id?: string - Filter by title ID
141
+ * - start_date?: string - Start date (YYYY-MM-DD)
142
+ * - end_date?: string - End date (YYYY-MM-DD)
143
+ * - bucket_size?: number - Duration bucket size in seconds
144
+ * @returns Promise with histogram data
145
+ */
146
+ public static sessionsHistogram<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
147
+ return Requests.processRoute(
148
+ WebsiteAnalyticsRoute.routes.sessionsHistogram,
149
+ {},
150
+ undefined,
151
+ params
152
+ );
153
+ }
154
+
155
+ /**
156
+ * Get pageviews over time with optional grouping
157
+ *
158
+ * @param params Filtering options:
159
+ * - title_id?: string - Filter by title ID
160
+ * - start_date?: string - Start date (YYYY-MM-DD)
161
+ * - end_date?: string - End date (YYYY-MM-DD)
162
+ * - group_by?: 'hour'|'day'|'week'|'month' - Grouping period
163
+ * - path?: string - Filter by specific path
164
+ * @returns Promise with pageviews over time data
165
+ */
166
+ public static pageviewsOverTime<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
167
+ return Requests.processRoute(
168
+ WebsiteAnalyticsRoute.routes.pageviewsOverTime,
169
+ {},
170
+ undefined,
171
+ params
172
+ );
173
+ }
174
+
175
+ /**
176
+ * Get top pages by views
177
+ *
178
+ * @param params Filtering options:
179
+ * - title_id?: string - Filter by title ID
180
+ * - start_date?: string - Start date (YYYY-MM-DD)
181
+ * - end_date?: string - End date (YYYY-MM-DD)
182
+ * - limit?: number - Number of top pages to return
183
+ * @returns Promise with top pages data
184
+ */
185
+ public static topPages<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
186
+ return Requests.processRoute(
187
+ WebsiteAnalyticsRoute.routes.topPages,
188
+ {},
189
+ undefined,
190
+ params
191
+ );
192
+ }
193
+
194
+ /**
195
+ * Get summary of events
196
+ *
197
+ * @param params Filtering options:
198
+ * - title_id?: string - Filter by title ID
199
+ * - start_date?: string - Start date (YYYY-MM-DD)
200
+ * - end_date?: string - End date (YYYY-MM-DD)
201
+ * - event_category?: string - Filter by event category
202
+ * @returns Promise with events summary data
203
+ */
204
+ public static eventsSummary<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
205
+ return Requests.processRoute(
206
+ WebsiteAnalyticsRoute.routes.eventsSummary,
207
+ {},
208
+ undefined,
209
+ params
210
+ );
211
+ }
212
+
213
+ /**
214
+ * Get most popular events
215
+ *
216
+ * @param params Filtering options:
217
+ * - title_id?: string - Filter by title ID
218
+ * - start_date?: string - Start date (YYYY-MM-DD)
219
+ * - end_date?: string - End date (YYYY-MM-DD)
220
+ * - limit?: number - Number of events to return
221
+ * @returns Promise with popular events data
222
+ */
223
+ public static popularEvents<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
224
+ return Requests.processRoute(
225
+ WebsiteAnalyticsRoute.routes.popularEvents,
226
+ {},
227
+ undefined,
228
+ params
229
+ );
230
+ }
231
+
232
+ /**
233
+ * Get geographic distribution of visitors
234
+ *
235
+ * @param params Filtering options:
236
+ * - title_id?: string - Filter by title ID
237
+ * - start_date?: string - Start date (YYYY-MM-DD)
238
+ * - end_date?: string - End date (YYYY-MM-DD)
239
+ * - limit?: number - Number of countries to return
240
+ * @returns Promise with geo distribution data
241
+ */
242
+ public static geoDistribution<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
243
+ return Requests.processRoute(
244
+ WebsiteAnalyticsRoute.routes.geoDistribution,
245
+ {},
246
+ undefined,
247
+ params
248
+ );
249
+ }
250
+
251
+ /**
252
+ * Get device type breakdown
253
+ *
254
+ * @param params Filtering options:
255
+ * - title_id?: string - Filter by title ID
256
+ * - start_date?: string - Start date (YYYY-MM-DD)
257
+ * - end_date?: string - End date (YYYY-MM-DD)
258
+ * @returns Promise with device breakdown data
259
+ */
260
+ public static deviceBreakdown<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
261
+ return Requests.processRoute(
262
+ WebsiteAnalyticsRoute.routes.deviceBreakdown,
263
+ {},
264
+ undefined,
265
+ params
266
+ );
267
+ }
268
+
269
+ /**
270
+ * Get top referrers
271
+ *
272
+ * @param params Filtering options:
273
+ * - title_id?: string - Filter by title ID
274
+ * - start_date?: string - Start date (YYYY-MM-DD)
275
+ * - end_date?: string - End date (YYYY-MM-DD)
276
+ * - limit?: number - Number of referrers to return
277
+ * @returns Promise with referrers data
278
+ */
279
+ public static referrers<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
280
+ return Requests.processRoute(
281
+ WebsiteAnalyticsRoute.routes.referrers,
282
+ {},
283
+ undefined,
284
+ params
285
+ );
286
+ }
287
+
288
+ /**
289
+ * Get UTM campaign performance
290
+ *
291
+ * @param params Filtering options:
292
+ * - title_id?: string - Filter by title ID
293
+ * - start_date?: string - Start date (YYYY-MM-DD)
294
+ * - end_date?: string - End date (YYYY-MM-DD)
295
+ * - group_by?: 'source'|'medium'|'campaign' - Grouping field
296
+ * @returns Promise with UTM performance data
297
+ */
298
+ public static utmPerformance<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
299
+ return Requests.processRoute(
300
+ WebsiteAnalyticsRoute.routes.utmPerformance,
301
+ {},
302
+ undefined,
303
+ params
304
+ );
305
+ }
306
+ }
307
+
308
+ export default WebsiteAnalytics;
package/src/api/index.ts CHANGED
@@ -31,6 +31,7 @@ import Scheduler from "./Scheduler";
31
31
  import Funnel from "./Funnel";
32
32
  import SocialStats from "./SocialStats";
33
33
  import Hashtags from "./Hashtags";
34
+ import WebsiteAnalytics from "./WebsiteAnalytics";
34
35
 
35
36
  export {Ads};
36
37
  export {Auth};
@@ -64,4 +65,5 @@ export {Media};
64
65
  export {Scheduler};
65
66
  export {Funnel};
66
67
  export {SocialStats};
67
- export {Hashtags};
68
+ export {Hashtags};
69
+ export {WebsiteAnalytics};
package/src/index.ts CHANGED
@@ -35,6 +35,7 @@ import {Scheduler} from "./api";
35
35
  import {Funnel} from "./api";
36
36
  import {SocialStats} from "./api";
37
37
  import {Hashtags} from "./api";
38
+ import {WebsiteAnalytics} from "./api";
38
39
 
39
40
  import Requests from "./util/Requests";
40
41
  import Parser from "./util/Parser";
@@ -98,7 +99,8 @@ class Glitch {
98
99
  Media : Media,
99
100
  Scheduler : Scheduler,
100
101
  Funnel: Funnel,
101
- SocialStats : SocialStats
102
+ SocialStats : SocialStats,
103
+ WebsiteAnalytics: WebsiteAnalytics
102
104
  }
103
105
 
104
106
  public static util = {
@@ -136,6 +136,36 @@ class AdsRoute {
136
136
  url: "/ads/campaigns/{campaign_id}/groups/{group_id}/triggers/{trigger_id}",
137
137
  method: HTTP_METHODS.DELETE,
138
138
  },
139
+
140
+ // REDDIT TARGETING routes
141
+ getRedditCarriers: {
142
+ url: "/ads/reddit/targeting/carriers",
143
+ method: HTTP_METHODS.GET,
144
+ },
145
+ getRedditCommunities: {
146
+ url: "/ads/reddit/targeting/communities",
147
+ method: HTTP_METHODS.GET,
148
+ },
149
+ searchRedditCommunities: {
150
+ url: "/ads/reddit/targeting/communities/search",
151
+ method: HTTP_METHODS.GET,
152
+ },
153
+ getRedditDevices: {
154
+ url: "/ads/reddit/targeting/devices",
155
+ method: HTTP_METHODS.GET,
156
+ },
157
+ getRedditGeolocations: {
158
+ url: "/ads/reddit/targeting/geolocations",
159
+ method: HTTP_METHODS.GET,
160
+ },
161
+ getRedditInterests: {
162
+ url: "/ads/reddit/targeting/interests",
163
+ method: HTTP_METHODS.GET,
164
+ },
165
+ getRedditThirdPartyAudiences: {
166
+ url: "/ads/reddit/targeting/third_party_audiences",
167
+ method: HTTP_METHODS.GET,
168
+ },
139
169
  };
140
170
  }
141
171
 
@@ -13,6 +13,7 @@ class SchedulerRoute {
13
13
 
14
14
  // Title Update Routes
15
15
  listUpdates: { url: '/schedulers/{scheduler_id}/updates', method: HTTP_METHODS.GET },
16
+ searchUpdates: { url: '/schedulers/{scheduler_id}/updates/search', method: HTTP_METHODS.GET },
16
17
  createUpdate: { url: '/schedulers/{scheduler_id}/updates', method: HTTP_METHODS.POST },
17
18
  getUpdate: { url: '/schedulers/{scheduler_id}/updates/{update_id}', method: HTTP_METHODS.GET },
18
19
  updateUpdate: { url: '/schedulers/{scheduler_id}/updates/{update_id}', method: HTTP_METHODS.PUT },
@@ -32,6 +33,7 @@ class SchedulerRoute {
32
33
  clearTwitchAuth: { url: '/schedulers/{scheduler_id}/clearTwitchAuth', method: HTTP_METHODS.DELETE },
33
34
  clearKickAuth: { url: '/schedulers/{scheduler_id}/clearKickAuth', method: HTTP_METHODS.DELETE },
34
35
  clearRedditAuth: { url: '/schedulers/{scheduler_id}/clearRedditAuth', method: HTTP_METHODS.DELETE },
36
+ clearRedditAdsAuth: { url: '/schedulers/{scheduler_id}/clearRedditAdsAuth', method: HTTP_METHODS.DELETE },
35
37
  clearYouTubeAuth: { url: '/schedulers/{scheduler_id}/clearYouTubeAuth', method: HTTP_METHODS.DELETE },
36
38
  clearPatreonAuth: { url: '/schedulers/{scheduler_id}/clearPatreonAuth', method: HTTP_METHODS.DELETE },
37
39
  clearPinterestAuth: { url: '/schedulers/{scheduler_id}/clearPinterestAuth', method: HTTP_METHODS.DELETE },
@@ -0,0 +1,69 @@
1
+ import Route from "./interface";
2
+ import HTTP_METHODS from "../constants/HttpMethods";
3
+
4
+ class WebsiteAnalyticsRoute {
5
+ public static routes: { [key: string]: Route } = {
6
+ listSessions: {
7
+ url: '/analytics/sessions',
8
+ method: HTTP_METHODS.GET
9
+ },
10
+ listPageviews: {
11
+ url: '/analytics/pageviews',
12
+ method: HTTP_METHODS.GET
13
+ },
14
+ listEvents: {
15
+ url: '/analytics/events',
16
+ method: HTTP_METHODS.GET
17
+ },
18
+ overview: {
19
+ url: '/analytics/overview',
20
+ method: HTTP_METHODS.GET
21
+ },
22
+ collect: {
23
+ url: '/analytics/collect',
24
+ method: HTTP_METHODS.POST
25
+ },
26
+ sessionsAverage: {
27
+ url: '/analytics/sessions/average',
28
+ method: HTTP_METHODS.GET
29
+ },
30
+ sessionsHistogram: {
31
+ url: '/analytics/sessions/histogram',
32
+ method: HTTP_METHODS.GET
33
+ },
34
+ pageviewsOverTime: {
35
+ url: '/analytics/pageviews/over-time',
36
+ method: HTTP_METHODS.GET
37
+ },
38
+ topPages: {
39
+ url: '/analytics/pageviews/top-pages',
40
+ method: HTTP_METHODS.GET
41
+ },
42
+ eventsSummary: {
43
+ url: '/analytics/events/summary',
44
+ method: HTTP_METHODS.GET
45
+ },
46
+ popularEvents: {
47
+ url: '/analytics/events/popular',
48
+ method: HTTP_METHODS.GET
49
+ },
50
+ geoDistribution: {
51
+ url: '/analytics/geo-distribution',
52
+ method: HTTP_METHODS.GET
53
+ },
54
+ deviceBreakdown: {
55
+ url: '/analytics/device-breakdown',
56
+ method: HTTP_METHODS.GET
57
+ },
58
+ referrers: {
59
+ url: '/analytics/referrers',
60
+ method: HTTP_METHODS.GET
61
+ },
62
+ utmPerformance: {
63
+ url: '/analytics/utm-performance',
64
+ method: HTTP_METHODS.GET
65
+ }
66
+ };
67
+ }
68
+
69
+ export default WebsiteAnalyticsRoute;
@@ -1,8 +1,70 @@
1
1
  import { Config } from "../config";
2
2
  import Storage from "./Storage";
3
3
 
4
- class Session {
4
+ // Type declarations for crypto functionality
5
+ interface HmacInterface {
6
+ update(data: string): HmacInterface;
7
+ digest(encoding: 'hex'): string;
8
+ }
9
+
10
+ interface CryptoInterface {
11
+ createHmac(algorithm: string, secret: string): HmacInterface;
12
+ }
13
+
14
+ // Browser implementation using crypto-js
15
+ class BrowserCrypto implements CryptoInterface {
16
+ createHmac(algorithm: string, secret: string): HmacInterface {
17
+ const CryptoJS = require('crypto-js');
18
+
19
+ let data = '';
20
+
21
+ const hmac: HmacInterface = {
22
+ update: (updateData: string): HmacInterface => {
23
+ data = updateData;
24
+ return hmac;
25
+ },
26
+ digest: (encoding: 'hex'): string => {
27
+ if (encoding !== 'hex') {
28
+ throw new Error('Only hex encoding is supported in browser implementation');
29
+ }
30
+ return CryptoJS.HmacSHA256(data, secret).toString(CryptoJS.enc.Hex);
31
+ }
32
+ };
33
+
34
+ return hmac;
35
+ }
36
+ }
37
+
38
+ // Node.js implementation using native crypto
39
+ class NodeCrypto implements CryptoInterface {
40
+ private crypto: typeof import('crypto');
41
+
42
+ constructor() {
43
+ this.crypto = require('crypto');
44
+ }
45
+
46
+ createHmac(algorithm: string, secret: string): HmacInterface {
47
+ return this.crypto.createHmac(algorithm, secret);
48
+ }
49
+ }
50
+
51
+ // Determine which crypto implementation to use
52
+ const getCrypto = (): CryptoInterface => {
53
+ try {
54
+ // Check if we're in Node.js environment
55
+ if (typeof process !== 'undefined' && process.versions && process.versions.node) {
56
+ return new NodeCrypto();
57
+ }
58
+ // Fall back to browser implementation
59
+ return new BrowserCrypto();
60
+ } catch (e) {
61
+ return new BrowserCrypto();
62
+ }
63
+ };
64
+
65
+ const crypto = getCrypto();
5
66
 
67
+ class Session {
6
68
  private static _id_key = 'user_id';
7
69
  private static _first_name_key = 'user_first_name';
8
70
  private static _last_name_key = 'user_last_name';
@@ -37,7 +99,7 @@ class Session {
37
99
  public static hasJoinedCommunity() {
38
100
  const community = Storage.get('community');
39
101
 
40
- if(!community) {
102
+ if (!community) {
41
103
  return false;
42
104
  }
43
105
 
@@ -53,7 +115,7 @@ class Session {
53
115
  Storage.set(Session._username_key, null);
54
116
  }
55
117
 
56
- public static processAuthentication(data: { token: { access_token: string }, id: string, first_name: string, last_name: string, email: string, username: string }): void {
118
+ public static processAuthentication(data: { token: { access_token: string }, id: string, first_name: string, last_name: string, email: string, username: string }): void {
57
119
  Storage.setAuthToken(data.token.access_token);
58
120
  Storage.set(Session._id_key, data.id);
59
121
  Storage.set(Session._first_name_key, data.first_name);
@@ -63,6 +125,32 @@ class Session {
63
125
 
64
126
  Config.setAuthToken(data.token.access_token);
65
127
  }
128
+
129
+ /**
130
+ * Generate a tracking token for analytics collection
131
+ * @param titleId The title ID to generate token for
132
+ * @param secret The secret key (should match server config)
133
+ * @returns HMAC-SHA256 token
134
+ * @throws Error if crypto operations fail
135
+ */
136
+ public static generateTrackingToken(titleId: string, secret: string): string {
137
+ try {
138
+ if (!titleId) {
139
+ throw new Error('titleId is required');
140
+ }
141
+ if (!secret) {
142
+ throw new Error('secret is required');
143
+ }
144
+
145
+ return crypto
146
+ .createHmac('sha256', secret)
147
+ .update(titleId)
148
+ .digest('hex');
149
+ } catch (error) {
150
+ console.error('Failed to generate tracking token:', error);
151
+ throw new Error('Failed to generate tracking token');
152
+ }
153
+ }
66
154
  }
67
155
 
68
- export default Session;
156
+ export default Session;