@rivium/push-node 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rivium
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,369 @@
1
+ # RiviumPush Node.js SDK
2
+
3
+ Server-side SDK for [RiviumPush](https://rivium.co) — push notifications, inbox, in-app messages, and more.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @rivium-push/node
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { RiviumPush } from '@rivium-push/node';
15
+
16
+ const riviumPush = new RiviumPush({
17
+ apiKey: 'rv_live_xxxxxxxxxxxxxxxxxxxxx',
18
+ serverSecret: 'rv_srv_xxxxxxxxxxxxxxxxxxxxx', // Required for server-side operations
19
+ });
20
+
21
+ // Send a push notification
22
+ await riviumPush.push.sendToUser({
23
+ userId: 'user-123',
24
+ title: 'Order Shipped',
25
+ body: 'Your order #1234 has been shipped!',
26
+ data: { orderId: '1234' },
27
+ });
28
+ ```
29
+
30
+ > **Note:** Both `apiKey` and `serverSecret` are required for all server-side SDK operations. You can find these credentials in your [Rivium Console](https://console.rivium.co) when you create a project.
31
+
32
+ ## Push Notifications
33
+
34
+ ```typescript
35
+ // Send to a specific device
36
+ await riviumPush.push.sendToDevice({
37
+ deviceId: 'device-uuid',
38
+ title: 'Hello',
39
+ body: 'Welcome to our app!',
40
+ });
41
+
42
+ // Send to a user (all their devices)
43
+ await riviumPush.push.sendToUser({
44
+ userId: 'user-123',
45
+ title: 'New Message',
46
+ body: 'You have a new message',
47
+ });
48
+
49
+ // Send to multiple devices
50
+ await riviumPush.push.sendToDevices({
51
+ deviceIds: ['device-1', 'device-2', 'device-3'],
52
+ title: 'Update Available',
53
+ body: 'A new version is available',
54
+ });
55
+
56
+ // Send to a topic (e.g., "promotions")
57
+ await riviumPush.push.sendToTopic({
58
+ topic: 'promotions',
59
+ title: 'Flash Sale!',
60
+ body: '50% off everything today only',
61
+ imageUrl: 'https://example.com/sale.jpg',
62
+ });
63
+
64
+ // Send to a segment
65
+ await riviumPush.push.sendToSegment({
66
+ segmentId: 'segment-uuid',
67
+ title: 'Exclusive Offer',
68
+ body: 'Just for our VIP customers',
69
+ });
70
+
71
+ // Broadcast to all devices
72
+ await riviumPush.push.broadcast({
73
+ title: 'App Update',
74
+ body: 'Check out the new features!',
75
+ });
76
+ ```
77
+
78
+ ### Rich Notifications
79
+
80
+ ```typescript
81
+ await riviumPush.push.sendToUser({
82
+ userId: 'user-123',
83
+ title: 'New Product',
84
+ body: 'Check out our latest arrival',
85
+ imageUrl: 'https://example.com/product.jpg',
86
+ actions: [
87
+ { id: 'buy', title: 'Buy Now', action: 'OPEN_PRODUCT' },
88
+ { id: 'later', title: 'Save for Later' },
89
+ ],
90
+ deepLink: 'myapp://product/123',
91
+ data: { productId: '123' },
92
+ });
93
+ ```
94
+
95
+ ### Using Templates
96
+
97
+ ```typescript
98
+ await riviumPush.push.sendToUser({
99
+ userId: 'user-123',
100
+ templateId: 'order-shipped-template',
101
+ templateVariables: {
102
+ orderNumber: '#1234',
103
+ trackingUrl: 'https://track.example.com/1234',
104
+ },
105
+ });
106
+ ```
107
+
108
+ ## Inbox Messages
109
+
110
+ ```typescript
111
+ // Send inbox message to a user
112
+ await riviumPush.inbox.sendToUser({
113
+ userId: 'user-123',
114
+ content: {
115
+ title: 'Welcome!',
116
+ body: 'Thanks for joining us.',
117
+ imageUrl: 'https://example.com/welcome.jpg',
118
+ deepLink: 'myapp://onboarding',
119
+ },
120
+ });
121
+
122
+ // Send to multiple users
123
+ await riviumPush.inbox.sendToUsers({
124
+ userIds: ['user-1', 'user-2', 'user-3'],
125
+ content: {
126
+ title: 'New Feature',
127
+ body: 'Check out our latest feature',
128
+ },
129
+ });
130
+
131
+ // Broadcast to all
132
+ await riviumPush.inbox.broadcast({
133
+ content: {
134
+ title: 'Holiday Sale',
135
+ body: 'Up to 70% off!',
136
+ },
137
+ expiresAt: '2025-12-31T23:59:59Z',
138
+ });
139
+ ```
140
+
141
+ ## Device Management
142
+
143
+ ```typescript
144
+ // List all devices
145
+ const devices = await riviumPush.devices.list();
146
+
147
+ // Subscribe a device to a topic
148
+ await riviumPush.devices.subscribeTopic('device-uuid', 'news');
149
+
150
+ // Unsubscribe from a topic
151
+ await riviumPush.devices.unsubscribeTopic('device-uuid', 'news');
152
+
153
+ // Associate device with a user
154
+ await riviumPush.devices.setUserId('device-uuid', 'user-123');
155
+
156
+ // Delete a device
157
+ await riviumPush.devices.delete('device-uuid');
158
+ ```
159
+
160
+ ## Templates
161
+
162
+ ```typescript
163
+ // Create a template
164
+ const template = await riviumPush.templates.create({
165
+ name: 'Order Shipped',
166
+ title: 'Your order {{orderNumber}} has shipped!',
167
+ body: 'Track your package: {{trackingUrl}}',
168
+ variables: ['orderNumber', 'trackingUrl'],
169
+ });
170
+
171
+ // List templates
172
+ const templates = await riviumPush.templates.list();
173
+
174
+ // Render a template (preview)
175
+ const rendered = await riviumPush.templates.render(template.id, {
176
+ orderNumber: '#1234',
177
+ trackingUrl: 'https://track.example.com/1234',
178
+ });
179
+ ```
180
+
181
+ ## Segments
182
+
183
+ ```typescript
184
+ // Create a segment
185
+ const segment = await riviumPush.segments.create({
186
+ name: 'VIP Customers',
187
+ description: 'Customers with more than 10 orders',
188
+ filters: [
189
+ { field: 'metadata.orders', operator: 'gt', value: 10 },
190
+ ],
191
+ });
192
+
193
+ // Get devices in a segment
194
+ const devices = await riviumPush.segments.getDevices(segment.id);
195
+
196
+ // Recalculate segment membership
197
+ await riviumPush.segments.recalculate(segment.id);
198
+ ```
199
+
200
+ ## Scheduled Messages
201
+
202
+ ```typescript
203
+ // Schedule a message
204
+ const scheduled = await riviumPush.scheduled.create({
205
+ title: 'Reminder',
206
+ body: 'Don\'t forget to complete your purchase!',
207
+ targetType: 'user',
208
+ targetValue: 'user-123',
209
+ scheduledAt: '2025-02-14T09:00:00Z',
210
+ timezone: 'America/New_York',
211
+ });
212
+
213
+ // List pending messages
214
+ const pending = await riviumPush.scheduled.listPending();
215
+
216
+ // Cancel a scheduled message
217
+ await riviumPush.scheduled.cancel(scheduled.id);
218
+ ```
219
+
220
+ ## Webhooks
221
+
222
+ ```typescript
223
+ // Create a webhook
224
+ const webhook = await riviumPush.webhooks.create({
225
+ name: 'Order Events',
226
+ url: 'https://example.com/webhooks/rivium-push',
227
+ events: ['message.delivered', 'message.opened', 'message.clicked'],
228
+ secret: 'my-secret-key',
229
+ });
230
+
231
+ // Test a webhook
232
+ await riviumPush.webhooks.test(webhook.id, 'message.opened');
233
+
234
+ // Get delivery logs
235
+ const logs = await riviumPush.webhooks.getLogs(webhook.id);
236
+ ```
237
+
238
+ ## Analytics
239
+
240
+ ```typescript
241
+ // Get overview stats
242
+ const overview = await riviumPush.analytics.getOverview();
243
+ console.log(`Delivery rate: ${overview.deliveryRate}%`);
244
+
245
+ // Get daily stats
246
+ const daily = await riviumPush.analytics.getDaily(30); // Last 30 days
247
+
248
+ // Get app stats
249
+ const stats = await riviumPush.analytics.getStats();
250
+ console.log(`Total devices: ${stats.totalDevices}`);
251
+ ```
252
+
253
+ ## A/B Testing
254
+
255
+ ```typescript
256
+ // Create an A/B test
257
+ const test = await riviumPush.abTesting.create({
258
+ appId: 'your-app-id',
259
+ name: 'Notification Copy Test',
260
+ variants: [
261
+ {
262
+ name: 'Control',
263
+ title: 'Check this out',
264
+ body: 'See what\'s new',
265
+ trafficPercentage: 50,
266
+ },
267
+ {
268
+ name: 'Urgency',
269
+ title: 'Don\'t miss out!',
270
+ body: 'Limited time offer',
271
+ trafficPercentage: 50,
272
+ },
273
+ ],
274
+ });
275
+
276
+ // Start the test
277
+ await riviumPush.abTesting.start(test.id);
278
+
279
+ // Get results
280
+ const results = await riviumPush.abTesting.getResults(test.id);
281
+ ```
282
+
283
+ ## In-App Messages
284
+
285
+ ```typescript
286
+ // Create an in-app message
287
+ const message = await riviumPush.inApp.create('your-app-id', {
288
+ name: 'Welcome Modal',
289
+ type: 'modal',
290
+ content: {
291
+ title: 'Welcome!',
292
+ body: 'Thanks for downloading our app',
293
+ imageUrl: 'https://example.com/welcome.jpg',
294
+ buttons: [
295
+ { id: 'start', text: 'Get Started', action: 'dismiss', style: 'primary' },
296
+ ],
297
+ },
298
+ triggerType: 'on_app_open',
299
+ maxImpressions: 1,
300
+ });
301
+
302
+ // Activate the message
303
+ await riviumPush.inApp.activate('your-app-id', message.id);
304
+ ```
305
+
306
+ ## Error Handling
307
+
308
+ ```typescript
309
+ import { RiviumPush, RiviumPushError } from '@rivium-push/node';
310
+
311
+ try {
312
+ await riviumPush.push.sendToUser({
313
+ userId: 'user-123',
314
+ title: 'Hello',
315
+ body: 'World',
316
+ });
317
+ } catch (error) {
318
+ if (error instanceof RiviumPushError) {
319
+ console.error(`Status: ${error.statusCode}`);
320
+ console.error(`Message: ${error.message}`);
321
+ console.error(`Response:`, error.response);
322
+ }
323
+ }
324
+ ```
325
+
326
+ ## Configuration
327
+
328
+ ```typescript
329
+ const riviumPush = new RiviumPush({
330
+ apiKey: 'rv_live_xxxxxxxxxxxxxxxxxxxxx', // Required - from Rivium Console
331
+ serverSecret: 'rv_srv_xxxxxxxxxxxxxxxxxxxxx', // Required - from Rivium Console
332
+ });
333
+ ```
334
+
335
+ ### Environment Variables
336
+
337
+ We recommend using environment variables to store your credentials:
338
+
339
+ ```typescript
340
+ const riviumPush = new RiviumPush({
341
+ apiKey: process.env.RIVIUM_API_KEY!,
342
+ serverSecret: process.env.RIVIUM_SERVER_SECRET!,
343
+ });
344
+ ```
345
+
346
+ ```bash
347
+ # .env
348
+ RIVIUM_API_KEY=rv_live_xxxxxxxxxxxxxxxxxxxxx
349
+ RIVIUM_SERVER_SECRET=rv_srv_xxxxxxxxxxxxxxxxxxxxx
350
+ ```
351
+
352
+ ### Credentials
353
+
354
+ | Credential | Format | Description |
355
+ |------------|--------|-------------|
356
+ | **API Key** | `rv_live_xxx` | Used for client-side SDKs (iOS, Android, Web) and server-side SDKs |
357
+ | **Server Secret** | `rv_srv_xxx` | **Required** for server-side operations. Never expose in client-side code. |
358
+
359
+ Both credentials are generated when you create a project in the [Rivium Console](https://console.rivium.co). Store them securely and never commit them to version control.
360
+
361
+ ## Links
362
+
363
+ - [Rivium Push](https://rivium.co/cloud/rivium-push) - Learn more about Rivium Push
364
+ - [Documentation](https://rivium.co/cloud/rivium-push/docs/quick-start) - Full documentation and guides
365
+ - [Rivium Console](https://console.rivium.co) - Manage your push notifications
366
+
367
+ ## License
368
+
369
+ MIT — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,18 @@
1
+ import { RiviumPushConfig } from './types';
2
+ export declare class HttpClient {
3
+ private apiKey;
4
+ private serverSecret;
5
+ private baseUrl;
6
+ constructor(config: RiviumPushConfig);
7
+ request<T>(method: string, path: string, body?: any, query?: Record<string, any>): Promise<T>;
8
+ get<T>(path: string, query?: Record<string, any>): Promise<T>;
9
+ post<T>(path: string, body?: any, query?: Record<string, any>): Promise<T>;
10
+ put<T>(path: string, body?: any, query?: Record<string, any>): Promise<T>;
11
+ patch<T>(path: string, body?: any): Promise<T>;
12
+ delete<T>(path: string, body?: any, query?: Record<string, any>): Promise<T>;
13
+ }
14
+ export declare class RiviumPushError extends Error {
15
+ statusCode: number;
16
+ response: any;
17
+ constructor(message: string, statusCode: number, response: any);
18
+ }
package/dist/client.js ADDED
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RiviumPushError = exports.HttpClient = void 0;
7
+ const https_1 = __importDefault(require("https"));
8
+ const http_1 = __importDefault(require("http"));
9
+ const BASE_URL = 'https://push-api.rivium.co';
10
+ class HttpClient {
11
+ constructor(config) {
12
+ if (!config.apiKey) {
13
+ throw new Error('RiviumPush: apiKey is required');
14
+ }
15
+ if (!config.serverSecret) {
16
+ throw new Error('RiviumPush: serverSecret is required for server-side operations');
17
+ }
18
+ this.apiKey = config.apiKey;
19
+ this.serverSecret = config.serverSecret;
20
+ this.baseUrl = BASE_URL;
21
+ }
22
+ async request(method, path, body, query) {
23
+ const url = new URL(path, this.baseUrl);
24
+ if (query) {
25
+ for (const [k, v] of Object.entries(query)) {
26
+ if (v !== undefined && v !== null) {
27
+ url.searchParams.set(k, String(v));
28
+ }
29
+ }
30
+ }
31
+ const payload = body ? JSON.stringify(body) : undefined;
32
+ const isHttps = url.protocol === 'https:';
33
+ const lib = isHttps ? https_1.default : http_1.default;
34
+ // Build headers
35
+ const headers = {
36
+ 'x-api-key': this.apiKey,
37
+ 'x-server-secret': this.serverSecret,
38
+ 'Content-Type': 'application/json',
39
+ };
40
+ if (payload) {
41
+ headers['Content-Length'] = Buffer.byteLength(payload);
42
+ }
43
+ return new Promise((resolve, reject) => {
44
+ const req = lib.request(url, {
45
+ method,
46
+ headers,
47
+ }, (res) => {
48
+ let data = '';
49
+ res.on('data', (chunk) => (data += chunk));
50
+ res.on('end', () => {
51
+ const statusCode = res.statusCode || 0;
52
+ let parsed;
53
+ try {
54
+ parsed = data ? JSON.parse(data) : {};
55
+ }
56
+ catch {
57
+ parsed = { message: data };
58
+ }
59
+ if (statusCode >= 200 && statusCode < 300) {
60
+ resolve(parsed);
61
+ }
62
+ else {
63
+ const err = new RiviumPushError(parsed.message || `Request failed with status ${statusCode}`, statusCode, parsed);
64
+ reject(err);
65
+ }
66
+ });
67
+ });
68
+ req.on('error', reject);
69
+ if (payload)
70
+ req.write(payload);
71
+ req.end();
72
+ });
73
+ }
74
+ get(path, query) {
75
+ return this.request('GET', path, undefined, query);
76
+ }
77
+ post(path, body, query) {
78
+ return this.request('POST', path, body, query);
79
+ }
80
+ put(path, body, query) {
81
+ return this.request('PUT', path, body, query);
82
+ }
83
+ patch(path, body) {
84
+ return this.request('PATCH', path, body);
85
+ }
86
+ delete(path, body, query) {
87
+ return this.request('DELETE', path, body, query);
88
+ }
89
+ }
90
+ exports.HttpClient = HttpClient;
91
+ class RiviumPushError extends Error {
92
+ constructor(message, statusCode, response) {
93
+ super(message);
94
+ this.name = 'RiviumPushError';
95
+ this.statusCode = statusCode;
96
+ this.response = response;
97
+ }
98
+ }
99
+ exports.RiviumPushError = RiviumPushError;
@@ -0,0 +1,37 @@
1
+ import { Push } from './modules/push';
2
+ import { Devices } from './modules/devices';
3
+ import { Templates } from './modules/templates';
4
+ import { Segments } from './modules/segments';
5
+ import { Scheduled } from './modules/scheduled';
6
+ import { Inbox } from './modules/inbox';
7
+ import { InApp } from './modules/in-app';
8
+ import { ABTesting } from './modules/ab-testing';
9
+ import { Webhooks } from './modules/webhooks';
10
+ import { Analytics } from './modules/analytics';
11
+ import { RiviumPushConfig } from './types';
12
+ export declare class RiviumPush {
13
+ private client;
14
+ /** Push notifications */
15
+ push: Push;
16
+ /** Device management */
17
+ devices: Devices;
18
+ /** Notification templates */
19
+ templates: Templates;
20
+ /** User segments */
21
+ segments: Segments;
22
+ /** Scheduled messages */
23
+ scheduled: Scheduled;
24
+ /** Inbox messages */
25
+ inbox: Inbox;
26
+ /** In-app messages */
27
+ inApp: InApp;
28
+ /** A/B testing */
29
+ abTesting: ABTesting;
30
+ /** Webhooks */
31
+ webhooks: Webhooks;
32
+ /** Analytics */
33
+ analytics: Analytics;
34
+ constructor(config: RiviumPushConfig);
35
+ }
36
+ export { RiviumPushError } from './client';
37
+ export * from './types';
package/dist/index.js ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.RiviumPushError = exports.RiviumPush = void 0;
18
+ const client_1 = require("./client");
19
+ const push_1 = require("./modules/push");
20
+ const devices_1 = require("./modules/devices");
21
+ const templates_1 = require("./modules/templates");
22
+ const segments_1 = require("./modules/segments");
23
+ const scheduled_1 = require("./modules/scheduled");
24
+ const inbox_1 = require("./modules/inbox");
25
+ const in_app_1 = require("./modules/in-app");
26
+ const ab_testing_1 = require("./modules/ab-testing");
27
+ const webhooks_1 = require("./modules/webhooks");
28
+ const analytics_1 = require("./modules/analytics");
29
+ class RiviumPush {
30
+ constructor(config) {
31
+ this.client = new client_1.HttpClient(config);
32
+ this.push = new push_1.Push(this.client);
33
+ this.devices = new devices_1.Devices(this.client);
34
+ this.templates = new templates_1.Templates(this.client);
35
+ this.segments = new segments_1.Segments(this.client);
36
+ this.scheduled = new scheduled_1.Scheduled(this.client);
37
+ this.inbox = new inbox_1.Inbox(this.client);
38
+ this.inApp = new in_app_1.InApp(this.client);
39
+ this.abTesting = new ab_testing_1.ABTesting(this.client);
40
+ this.webhooks = new webhooks_1.Webhooks(this.client);
41
+ this.analytics = new analytics_1.Analytics(this.client);
42
+ }
43
+ }
44
+ exports.RiviumPush = RiviumPush;
45
+ var client_2 = require("./client");
46
+ Object.defineProperty(exports, "RiviumPushError", { enumerable: true, get: function () { return client_2.RiviumPushError; } });
47
+ // Re-export types
48
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,59 @@
1
+ import { HttpClient } from '../client';
2
+ import { ABTest, CreateABTestOptions } from '../types';
3
+ export declare class ABTesting {
4
+ private client;
5
+ constructor(client: HttpClient);
6
+ /**
7
+ * Create a new A/B test.
8
+ */
9
+ create(options: CreateABTestOptions & {
10
+ appId: string;
11
+ }): Promise<ABTest>;
12
+ /**
13
+ * List all A/B tests for an app.
14
+ */
15
+ list(appId: string): Promise<ABTest[]>;
16
+ /**
17
+ * Get an A/B test by ID.
18
+ */
19
+ get(id: string): Promise<ABTest>;
20
+ /**
21
+ * Get results for an A/B test.
22
+ */
23
+ getResults(id: string): Promise<any>;
24
+ /**
25
+ * Start an A/B test.
26
+ */
27
+ start(id: string): Promise<ABTest>;
28
+ /**
29
+ * Pause an A/B test.
30
+ */
31
+ pause(id: string): Promise<ABTest>;
32
+ /**
33
+ * Complete an A/B test.
34
+ */
35
+ complete(id: string, winnerId?: string): Promise<ABTest>;
36
+ /**
37
+ * Delete an A/B test.
38
+ */
39
+ delete(id: string): Promise<{
40
+ success: boolean;
41
+ }>;
42
+ /**
43
+ * Send an A/B test to targeted devices.
44
+ */
45
+ send(id: string): Promise<{
46
+ sent: number;
47
+ }>;
48
+ /**
49
+ * Calculate audience size for targeting options.
50
+ */
51
+ getAudienceSize(options: {
52
+ appId: string;
53
+ targetType?: string;
54
+ segmentId?: string;
55
+ targetPercentage?: number;
56
+ }): Promise<{
57
+ count: number;
58
+ }>;
59
+ }