@gapi/onesignal-notifications 1.8.122

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,7 @@
1
+ export declare const Constants: {
2
+ API_ROOT: string;
3
+ /** PATHS **/
4
+ NOTIFICATIONS_PATH: string;
5
+ APPS_PATH: string;
6
+ DEVICES_PATH: string;
7
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Constants = void 0;
4
+ exports.Constants = {
5
+ API_ROOT: 'https://onesignal.com/api/v1',
6
+ /** PATHS **/
7
+ NOTIFICATIONS_PATH: '/notifications',
8
+ APPS_PATH: '/apps',
9
+ DEVICES_PATH: '/players',
10
+ };
@@ -0,0 +1,8 @@
1
+ import { ModuleWithServices } from '@rxdi/core';
2
+ import { OneSignalConfig } from './onesignal.config';
3
+ export declare class OneSignalModule {
4
+ static forRoot(config: OneSignalConfig): ModuleWithServices;
5
+ }
6
+ export * from './notification';
7
+ export * from './client';
8
+ export * from './interfaces/index';
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
10
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
11
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
12
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
13
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
14
+ };
15
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
+ for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
17
+ };
18
+ var OneSignalModule_1;
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.OneSignalModule = void 0;
21
+ const core_1 = require("@rxdi/core");
22
+ const client_1 = require("./client");
23
+ let OneSignalModule = OneSignalModule_1 = class OneSignalModule {
24
+ static forRoot(config) {
25
+ core_1.Container.set(client_1.OneSignalClientService, new client_1.OneSignalClientService(config));
26
+ return {
27
+ module: OneSignalModule_1,
28
+ };
29
+ }
30
+ };
31
+ OneSignalModule = OneSignalModule_1 = __decorate([
32
+ core_1.Module()
33
+ ], OneSignalModule);
34
+ exports.OneSignalModule = OneSignalModule;
35
+ __exportStar(require("./notification"), exports);
36
+ __exportStar(require("./client"), exports);
37
+ __exportStar(require("./interfaces/index"), exports);
@@ -0,0 +1,19 @@
1
+ import { SendNotificationResponse } from './notificationResponse';
2
+ export interface OneSignalClient {
3
+ setRootUrl(rootUrl: string): void;
4
+ setApp(app: any): void;
5
+ sendNotification(notification: any, callback?: any): Promise<SendNotificationResponse>;
6
+ cancelNotification(notificationId: any, callback: any): Promise<any>;
7
+ viewNotification(notificationId: any, callback: any): Promise<any>;
8
+ viewNotifications(query: any, callback: any): Promise<any>;
9
+ viewApps(callback: any): Promise<any>;
10
+ viewApp(appId: any, callback: any): Promise<any>;
11
+ createApp(body: any, callback: any): Promise<any>;
12
+ updateApp(body: any, callback: any): Promise<any>;
13
+ viewDevices(query: any, callback: any): Promise<any>;
14
+ viewDevice(deviceId: any, callback: any): Promise<any>;
15
+ addDevice(body: any, callback: any): Promise<any>;
16
+ editDevice(deviceId: any, body: any, callback: any): Promise<any>;
17
+ trackOpen(notificationId: any, body: any, callback: any): Promise<any>;
18
+ csvExport(body: any, callback: any): Promise<any>;
19
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export * from './client';
2
+ export * from './notificationDataResponse';
3
+ export * from './notificationHttpResponse';
4
+ export * from './notificationResponse';
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./client"), exports);
14
+ __exportStar(require("./notificationDataResponse"), exports);
15
+ __exportStar(require("./notificationHttpResponse"), exports);
16
+ __exportStar(require("./notificationResponse"), exports);
@@ -0,0 +1,4 @@
1
+ export interface SendNotificationDataResponse {
2
+ id: string;
3
+ recipients: number;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,42 @@
1
+ /// <reference types="node" />
2
+ import { Domain } from 'domain';
3
+ import { ClientRequest } from 'http';
4
+ import { TLSSocket } from 'tls';
5
+ import { SendNotificationDataResponse } from './notificationDataResponse';
6
+ export interface SendNotificationHttpResponse {
7
+ _consuming: boolean;
8
+ _dumped: boolean;
9
+ _events: any;
10
+ _eventsCount: number;
11
+ _maxListeners: number;
12
+ _readableState: any;
13
+ body: SendNotificationDataResponse;
14
+ caseless: {
15
+ dict: Record<string, any>;
16
+ };
17
+ client: TLSSocket;
18
+ complete: true;
19
+ connection: TLSSocket;
20
+ destroyed: boolean;
21
+ domain: Domain;
22
+ headers: Record<string, any>;
23
+ httpVersion: string;
24
+ httpVersionMajor: number;
25
+ httpVersionMinor: number;
26
+ method: any;
27
+ rawHeaders: Array<{
28
+ [key: string]: string;
29
+ }>;
30
+ rawTrailers: Array<any>;
31
+ read: Function;
32
+ readable: boolean;
33
+ req: ClientRequest;
34
+ request: Request;
35
+ socket: TLSSocket;
36
+ statusCode: number;
37
+ statusMessage: string;
38
+ toJSON: Function;
39
+ trailers: Record<string, any>;
40
+ upgrade: boolean;
41
+ url: string;
42
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ import { SendNotificationDataResponse } from './notificationDataResponse';
2
+ import { SendNotificationHttpResponse } from './notificationHttpResponse';
3
+ export interface SendNotificationResponse {
4
+ data: SendNotificationDataResponse;
5
+ httpResponse: SendNotificationHttpResponse;
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,34 @@
1
+ export interface PostBody {
2
+ contents: {
3
+ [key: string]: string;
4
+ };
5
+ data: any;
6
+ content_available: any;
7
+ template_id: any;
8
+ included_segments: any;
9
+ excluded_segments: any;
10
+ filters: any;
11
+ app_ids: any;
12
+ app_id: any;
13
+ include_player_ids: string[];
14
+ }
15
+ export declare class Notification {
16
+ initialBody: {
17
+ contents?: any;
18
+ content_available?: any;
19
+ template_id?: any;
20
+ };
21
+ postBody: PostBody;
22
+ allowed_fields: string[];
23
+ constructor(initialBody: {
24
+ contents?: any;
25
+ content_available?: any;
26
+ template_id?: any;
27
+ });
28
+ setParameter(name: string, value: any): this;
29
+ setContent(contents: any): this;
30
+ setIncludedSegments<T>(included_segments: T[]): this;
31
+ setExcludedSegments<T>(excluded_segments: T[]): this;
32
+ setFilters(filters: any): this;
33
+ setTargetDevices(include_player_ids: string[]): this;
34
+ }
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Notification = void 0;
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ const ALLOWED_FIELDS = [
6
+ 'contents',
7
+ 'included_segments',
8
+ 'excluded_segments',
9
+ 'filters',
10
+ 'include_player_ids',
11
+ 'app_id',
12
+ 'app_ids',
13
+ 'headings',
14
+ 'subtitle',
15
+ 'template_id',
16
+ 'content_available',
17
+ 'mutable_content',
18
+ 'data',
19
+ 'url',
20
+ 'ios_attachments',
21
+ 'big_picture',
22
+ 'adm_big_picture',
23
+ 'chrome_big_picture',
24
+ 'buttons',
25
+ 'web_buttons',
26
+ 'ios_category',
27
+ 'android_background_layout',
28
+ 'small_icon',
29
+ 'large_icon',
30
+ 'adm_small_icon',
31
+ 'adm_large_icon',
32
+ 'chrome_web_icon',
33
+ 'chrome_web_image',
34
+ 'firefox_icon',
35
+ 'chrome_icon',
36
+ 'ios_sound',
37
+ 'android_sound',
38
+ 'android_led_color',
39
+ 'android_accent_color',
40
+ 'android_visibility',
41
+ 'adm_sound',
42
+ 'ios_badgeType',
43
+ 'ios_badgeCount',
44
+ 'collapse_id',
45
+ 'send_after',
46
+ 'delayed_option',
47
+ 'delivery_time_of_day',
48
+ 'ttl',
49
+ 'priority',
50
+ 'android_group',
51
+ 'android_group_message',
52
+ 'adm_group',
53
+ 'adm_group_message',
54
+ 'isIos',
55
+ 'isAndroid',
56
+ 'isAnyWeb',
57
+ 'isChromeWeb',
58
+ 'isFirefox',
59
+ 'isSafari',
60
+ 'isWP',
61
+ 'isWP_WNS',
62
+ 'isAdm',
63
+ 'isChrome',
64
+ 'android_channel_id',
65
+ 'existing_android_channel_id',
66
+ ];
67
+ class Notification {
68
+ constructor(initialBody) {
69
+ this.allowed_fields = ALLOWED_FIELDS;
70
+ this.initialBody = initialBody;
71
+ this.postBody = {};
72
+ if (initialBody.constructor !== Object) {
73
+ throw new Error('Body must be a JSON object');
74
+ }
75
+ if ('contents' in initialBody) {
76
+ this.postBody.contents = this.initialBody.contents;
77
+ return;
78
+ }
79
+ if ('content_available' in initialBody) {
80
+ this.postBody.content_available = this.initialBody.content_available;
81
+ return;
82
+ }
83
+ if ('template_id' in initialBody) {
84
+ this.postBody.template_id = this.initialBody.template_id;
85
+ return;
86
+ }
87
+ throw new Error('Body must include one of the following fields: contents, content_available, template_id');
88
+ }
89
+ setParameter(name, value) {
90
+ if (name && name[0] === '!') {
91
+ name = name.substring(1);
92
+ }
93
+ else if (ALLOWED_FIELDS.indexOf(name) === -1) {
94
+ throw new Error('"' +
95
+ name +
96
+ '" is not present in documentation. You should add a ' +
97
+ 'exclamation mark to the begging of the name, if you want to set it : !' +
98
+ name);
99
+ }
100
+ this.postBody[name] = value;
101
+ return this;
102
+ }
103
+ setContent(contents) {
104
+ this.postBody.contents = contents;
105
+ return this;
106
+ }
107
+ setIncludedSegments(included_segments) {
108
+ this.postBody.included_segments = included_segments;
109
+ return this;
110
+ }
111
+ setExcludedSegments(excluded_segments) {
112
+ this.postBody.excluded_segments = excluded_segments;
113
+ return this;
114
+ }
115
+ setFilters(filters) {
116
+ this.postBody.filters = filters;
117
+ return this;
118
+ }
119
+ setTargetDevices(include_player_ids) {
120
+ this.postBody.include_player_ids = include_player_ids;
121
+ return this;
122
+ }
123
+ }
124
+ exports.Notification = Notification;
@@ -0,0 +1,7 @@
1
+ export declare class OneSignalConfig {
2
+ userAuthKey: string;
3
+ app: {
4
+ appAuthKey: string;
5
+ appId: string;
6
+ };
7
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OneSignalConfig = void 0;
4
+ class OneSignalConfig {
5
+ }
6
+ exports.OneSignalConfig = OneSignalConfig;
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@gapi/onesignal-notifications",
3
+ "version": "1.8.122",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/Stradivario/onesignal-notifications.git"
7
+ },
8
+ "scripts": {
9
+ "patch": "npm run build && npm version patch && npm publish --update-readme --access public && npm run delete-dist",
10
+ "delete-dist": "rm -rf dist",
11
+ "clean": "git clean -dxf",
12
+ "lint": "npx eslint . --ext .ts",
13
+ "lint-fix": "npx eslint . --fix --ext .ts",
14
+ "build": "rm -rf dist && tsc || true"
15
+ },
16
+ "author": {
17
+ "name": "Kristian Tachev(Stradivario)",
18
+ "email": "kristiqn.tachev@gmail.com"
19
+ },
20
+ "keywords": [
21
+ "graphql",
22
+ "gapi",
23
+ "node"
24
+ ],
25
+ "license": "MIT",
26
+ "bugs": {
27
+ "url": "http://gitlab.youvolio.com/gapi/onesignal-notifications/issues"
28
+ },
29
+ "dependencies": {
30
+ "request": "^2.88.0"
31
+ },
32
+ "devDependencies": {
33
+ "@rxdi/core": "^0.7.114",
34
+ "@types/node": "^13.11.1",
35
+ "@types/request": "^2.48.1"
36
+ },
37
+ "main": "./dist/index.js",
38
+ "types": "./dist/index.d.ts",
39
+ "module": "./dist/index.js",
40
+ "typings": "./dist/index.d.ts"
41
+ }
package/src/client.ts ADDED
@@ -0,0 +1,358 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { Service } from '@rxdi/core';
3
+ import * as request from 'request';
4
+
5
+ import { Constants } from './constants';
6
+ import { OneSignalClient } from './interfaces/client';
7
+ import { SendNotificationResponse } from './interfaces/notificationResponse';
8
+ import { Notification } from './notification';
9
+ import { OneSignalConfig } from './onesignal.config';
10
+
11
+ function checkCredential(credentialName, credential): boolean {
12
+ const ALLOWED_CREDENTIALS: any = [
13
+ { name: 'userAuthKey', type: 'string' },
14
+ { name: 'app', type: 'object', requiredFields: ['appAuthKey', 'appId'] },
15
+ { name: 'apps', type: 'object' },
16
+ ];
17
+ for (let i = 0; i < ALLOWED_CREDENTIALS.length; i++) {
18
+ if (ALLOWED_CREDENTIALS[i].name === credentialName) {
19
+ if (typeof credential !== ALLOWED_CREDENTIALS[i].type) {
20
+ throw new Error(
21
+ credentialName + ' must be a ' + ALLOWED_CREDENTIALS[i].type
22
+ );
23
+ }
24
+ if (ALLOWED_CREDENTIALS[i].requiredFields) {
25
+ for (let j = 0; j < ALLOWED_CREDENTIALS[i].requiredFields.length; j++) {
26
+ if (!(ALLOWED_CREDENTIALS[i].requiredFields[j] in credential)) {
27
+ throw new Error(
28
+ credentialName +
29
+ ' must contain ' +
30
+ ALLOWED_CREDENTIALS[i].requiredFields[j]
31
+ );
32
+ }
33
+ }
34
+ }
35
+ return true;
36
+ }
37
+ }
38
+ return false;
39
+ }
40
+
41
+ export interface DevicesData<T> {
42
+ players: Player<T>[];
43
+ }
44
+
45
+ export interface Player<T> {
46
+ id: string;
47
+ identifier: string;
48
+ session_count: number;
49
+ language: string;
50
+ timezone: number;
51
+ game_version: string;
52
+ device_os: string;
53
+ device_type: number;
54
+ device_model: string;
55
+ ad_id: string;
56
+ tags: T;
57
+ last_active: number;
58
+ playtime: number;
59
+ amount_spend: number;
60
+ created_at: number;
61
+ invalid_identifier: boolean;
62
+ badge_count: number;
63
+ sdk: string;
64
+ test_type: any;
65
+ ip: any;
66
+ }
67
+
68
+ @Service()
69
+ export class OneSignalClientService implements OneSignalClient {
70
+ API_URI: string;
71
+ app: any;
72
+ apps: any;
73
+ userAuthKey: string;
74
+
75
+ constructor(credentials: OneSignalConfig) {
76
+ if (typeof credentials !== 'object') {
77
+ throw new Error('credentials parameter must be a JSON object');
78
+ }
79
+
80
+ this.API_URI = Constants.API_ROOT;
81
+
82
+ for (const key in credentials) {
83
+ if (
84
+ credentials.hasOwnProperty(key) &&
85
+ checkCredential(key, credentials[key])
86
+ ) {
87
+ this[key] = credentials[key];
88
+ }
89
+ }
90
+ }
91
+
92
+ basicRequest(
93
+ url: string,
94
+ apiKey: string,
95
+ method: 'PUT' | 'POST' | 'GET' | 'DELETE',
96
+ body
97
+ ): Promise<any> {
98
+ const options = {
99
+ url: url,
100
+ method: method,
101
+ } as any;
102
+ if (apiKey) {
103
+ options.headers = {
104
+ 'Content-Type': 'application/json; charset=utf-8',
105
+ Authorization: 'Basic ' + apiKey,
106
+ };
107
+ }
108
+ if (body) {
109
+ options.body = body;
110
+ options.json = true;
111
+ }
112
+
113
+ return new Promise(function (resolve, reject) {
114
+ request(options, function (err, httpResponse, data) {
115
+ if (err) {
116
+ return reject(err);
117
+ }
118
+ return resolve({ httpResponse: httpResponse, data: data });
119
+ });
120
+ });
121
+ }
122
+ setRootUrl(rootUrl: string) {
123
+ if (!rootUrl) {
124
+ throw new Error('You must set a valid rootUsrl.');
125
+ }
126
+ this.API_URI = rootUrl;
127
+ }
128
+
129
+ setApp(app) {
130
+ checkCredential('app', app);
131
+ this.app = app;
132
+ }
133
+
134
+ async sendNotification(
135
+ notification: Notification
136
+ ): Promise<SendNotificationResponse> {
137
+ if (!notification || !notification.postBody) {
138
+ throw new Error(
139
+ 'notification parameter must be a typeof Notification object.'
140
+ );
141
+ }
142
+ const postBody = notification.postBody;
143
+ if (this.apps && this.apps.length > 0) {
144
+ postBody.app_ids = this.apps;
145
+ return await this.basicRequest(
146
+ this.API_URI + Constants.NOTIFICATIONS_PATH,
147
+ this.userAuthKey,
148
+ 'POST',
149
+ postBody
150
+ );
151
+ }
152
+ if (this.app) {
153
+ postBody.app_id = this.app.appId;
154
+ return await this.basicRequest(
155
+ this.API_URI + Constants.NOTIFICATIONS_PATH,
156
+ this.app.appAuthKey,
157
+ 'POST',
158
+ postBody
159
+ );
160
+ }
161
+ throw new Error('You must set either an "app" or "apps" on Client');
162
+ }
163
+
164
+ async cancelNotification(notificationId: string): Promise<any> {
165
+ if (!this.app) {
166
+ throw new Error('You must define an "app" object.');
167
+ }
168
+ const notificationUri =
169
+ this.API_URI +
170
+ Constants.NOTIFICATIONS_PATH +
171
+ '/' +
172
+ notificationId +
173
+ '?app_id=' +
174
+ this.app.appId;
175
+ return await this.basicRequest(
176
+ notificationUri,
177
+ this.app.appAuthKey,
178
+ 'DELETE',
179
+ null
180
+ );
181
+ }
182
+
183
+ async viewNotification(notificationId: string): Promise<any> {
184
+ if (!this.app) {
185
+ throw new Error('You must define an "app" object.');
186
+ }
187
+ const notificationUri =
188
+ this.API_URI +
189
+ Constants.NOTIFICATIONS_PATH +
190
+ '/' +
191
+ notificationId +
192
+ '?app_id=' +
193
+ this.app.appId;
194
+ return await this.basicRequest(
195
+ notificationUri,
196
+ this.app.appAuthKey,
197
+ 'GET',
198
+ null
199
+ );
200
+ }
201
+
202
+ async viewNotifications(query: {
203
+ limit: number;
204
+ offset: number;
205
+ }): Promise<any> {
206
+ if (!this.app) {
207
+ throw new Error('You must define an "app" object.');
208
+ }
209
+ const appUri =
210
+ this.API_URI +
211
+ Constants.NOTIFICATIONS_PATH +
212
+ '?app_id=' +
213
+ this.app.appId +
214
+ '&' +
215
+ query;
216
+ return await this.basicRequest(appUri, this.app.appAuthKey, 'GET', null);
217
+ }
218
+
219
+ async viewApps(): Promise<any> {
220
+ if (!this.userAuthKey) {
221
+ throw new Error('You must define "userAuthKey" on Client');
222
+ }
223
+ return await this.basicRequest(
224
+ this.API_URI + Constants.APPS_PATH,
225
+ this.userAuthKey,
226
+ 'GET',
227
+ null
228
+ );
229
+ }
230
+
231
+ async viewApp(appId: string): Promise<any> {
232
+ if (!this.userAuthKey) {
233
+ throw new Error('You must define "userAuthKey" on Client');
234
+ }
235
+ return await this.basicRequest(
236
+ this.API_URI + Constants.APPS_PATH + '/' + appId,
237
+ this.userAuthKey,
238
+ 'GET',
239
+ null
240
+ );
241
+ }
242
+
243
+ async createApp(body): Promise<any> {
244
+ if (!body.name) {
245
+ throw new Error('You must specify a name in body');
246
+ }
247
+ if (!this.userAuthKey) {
248
+ throw new Error('You must define "userAuthKey" on Client');
249
+ }
250
+ return await this.basicRequest(
251
+ this.API_URI + Constants.APPS_PATH,
252
+ this.userAuthKey,
253
+ 'POST',
254
+ body
255
+ );
256
+ }
257
+
258
+ async updateApp(body): Promise<any> {
259
+ if (!this.app) {
260
+ throw new Error('You must define an "app" object.');
261
+ }
262
+ if (!this.userAuthKey) {
263
+ throw new Error('You must define "userAuthKey" on Client');
264
+ }
265
+ return await this.basicRequest(
266
+ this.API_URI + Constants.APPS_PATH + '/' + this.app.appId,
267
+ this.userAuthKey,
268
+ 'PUT',
269
+ body
270
+ );
271
+ }
272
+
273
+ async viewDevices<T>(query: {
274
+ limit: number;
275
+ offset: number;
276
+ }): Promise<{ data: DevicesData<T> }> {
277
+ if (!this.app) {
278
+ throw new Error('You must define an "app" object.');
279
+ }
280
+ const viewUri =
281
+ this.API_URI +
282
+ Constants.DEVICES_PATH +
283
+ '?app_id=' +
284
+ this.app.appId +
285
+ '&' +
286
+ query;
287
+ return await this.basicRequest(viewUri, this.app.appAuthKey, 'GET', null);
288
+ }
289
+
290
+ async viewDevice(deviceId: string): Promise<any> {
291
+ if (!this.app) {
292
+ throw new Error('You must define an "app" object.');
293
+ }
294
+ const viewUri =
295
+ this.API_URI +
296
+ Constants.DEVICES_PATH +
297
+ '/' +
298
+ deviceId +
299
+ '?app_id=' +
300
+ this.app.appId;
301
+ return await this.basicRequest(viewUri, this.app.appAuthKey, 'GET', null);
302
+ }
303
+
304
+ async addDevice(body): Promise<any> {
305
+ if (!this.app) {
306
+ throw new Error('You must define an "app" object.');
307
+ }
308
+ if (!('app_id' in body)) {
309
+ body.app_id = this.app.appId;
310
+ }
311
+ return await this.basicRequest(
312
+ this.API_URI + Constants.DEVICES_PATH,
313
+ this.app.appAuthKey,
314
+ 'POST',
315
+ body
316
+ );
317
+ }
318
+
319
+ async editDevice(deviceId: string, body): Promise<any> {
320
+ if (!this.app) {
321
+ throw new Error('You must define an "app" object.');
322
+ }
323
+ return await this.basicRequest(
324
+ this.API_URI + Constants.DEVICES_PATH + '/' + deviceId,
325
+ this.app.appAuthKey,
326
+ 'PUT',
327
+ body
328
+ );
329
+ }
330
+
331
+ async trackOpen(notificationId: string, body): Promise<any> {
332
+ if (!this.app) {
333
+ throw new Error('You must define an "app" object.');
334
+ }
335
+ if (!('app_id' in body)) {
336
+ body.app_id = this.app.appId;
337
+ }
338
+ return await this.basicRequest(
339
+ this.API_URI + Constants.NOTIFICATIONS_PATH + '/' + notificationId,
340
+ this.app.appAuthKey,
341
+ 'PUT',
342
+ body
343
+ );
344
+ }
345
+
346
+ async csvExport(body): Promise<any> {
347
+ if (!this.app) {
348
+ throw new Error('You must define an "app" object.');
349
+ }
350
+ const csvUri =
351
+ this.API_URI +
352
+ Constants.DEVICES_PATH +
353
+ '/csv_export' +
354
+ '?app_id=' +
355
+ this.app.appId;
356
+ return await this.basicRequest(csvUri, this.app.appAuthKey, 'POST', body);
357
+ }
358
+ }