@rivium/push-node 0.1.2 → 0.1.4
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 +40 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +6 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -1
- package/dist/modules/devices.d.ts +32 -1
- package/dist/modules/devices.js +35 -0
- package/dist/modules/receipts.d.ts +61 -0
- package/dist/modules/receipts.js +78 -0
- package/dist/types.d.ts +182 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +6 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -200,6 +200,46 @@ await riviumPush.devices.setUserId('device-uuid', 'user-123');
|
|
|
200
200
|
|
|
201
201
|
// Delete a device
|
|
202
202
|
await riviumPush.devices.delete('device-uuid');
|
|
203
|
+
|
|
204
|
+
// Paginated, filtered list (includes inactive devices unless isActive is set)
|
|
205
|
+
const { items, total } = await riviumPush.devices.listPage({
|
|
206
|
+
platform: 'web',
|
|
207
|
+
sdkName: 'web',
|
|
208
|
+
isActive: true,
|
|
209
|
+
page: 1,
|
|
210
|
+
limit: 50,
|
|
211
|
+
});
|
|
212
|
+
console.log(items[0]?.sdkName, items[0]?.sdkVersion, items[0]?.appVersion, items[0]?.updatedAt);
|
|
213
|
+
|
|
214
|
+
// Values you can filter on (app versions, SDK versions, failure reasons)
|
|
215
|
+
const options = await riviumPush.devices.filterOptions();
|
|
216
|
+
|
|
217
|
+
// Soft-unregister (stops sends, keeps history) and undo it
|
|
218
|
+
await riviumPush.devices.unregister('device-uuid');
|
|
219
|
+
await riviumPush.devices.reactivate('device-uuid');
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
`list()` is unchanged and still returns a plain array of active devices.
|
|
223
|
+
|
|
224
|
+
## Delivery Receipts
|
|
225
|
+
|
|
226
|
+
A send's `success` count means the push service *accepted* the notification.
|
|
227
|
+
Receipts show what happened per device.
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
const { messageId } = await riviumPush.push.sendToUser({ userId: 'user-123', title: 'Hi', body: 'Hello' });
|
|
231
|
+
const receipts = await riviumPush.receipts.getForMessage(messageId!);
|
|
232
|
+
|
|
233
|
+
// Paginated receipt log with filters
|
|
234
|
+
const { items } = await riviumPush.receipts.list({ status: 'failed', platform: 'ios', page: 1, limit: 100 });
|
|
235
|
+
|
|
236
|
+
// Delivery analytics (default range: last 30 days)
|
|
237
|
+
const analytics = await riviumPush.receipts.analytics({
|
|
238
|
+
startDate: new Date(Date.now() - 7 * 86400_000),
|
|
239
|
+
endDate: new Date(),
|
|
240
|
+
bucket: 'day',
|
|
241
|
+
});
|
|
242
|
+
console.log(analytics.totals.deliveryRate, analytics.topFailureReasons);
|
|
203
243
|
```
|
|
204
244
|
|
|
205
245
|
## Templates
|
package/dist/client.d.ts
CHANGED
package/dist/client.js
CHANGED
|
@@ -3,10 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.RiviumPushError = exports.HttpClient = void 0;
|
|
6
|
+
exports.RiviumPushError = exports.HttpClient = exports.SDK_HEADER_VALUE = void 0;
|
|
7
7
|
const https_1 = __importDefault(require("https"));
|
|
8
8
|
const http_1 = __importDefault(require("http"));
|
|
9
|
+
const version_1 = require("./version");
|
|
9
10
|
const BASE_URL = 'https://push-api.rivium.co';
|
|
11
|
+
/** Sent on every request so the backend can attribute traffic to this SDK. */
|
|
12
|
+
exports.SDK_HEADER_VALUE = `${version_1.SDK_NAME}/${version_1.SDK_VERSION}`;
|
|
10
13
|
class HttpClient {
|
|
11
14
|
constructor(config) {
|
|
12
15
|
if (!config.apiKey) {
|
|
@@ -24,7 +27,7 @@ class HttpClient {
|
|
|
24
27
|
if (query) {
|
|
25
28
|
for (const [k, v] of Object.entries(query)) {
|
|
26
29
|
if (v !== undefined && v !== null) {
|
|
27
|
-
url.searchParams.set(k, String(v));
|
|
30
|
+
url.searchParams.set(k, v instanceof Date ? v.toISOString() : String(v));
|
|
28
31
|
}
|
|
29
32
|
}
|
|
30
33
|
}
|
|
@@ -36,6 +39,7 @@ class HttpClient {
|
|
|
36
39
|
'x-api-key': this.apiKey,
|
|
37
40
|
'x-server-secret': this.serverSecret,
|
|
38
41
|
'Content-Type': 'application/json',
|
|
42
|
+
'X-Rivium-SDK': exports.SDK_HEADER_VALUE,
|
|
39
43
|
};
|
|
40
44
|
if (payload) {
|
|
41
45
|
headers['Content-Length'] = Buffer.byteLength(payload);
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { InApp } from './modules/in-app';
|
|
|
8
8
|
import { ABTesting } from './modules/ab-testing';
|
|
9
9
|
import { Webhooks } from './modules/webhooks';
|
|
10
10
|
import { Analytics } from './modules/analytics';
|
|
11
|
+
import { Receipts } from './modules/receipts';
|
|
11
12
|
import { RiviumPushConfig } from './types';
|
|
12
13
|
export declare class RiviumPush {
|
|
13
14
|
private client;
|
|
@@ -31,7 +32,10 @@ export declare class RiviumPush {
|
|
|
31
32
|
webhooks: Webhooks;
|
|
32
33
|
/** Analytics */
|
|
33
34
|
analytics: Analytics;
|
|
35
|
+
/** Per-device delivery receipts for messages you have sent. */
|
|
36
|
+
receipts: Receipts;
|
|
34
37
|
constructor(config: RiviumPushConfig);
|
|
35
38
|
}
|
|
36
39
|
export { RiviumPushError } from './client';
|
|
40
|
+
export { SDK_NAME, SDK_VERSION } from './version';
|
|
37
41
|
export * from './types';
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.RiviumPushError = exports.RiviumPush = void 0;
|
|
17
|
+
exports.SDK_VERSION = exports.SDK_NAME = exports.RiviumPushError = exports.RiviumPush = void 0;
|
|
18
18
|
const client_1 = require("./client");
|
|
19
19
|
const push_1 = require("./modules/push");
|
|
20
20
|
const devices_1 = require("./modules/devices");
|
|
@@ -26,6 +26,7 @@ const in_app_1 = require("./modules/in-app");
|
|
|
26
26
|
const ab_testing_1 = require("./modules/ab-testing");
|
|
27
27
|
const webhooks_1 = require("./modules/webhooks");
|
|
28
28
|
const analytics_1 = require("./modules/analytics");
|
|
29
|
+
const receipts_1 = require("./modules/receipts");
|
|
29
30
|
class RiviumPush {
|
|
30
31
|
constructor(config) {
|
|
31
32
|
this.client = new client_1.HttpClient(config);
|
|
@@ -39,10 +40,14 @@ class RiviumPush {
|
|
|
39
40
|
this.abTesting = new ab_testing_1.ABTesting(this.client);
|
|
40
41
|
this.webhooks = new webhooks_1.Webhooks(this.client);
|
|
41
42
|
this.analytics = new analytics_1.Analytics(this.client);
|
|
43
|
+
this.receipts = new receipts_1.Receipts(this.client);
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
exports.RiviumPush = RiviumPush;
|
|
45
47
|
var client_2 = require("./client");
|
|
46
48
|
Object.defineProperty(exports, "RiviumPushError", { enumerable: true, get: function () { return client_2.RiviumPushError; } });
|
|
49
|
+
var version_1 = require("./version");
|
|
50
|
+
Object.defineProperty(exports, "SDK_NAME", { enumerable: true, get: function () { return version_1.SDK_NAME; } });
|
|
51
|
+
Object.defineProperty(exports, "SDK_VERSION", { enumerable: true, get: function () { return version_1.SDK_VERSION; } });
|
|
47
52
|
// Re-export types
|
|
48
53
|
__exportStar(require("./types"), exports);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HttpClient } from '../client';
|
|
2
|
-
import { Device } from '../types';
|
|
2
|
+
import { Device, DeviceFilterOptions, DeviceListFilters, Paginated } from '../types';
|
|
3
3
|
export declare class Devices {
|
|
4
4
|
private client;
|
|
5
5
|
constructor(client: HttpClient);
|
|
@@ -7,6 +7,37 @@ export declare class Devices {
|
|
|
7
7
|
* List all registered devices.
|
|
8
8
|
*/
|
|
9
9
|
list(): Promise<Device[]>;
|
|
10
|
+
/**
|
|
11
|
+
* List devices one page at a time, with filters. Unlike `list()`, this
|
|
12
|
+
* includes inactive (unregistered) devices unless you pass `isActive`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const { items, total } = await rivium.devices.listPage({ platform: 'web', sdkName: 'web', page: 1, limit: 50 });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
listPage(filters?: DeviceListFilters): Promise<Paginated<Device>>;
|
|
20
|
+
/**
|
|
21
|
+
* Distinct app versions, SDK name/version pairs and recent failure reasons,
|
|
22
|
+
* with counts — the values `listPage()` can filter on.
|
|
23
|
+
*/
|
|
24
|
+
filterOptions(): Promise<DeviceFilterOptions>;
|
|
25
|
+
/**
|
|
26
|
+
* Soft-unregister a device: it stops receiving sends but keeps its row and
|
|
27
|
+
* receipt history. The device is reactivated by `reactivate()` or by its
|
|
28
|
+
* SDK's next register(). Use `delete()` to remove it entirely.
|
|
29
|
+
*/
|
|
30
|
+
unregister(deviceId: string): Promise<{
|
|
31
|
+
deviceId: string;
|
|
32
|
+
isActive: false;
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Reactivate a soft-unregistered device.
|
|
36
|
+
*/
|
|
37
|
+
reactivate(deviceId: string): Promise<{
|
|
38
|
+
deviceId: string;
|
|
39
|
+
isActive: true;
|
|
40
|
+
}>;
|
|
10
41
|
/**
|
|
11
42
|
* Delete a device by its deviceId.
|
|
12
43
|
*/
|
package/dist/modules/devices.js
CHANGED
|
@@ -11,6 +11,41 @@ class Devices {
|
|
|
11
11
|
async list() {
|
|
12
12
|
return this.client.get('/devices');
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* List devices one page at a time, with filters. Unlike `list()`, this
|
|
16
|
+
* includes inactive (unregistered) devices unless you pass `isActive`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const { items, total } = await rivium.devices.listPage({ platform: 'web', sdkName: 'web', page: 1, limit: 50 });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
async listPage(filters = {}) {
|
|
24
|
+
const { page, limit, ...rest } = filters;
|
|
25
|
+
// The backend only paginates when page or limit is present.
|
|
26
|
+
return this.client.get('/devices', { page: page ?? 1, limit, ...rest });
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Distinct app versions, SDK name/version pairs and recent failure reasons,
|
|
30
|
+
* with counts — the values `listPage()` can filter on.
|
|
31
|
+
*/
|
|
32
|
+
async filterOptions() {
|
|
33
|
+
return this.client.get('/devices/filter-options');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Soft-unregister a device: it stops receiving sends but keeps its row and
|
|
37
|
+
* receipt history. The device is reactivated by `reactivate()` or by its
|
|
38
|
+
* SDK's next register(). Use `delete()` to remove it entirely.
|
|
39
|
+
*/
|
|
40
|
+
async unregister(deviceId) {
|
|
41
|
+
return this.client.post(`/devices/${encodeURIComponent(deviceId)}/unregister`);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Reactivate a soft-unregistered device.
|
|
45
|
+
*/
|
|
46
|
+
async reactivate(deviceId) {
|
|
47
|
+
return this.client.post(`/devices/${encodeURIComponent(deviceId)}/reactivate`);
|
|
48
|
+
}
|
|
14
49
|
/**
|
|
15
50
|
* Delete a device by its deviceId.
|
|
16
51
|
*/
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { HttpClient } from '../client';
|
|
2
|
+
import { DeliveryReceipt, MessageDeliveryStats, Paginated, ReceiptAnalytics, ReceiptAnalyticsOptions, ReceiptListFilters, ReceiptListItem } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Delivery receipts — what actually happened to a notification, per device.
|
|
5
|
+
*
|
|
6
|
+
* A send returns `success` / `failed`, but those count what the push service
|
|
7
|
+
* *accepted*: APNs, FCM and Web Push confirm acceptance, never delivery.
|
|
8
|
+
* Receipts carry the rest of the story — which device, over which transport,
|
|
9
|
+
* why it failed, and whether the device confirmed receipt.
|
|
10
|
+
*
|
|
11
|
+
* Receipts are written for targeted sends (`sendToUser`, `sendToDevices`).
|
|
12
|
+
* Broadcasts record an aggregated per-platform breakdown on the message
|
|
13
|
+
* instead, since a row per device does not scale to a large audience.
|
|
14
|
+
*/
|
|
15
|
+
export declare class Receipts {
|
|
16
|
+
private client;
|
|
17
|
+
constructor(client: HttpClient);
|
|
18
|
+
/**
|
|
19
|
+
* Get every receipt for a message.
|
|
20
|
+
*
|
|
21
|
+
* @param messageId `messageId` from the SendResult of the original send.
|
|
22
|
+
*/
|
|
23
|
+
getForMessage(messageId: string): Promise<DeliveryReceipt[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Get delivery/open/click rates for one message.
|
|
26
|
+
*/
|
|
27
|
+
getMessageStats(messageId: string): Promise<MessageDeliveryStats>;
|
|
28
|
+
/**
|
|
29
|
+
* Get click counts per notification action button for one message.
|
|
30
|
+
*/
|
|
31
|
+
getActionStats(messageId: string): Promise<{
|
|
32
|
+
actionId: string;
|
|
33
|
+
count: number;
|
|
34
|
+
}[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Get recent receipts for one device — useful for answering
|
|
37
|
+
* "did this user receive anything?".
|
|
38
|
+
*/
|
|
39
|
+
getForDevice(deviceId: string, limit?: number): Promise<DeliveryReceipt[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Get aggregate delivery stats for the project over a date range.
|
|
42
|
+
*/
|
|
43
|
+
getStats(startDate: Date | string, endDate: Date | string): Promise<MessageDeliveryStats>;
|
|
44
|
+
/**
|
|
45
|
+
* Page through the receipt log for your app, newest first. All filters are
|
|
46
|
+
* optional exact matches; `hasError: true` returns failures that carry a
|
|
47
|
+
* reason without you knowing the reason strings.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const { items, total } = await rivium.receipts.list({ platform: 'ios', status: 'failed', limit: 100 });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
list(filters?: ReceiptListFilters): Promise<Paginated<ReceiptListItem>>;
|
|
55
|
+
/**
|
|
56
|
+
* Delivery analytics for a date range (default: the last 30 days): totals,
|
|
57
|
+
* per-platform, per-transport and per-SDK-version breakdowns, a timeseries
|
|
58
|
+
* bucketed by day or hour, and the top failure reasons.
|
|
59
|
+
*/
|
|
60
|
+
analytics(options?: ReceiptAnalyticsOptions): Promise<ReceiptAnalytics>;
|
|
61
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Receipts = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Delivery receipts — what actually happened to a notification, per device.
|
|
6
|
+
*
|
|
7
|
+
* A send returns `success` / `failed`, but those count what the push service
|
|
8
|
+
* *accepted*: APNs, FCM and Web Push confirm acceptance, never delivery.
|
|
9
|
+
* Receipts carry the rest of the story — which device, over which transport,
|
|
10
|
+
* why it failed, and whether the device confirmed receipt.
|
|
11
|
+
*
|
|
12
|
+
* Receipts are written for targeted sends (`sendToUser`, `sendToDevices`).
|
|
13
|
+
* Broadcasts record an aggregated per-platform breakdown on the message
|
|
14
|
+
* instead, since a row per device does not scale to a large audience.
|
|
15
|
+
*/
|
|
16
|
+
class Receipts {
|
|
17
|
+
constructor(client) {
|
|
18
|
+
this.client = client;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get every receipt for a message.
|
|
22
|
+
*
|
|
23
|
+
* @param messageId `messageId` from the SendResult of the original send.
|
|
24
|
+
*/
|
|
25
|
+
async getForMessage(messageId) {
|
|
26
|
+
return this.client.get(`/receipts/message/${encodeURIComponent(messageId)}`);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get delivery/open/click rates for one message.
|
|
30
|
+
*/
|
|
31
|
+
async getMessageStats(messageId) {
|
|
32
|
+
return this.client.get(`/receipts/message/${encodeURIComponent(messageId)}/stats`);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get click counts per notification action button for one message.
|
|
36
|
+
*/
|
|
37
|
+
async getActionStats(messageId) {
|
|
38
|
+
return this.client.get(`/receipts/message/${encodeURIComponent(messageId)}/actions`);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get recent receipts for one device — useful for answering
|
|
42
|
+
* "did this user receive anything?".
|
|
43
|
+
*/
|
|
44
|
+
async getForDevice(deviceId, limit) {
|
|
45
|
+
return this.client.get(`/receipts/device/${encodeURIComponent(deviceId)}`, { limit });
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get aggregate delivery stats for the project over a date range.
|
|
49
|
+
*/
|
|
50
|
+
async getStats(startDate, endDate) {
|
|
51
|
+
return this.client.get('/receipts/stats', {
|
|
52
|
+
startDate: startDate instanceof Date ? startDate.toISOString() : startDate,
|
|
53
|
+
endDate: endDate instanceof Date ? endDate.toISOString() : endDate,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Page through the receipt log for your app, newest first. All filters are
|
|
58
|
+
* optional exact matches; `hasError: true` returns failures that carry a
|
|
59
|
+
* reason without you knowing the reason strings.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* const { items, total } = await rivium.receipts.list({ platform: 'ios', status: 'failed', limit: 100 });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
async list(filters = {}) {
|
|
67
|
+
return this.client.get('/receipts', { ...filters });
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Delivery analytics for a date range (default: the last 30 days): totals,
|
|
71
|
+
* per-platform, per-transport and per-SDK-version breakdowns, a timeseries
|
|
72
|
+
* bucketed by day or hour, and the top failure reasons.
|
|
73
|
+
*/
|
|
74
|
+
async analytics(options = {}) {
|
|
75
|
+
return this.client.get('/receipts/analytics', { ...options });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.Receipts = Receipts;
|
package/dist/types.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ export interface RiviumPushConfig {
|
|
|
4
4
|
/** Server secret for server-side authentication (rv_srv_xxx) - required for all server operations */
|
|
5
5
|
serverSecret: string;
|
|
6
6
|
}
|
|
7
|
+
/** Page-numbered list response. */
|
|
8
|
+
export interface Paginated<T> {
|
|
9
|
+
items: T[];
|
|
10
|
+
total: number;
|
|
11
|
+
page: number;
|
|
12
|
+
limit: number;
|
|
13
|
+
}
|
|
7
14
|
export interface PaginationParams {
|
|
8
15
|
limit?: number;
|
|
9
16
|
offset?: number;
|
|
@@ -17,6 +24,141 @@ export interface SendResult {
|
|
|
17
24
|
failed: number;
|
|
18
25
|
reason?: 'no_recipients';
|
|
19
26
|
billing?: BillingInfo;
|
|
27
|
+
/**
|
|
28
|
+
* Id of the message this send created. Use it to fetch delivery receipts
|
|
29
|
+
* later — `success` only means the push service accepted the notification,
|
|
30
|
+
* not that any device received it.
|
|
31
|
+
*/
|
|
32
|
+
messageId?: string;
|
|
33
|
+
}
|
|
34
|
+
/** Which transport carried a notification to a device. */
|
|
35
|
+
export type DeliveryTransport = 'apns' | 'voip' | 'webpush' | 'pn';
|
|
36
|
+
export type ReceiptStatus = 'sent' | 'delivered' | 'opened' | 'clicked' | 'failed' | 'dismissed';
|
|
37
|
+
export interface DeliveryReceipt {
|
|
38
|
+
id: string;
|
|
39
|
+
messageId: string;
|
|
40
|
+
deviceId: string;
|
|
41
|
+
userId?: string;
|
|
42
|
+
platform?: string;
|
|
43
|
+
/** `sent` = accepted by the transport; `delivered` = confirmed by the device. */
|
|
44
|
+
status: ReceiptStatus;
|
|
45
|
+
transport?: DeliveryTransport;
|
|
46
|
+
/** The push service's own id — APNs `apns-id`. Quote it when escalating. */
|
|
47
|
+
providerMessageId?: string;
|
|
48
|
+
/** Failure reason, e.g. 'Unregistered', 'Gone', 'BadDeviceToken'. */
|
|
49
|
+
error?: string;
|
|
50
|
+
sentAt: string;
|
|
51
|
+
deliveredAt?: string;
|
|
52
|
+
openedAt?: string;
|
|
53
|
+
clickedAt?: string;
|
|
54
|
+
/** SDK that registered the device (send-time snapshot, device fallback). */
|
|
55
|
+
sdkName?: string | null;
|
|
56
|
+
sdkVersion?: string | null;
|
|
57
|
+
appVersion?: string | null;
|
|
58
|
+
}
|
|
59
|
+
/** One row of `receipts.list()`. */
|
|
60
|
+
export interface ReceiptListItem {
|
|
61
|
+
id: string;
|
|
62
|
+
messageId: string;
|
|
63
|
+
messageTitle: string;
|
|
64
|
+
deviceId: string;
|
|
65
|
+
userId: string | null;
|
|
66
|
+
status: ReceiptStatus;
|
|
67
|
+
platform: string | null;
|
|
68
|
+
transport: string | null;
|
|
69
|
+
providerMessageId: string | null;
|
|
70
|
+
error: string | null;
|
|
71
|
+
actionId: string | null;
|
|
72
|
+
sentAt: string;
|
|
73
|
+
deliveredAt: string | null;
|
|
74
|
+
openedAt: string | null;
|
|
75
|
+
clickedAt: string | null;
|
|
76
|
+
/** Send-time snapshot, falling back to the device's current values; null = unknown. */
|
|
77
|
+
sdkName: string | null;
|
|
78
|
+
sdkVersion: string | null;
|
|
79
|
+
appVersion: string | null;
|
|
80
|
+
}
|
|
81
|
+
export interface ReceiptListFilters {
|
|
82
|
+
/** 1-based page (default 1). */
|
|
83
|
+
page?: number;
|
|
84
|
+
/** Page size (default 50, max 200). */
|
|
85
|
+
limit?: number;
|
|
86
|
+
platform?: Platform;
|
|
87
|
+
status?: ReceiptStatus;
|
|
88
|
+
transport?: DeliveryTransport;
|
|
89
|
+
/** Exact failure reason, e.g. 'Unregistered'. */
|
|
90
|
+
error?: string;
|
|
91
|
+
/** true = only failed receipts with a reason; false = only without. */
|
|
92
|
+
hasError?: boolean;
|
|
93
|
+
userId?: string;
|
|
94
|
+
deviceId?: string;
|
|
95
|
+
messageId?: string;
|
|
96
|
+
startDate?: Date | string;
|
|
97
|
+
endDate?: Date | string;
|
|
98
|
+
}
|
|
99
|
+
export interface ReceiptCounts {
|
|
100
|
+
total: number;
|
|
101
|
+
sent: number;
|
|
102
|
+
delivered: number;
|
|
103
|
+
opened: number;
|
|
104
|
+
clicked: number;
|
|
105
|
+
failed: number;
|
|
106
|
+
/**
|
|
107
|
+
* Receipts the device itself acked. iOS can only confirm with a Notification
|
|
108
|
+
* Service Extension, so a low iOS delivery rate is expected without one.
|
|
109
|
+
*/
|
|
110
|
+
deliveryConfirmedCount: number;
|
|
111
|
+
deliveryRate: number;
|
|
112
|
+
openRate: number;
|
|
113
|
+
clickRate: number;
|
|
114
|
+
failureRate: number;
|
|
115
|
+
}
|
|
116
|
+
export interface ReceiptAnalyticsOptions {
|
|
117
|
+
/** Default: 30 days before endDate. */
|
|
118
|
+
startDate?: Date | string;
|
|
119
|
+
/** Default: now. */
|
|
120
|
+
endDate?: Date | string;
|
|
121
|
+
/** Default 'day'. */
|
|
122
|
+
bucket?: 'day' | 'hour';
|
|
123
|
+
}
|
|
124
|
+
export interface ReceiptAnalytics {
|
|
125
|
+
startDate: string;
|
|
126
|
+
endDate: string;
|
|
127
|
+
bucket: 'day' | 'hour';
|
|
128
|
+
totals: ReceiptCounts;
|
|
129
|
+
/** `needsNse` is true for iOS: background delivery is only confirmed with a Notification Service Extension. */
|
|
130
|
+
byPlatform: (ReceiptCounts & {
|
|
131
|
+
platform: string;
|
|
132
|
+
needsNse: boolean;
|
|
133
|
+
})[];
|
|
134
|
+
timeseries: (ReceiptCounts & {
|
|
135
|
+
bucket: string;
|
|
136
|
+
platform: string;
|
|
137
|
+
})[];
|
|
138
|
+
topFailureReasons: {
|
|
139
|
+
platform: string;
|
|
140
|
+
error: string;
|
|
141
|
+
count: number;
|
|
142
|
+
}[];
|
|
143
|
+
byTransport: (ReceiptCounts & {
|
|
144
|
+
transport: string;
|
|
145
|
+
})[];
|
|
146
|
+
/** 'unknown' when neither the receipt nor the device recorded an SDK. */
|
|
147
|
+
bySdkVersion: (ReceiptCounts & {
|
|
148
|
+
sdkName: string;
|
|
149
|
+
sdkVersion: string;
|
|
150
|
+
})[];
|
|
151
|
+
}
|
|
152
|
+
export interface MessageDeliveryStats {
|
|
153
|
+
total: number;
|
|
154
|
+
sent: number;
|
|
155
|
+
delivered: number;
|
|
156
|
+
opened: number;
|
|
157
|
+
clicked: number;
|
|
158
|
+
failed: number;
|
|
159
|
+
deliveryRate: number;
|
|
160
|
+
openRate: number;
|
|
161
|
+
clickRate: number;
|
|
20
162
|
}
|
|
21
163
|
export interface NotificationAction {
|
|
22
164
|
id: string;
|
|
@@ -81,7 +223,47 @@ export interface Device {
|
|
|
81
223
|
appIdentifier?: string;
|
|
82
224
|
userId?: string;
|
|
83
225
|
metadata?: Record<string, any>;
|
|
226
|
+
isActive?: boolean;
|
|
227
|
+
appVersion?: string | null;
|
|
228
|
+
/** SDK that last registered the device, e.g. 'web', 'ios', 'flutter'. */
|
|
229
|
+
sdkName?: string | null;
|
|
230
|
+
sdkVersion?: string | null;
|
|
84
231
|
createdAt: string;
|
|
232
|
+
/** Last registration/update; used as "last seen". */
|
|
233
|
+
updatedAt?: string;
|
|
234
|
+
}
|
|
235
|
+
export interface DeviceListFilters {
|
|
236
|
+
/** 1-based page (default 1). */
|
|
237
|
+
page?: number;
|
|
238
|
+
/** Page size (default 50, max 200). */
|
|
239
|
+
limit?: number;
|
|
240
|
+
platform?: Platform;
|
|
241
|
+
isActive?: boolean;
|
|
242
|
+
userId?: string;
|
|
243
|
+
appVersion?: string;
|
|
244
|
+
sdkName?: string;
|
|
245
|
+
sdkVersion?: string;
|
|
246
|
+
/** Substring match on deviceId or userId. */
|
|
247
|
+
search?: string;
|
|
248
|
+
lastSeenBefore?: Date | string;
|
|
249
|
+
lastSeenAfter?: Date | string;
|
|
250
|
+
/** The device's most recent receipt failure reason, e.g. 'Unregistered'. */
|
|
251
|
+
failureReason?: string;
|
|
252
|
+
}
|
|
253
|
+
export interface DeviceFilterOptions {
|
|
254
|
+
appVersions: {
|
|
255
|
+
appVersion: string;
|
|
256
|
+
count: number;
|
|
257
|
+
}[];
|
|
258
|
+
sdks: {
|
|
259
|
+
sdkName: string;
|
|
260
|
+
sdkVersion: string;
|
|
261
|
+
count: number;
|
|
262
|
+
}[];
|
|
263
|
+
failureReasons: {
|
|
264
|
+
error: string;
|
|
265
|
+
count: number;
|
|
266
|
+
}[];
|
|
85
267
|
}
|
|
86
268
|
export interface CreateTemplateOptions {
|
|
87
269
|
name: string;
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SDK_VERSION = exports.SDK_NAME = void 0;
|
|
4
|
+
// AUTO-GENERATED by scripts/gen-version.mjs from package.json. Do not edit.
|
|
5
|
+
exports.SDK_NAME = 'node';
|
|
6
|
+
exports.SDK_VERSION = '0.1.4';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rivium/push-node",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/Rivium-co/rivium-push-nodejs-sdk.git"
|
|
@@ -9,14 +9,16 @@
|
|
|
9
9
|
"bugs": {
|
|
10
10
|
"url": "https://github.com/Rivium-co/rivium-push-nodejs-sdk/issues"
|
|
11
11
|
},
|
|
12
|
-
"description": "RiviumPush Node.js SDK
|
|
12
|
+
"description": "RiviumPush Node.js SDK — server-side push notifications, inbox, in-app messages, and more",
|
|
13
13
|
"main": "dist/index.js",
|
|
14
14
|
"types": "dist/index.d.ts",
|
|
15
15
|
"files": [
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
+
"prebuild": "node scripts/gen-version.mjs",
|
|
19
20
|
"build": "tsc",
|
|
21
|
+
"test": "npm run build && node --test test/*.test.js",
|
|
20
22
|
"prepublishOnly": "npm run build"
|
|
21
23
|
},
|
|
22
24
|
"keywords": [
|