react-native-insider 8.1.0 → 9.0.0-nh
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 +89 -660
- package/RNInsider.podspec +33 -12
- package/android/build.gradle +16 -7
- package/android/src/main/java/com/useinsider/react/RNInsiderAppFrameViewManager.java +253 -0
- package/android/src/main/java/com/useinsider/react/RNInsiderModule.java +238 -178
- package/android/src/main/java/com/useinsider/react/RNInsiderPackage.java +5 -1
- package/android/src/main/java/com/useinsider/react/RNUtils.java +111 -0
- package/babel.config.js +4 -1
- package/index.d.ts +196 -161
- package/index.js +60 -11
- package/ios/RNInsider/RNInsider.m +245 -341
- package/ios/RNInsider/RNInsiderAppFrameView.h +33 -0
- package/ios/RNInsider/RNInsiderAppFrameView.mm +315 -0
- package/ios/RNInsider/RNNotificationHandler.h +4 -1
- package/ios/RNInsider/RNNotificationHandler.m +16 -18
- package/ios/RNInsider/RNUtils.h +2 -0
- package/ios/RNInsider/RNUtils.m +79 -0
- package/package.json +43 -12
- package/src/EventHandler.js +17 -0
- package/src/InsiderAppFrame.d.ts +45 -0
- package/src/InsiderAppFrame.js +265 -0
- package/src/InsiderAppFrameLogic.d.ts +35 -0
- package/src/InsiderAppFrameLogic.js +192 -0
- package/src/InsiderAppFrameStatus.d.ts +22 -0
- package/src/InsiderAppFrameStatus.js +35 -0
- package/src/InsiderAppFramesError.d.ts +25 -0
- package/src/InsiderAppFramesError.js +77 -0
- package/src/InsiderEvent.js +1 -0
- package/src/InsiderEvents.d.ts +93 -0
- package/src/InsiderEvents.js +124 -0
- package/src/InsiderIdentifier.js +1 -1
- package/src/InsiderUser.d.ts +3 -2
- package/src/InsiderUser.js +27 -0
- package/src/Util.js +2 -1
- package/src/specs/InsiderAppFrameNativeComponent.ts +54 -0
- package/.orbit-output/config/MASTER.md +0 -129
- package/.orbit-output/config/architecture/API_DOCS.md +0 -342
- package/.orbit-output/config/architecture/ARCHITECTURE.md +0 -209
- package/.orbit-output/config/architecture/CODE-CATALOG.md +0 -172
- package/.orbit-output/config/architecture/project.yaml +0 -138
- package/.orbit-output/config/automation/AUTOMATION-SETUP.md +0 -50
- package/.orbit-output/config/enforcement/ENFORCEMENT-RULES.md +0 -41
- package/.orbit-output/config/enforcement/validate.sh +0 -49
- package/.orbit-output/skills/custom/academy-doc-generator.md +0 -598
- package/android/.settings/org.eclipse.buildship.core.prefs +0 -13
- package/android/src/test/java/com/useinsider/react/RNInsiderModuleTest.java +0 -169
- package/docs/app-cards/app-cards_new.md +0 -569
- package/ios/RNInsiderTests/RNInsiderTriggerPushProcessTests.m +0 -91
package/README.md
CHANGED
|
@@ -1,710 +1,139 @@
|
|
|
1
1
|
# Insider ReactNative SDK
|
|
2
2
|
|
|
3
|
-
Official React Native SDK for [Insider](https://www.insiderone.com) - A single platform for building individualized, cross-channel customer experiences.
|
|
4
|
-
|
|
5
3
|
[](http://coverus.internal.dataforce/app/project/github/useinsider/react-native-insider)
|
|
6
4
|
[](https://www.npmjs.com/package/react-native-insider)
|
|
7
5
|
[](LICENSE)
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- **Smart Recommendations** - AI-powered personalized product recommendations
|
|
15
|
-
- **Message Center** - In-app messaging and notification management
|
|
16
|
-
- **Content Optimizer** - A/B testing and dynamic content optimization
|
|
17
|
-
- **Push Notifications** - Rich push notifications with deep linking support
|
|
18
|
-
- **In-App Messages** - Native in-app messaging with callback handlers
|
|
19
|
-
- **Geofencing** - Location-based targeting and triggers
|
|
20
|
-
- **GDPR Compliance** - Built-in consent management and privacy controls
|
|
21
|
-
- **TypeScript Support** - Full TypeScript definitions included
|
|
7
|
+
Official React Native SDK for the [Insider](https://www.insiderone.com) marketing
|
|
8
|
+
and growth platform. Wraps the native Insider SDK on Android and iOS and exposes
|
|
9
|
+
its features — user identification, event tracking, product and purchase events,
|
|
10
|
+
push notifications, smart recommendations, content optimizer, message center,
|
|
11
|
+
App Cards and App Frames — through a single `Insider` module with full TypeScript definitions.
|
|
22
12
|
|
|
23
13
|
## Installation
|
|
24
14
|
|
|
25
|
-
With npm:
|
|
26
|
-
|
|
27
15
|
```bash
|
|
28
16
|
npm install react-native-insider
|
|
29
17
|
```
|
|
30
18
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
yarn add react-native-insider
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### iOS
|
|
38
|
-
|
|
39
|
-
1. Install CocoaPods dependencies:
|
|
19
|
+
On iOS, install the pods afterwards:
|
|
40
20
|
|
|
41
21
|
```bash
|
|
42
|
-
cd ios && pod install
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
2. In your Xcode project, enable the following capabilities under **Signing & Capabilities**:
|
|
46
|
-
- **Push Notifications** (if you are using **InsiderMobileAdvancedNotification** SDK)
|
|
47
|
-
- **Location (Always and WhenInUse)** (if you are using **InsiderGeofence** SDK)
|
|
48
|
-
- **Background Modes**: `Remote notifications` and `Location updates`
|
|
49
|
-
|
|
50
|
-
3. For rich push notifications, add Notification Service Extension and Notification Content Extension targets to your iOS project. Add the following to your `Podfile`:
|
|
51
|
-
|
|
52
|
-
```ruby
|
|
53
|
-
target 'YourNotificationService' do
|
|
54
|
-
use_frameworks!
|
|
55
|
-
pod "InsiderMobileAdvancedNotification"
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
target 'YourNotificationContent' do
|
|
59
|
-
use_frameworks!
|
|
60
|
-
pod "InsiderMobileAdvancedNotification"
|
|
61
|
-
end
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Android Setup
|
|
65
|
-
|
|
66
|
-
1. Add the Insider Maven repository to your **project-level** `android/build.gradle`:
|
|
67
|
-
|
|
68
|
-
```gradle
|
|
69
|
-
allprojects {
|
|
70
|
-
repositories {
|
|
71
|
-
maven { url 'https://mobilesdk.useinsider.com/android' }
|
|
72
|
-
}
|
|
73
|
-
}
|
|
22
|
+
cd ios && pod install
|
|
74
23
|
```
|
|
75
24
|
|
|
76
|
-
|
|
25
|
+
## Platform requirements
|
|
77
26
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
```
|
|
27
|
+
| Platform | Minimum |
|
|
28
|
+
|----------|---------|
|
|
29
|
+
| React Native | `>=0.74` (autolinking) |
|
|
30
|
+
| React | `>=18` |
|
|
31
|
+
| Android | `minSdk 24`, `compileSdk 36` |
|
|
32
|
+
| iOS | deployment target `12.0` |
|
|
85
33
|
|
|
86
|
-
|
|
34
|
+
App Frames on iOS additionally needs React Native `>=0.77` with the New
|
|
35
|
+
Architecture enabled; the rest of the SDK works on `>=0.74`.
|
|
87
36
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
manifestPlaceholders = [partner: 'your_partner_name']
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
```
|
|
37
|
+
The Insider pods are pinned by the podspec, so no version has to be declared
|
|
38
|
+
in your `Podfile`. On Android the SDK pulls in Firebase Messaging, Google Play
|
|
39
|
+
Services location and Huawei HMS push as transitive dependencies.
|
|
95
40
|
|
|
96
|
-
|
|
41
|
+
Gradle and Xcode setup — the Insider Maven repository, the `partner`
|
|
42
|
+
manifest placeholder, App Groups and the notification service extensions — is
|
|
43
|
+
covered in the integration guide and the sample app linked below.
|
|
97
44
|
|
|
98
|
-
## Quick
|
|
45
|
+
## Quick start
|
|
99
46
|
|
|
100
47
|
```typescript
|
|
101
|
-
import React, { useEffect } from 'react';
|
|
102
48
|
import Insider from 'react-native-insider';
|
|
103
49
|
import InsiderCallbackType from 'react-native-insider/src/InsiderCallbackType';
|
|
104
50
|
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
Insider.setActiveForegroundPushView();
|
|
130
|
-
|
|
131
|
-
// Enable data collection
|
|
132
|
-
Insider.enableIDFACollection(true);
|
|
133
|
-
Insider.enableLocationCollection(true);
|
|
134
|
-
|
|
135
|
-
// Start geofencing
|
|
136
|
-
Insider.startTrackingGeofence();
|
|
137
|
-
}, []);
|
|
138
|
-
|
|
139
|
-
return <YourApp />;
|
|
51
|
+
function onInsiderCallback(type, data) {
|
|
52
|
+
switch (type) {
|
|
53
|
+
case InsiderCallbackType.NOTIFICATION_OPEN:
|
|
54
|
+
// Handle push tap.
|
|
55
|
+
break;
|
|
56
|
+
case InsiderCallbackType.INAPP_BUTTON_CLICK:
|
|
57
|
+
// Handle in-app button tap.
|
|
58
|
+
break;
|
|
59
|
+
case InsiderCallbackType.INAPP_SEEN:
|
|
60
|
+
// Handle in-app message displayed.
|
|
61
|
+
break;
|
|
62
|
+
case InsiderCallbackType.TEMP_STORE_PURCHASE:
|
|
63
|
+
// Handle temp store purchase.
|
|
64
|
+
break;
|
|
65
|
+
case InsiderCallbackType.TEMP_STORE_ADDED_TO_CART:
|
|
66
|
+
// Handle temp store add-to-cart.
|
|
67
|
+
break;
|
|
68
|
+
case InsiderCallbackType.TEMP_STORE_CUSTOM_ACTION:
|
|
69
|
+
// Handle temp store custom action.
|
|
70
|
+
break;
|
|
71
|
+
case InsiderCallbackType.SESSION_STARTED:
|
|
72
|
+
// Handle session start.
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
140
75
|
}
|
|
141
|
-
```
|
|
142
76
|
|
|
143
|
-
## API Reference
|
|
144
|
-
|
|
145
|
-
### Initialization
|
|
146
|
-
|
|
147
|
-
#### `init(partnerName, appGroup, callback)`
|
|
148
|
-
|
|
149
|
-
Initialize the Insider SDK with your partner name and callback handler.
|
|
150
|
-
|
|
151
|
-
```typescript
|
|
152
77
|
Insider.init(
|
|
153
|
-
'
|
|
154
|
-
'group.com.
|
|
155
|
-
|
|
156
|
-
// Handle callbacks
|
|
157
|
-
}
|
|
78
|
+
'YOUR_PARTNER_NAME',
|
|
79
|
+
'group.com.example.app', // iOS App Group; pass any value on Android.
|
|
80
|
+
onInsiderCallback,
|
|
158
81
|
);
|
|
159
|
-
```
|
|
160
82
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
83
|
+
// Identify the user.
|
|
84
|
+
Insider.getCurrentUser()
|
|
85
|
+
.setName('Ada')
|
|
86
|
+
.setEmail('ada@example.com')
|
|
87
|
+
.setEmailOptin(true);
|
|
165
88
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
Insider.initWithCustomEndpoint(
|
|
172
|
-
'your_partner_name',
|
|
173
|
-
'group.com.your.app',
|
|
174
|
-
'https://your-custom-endpoint.com',
|
|
175
|
-
(type, data) => {
|
|
176
|
-
// Handle callbacks
|
|
177
|
-
}
|
|
178
|
-
);
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### User Management
|
|
182
|
-
|
|
183
|
-
#### Get Current User
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
const user = Insider.getCurrentUser();
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
#### User Attributes
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
|
-
import InsiderGender from 'react-native-insider/src/InsiderGender';
|
|
193
|
-
|
|
194
|
-
user
|
|
195
|
-
.setName('John')
|
|
196
|
-
.setSurname('Doe')
|
|
197
|
-
.setAge(30)
|
|
198
|
-
.setGender(InsiderGender.Male) // Male: 0, Female: 1, Other: 2
|
|
199
|
-
.setBirthday(new Date('1990-01-01'))
|
|
200
|
-
.setEmail('john.doe@example.com')
|
|
201
|
-
.setPhoneNumber('+1234567890')
|
|
202
|
-
.setLanguage('en')
|
|
203
|
-
.setLocale('en_US');
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
#### Marketing Preferences
|
|
207
|
-
|
|
208
|
-
```typescript
|
|
209
|
-
user
|
|
210
|
-
.setEmailOptin(true)
|
|
211
|
-
.setSMSOptin(true)
|
|
212
|
-
.setPushOptin(true)
|
|
213
|
-
.setWhatsappOptin(true)
|
|
214
|
-
.setLocationOptin(true);
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
#### Custom Attributes
|
|
218
|
-
|
|
219
|
-
```typescript
|
|
220
|
-
user
|
|
221
|
-
.setCustomAttributeWithString('membership_level', 'gold')
|
|
222
|
-
.setCustomAttributeWithInt('loyalty_points', 1500)
|
|
223
|
-
.setCustomAttributeWithDouble('account_balance', 99.99)
|
|
224
|
-
.setCustomAttributeWithBoolean('is_premium', true)
|
|
225
|
-
.setCustomAttributeWithDate('last_purchase', new Date())
|
|
226
|
-
.setCustomAttributeWithArray('interests', ['sports', 'technology']);
|
|
227
|
-
|
|
228
|
-
// Remove a custom attribute
|
|
229
|
-
user.unsetCustomAttribute('membership_level');
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
#### Login/Logout
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
import InsiderIdentifier from 'react-native-insider/src/InsiderIdentifier';
|
|
236
|
-
|
|
237
|
-
// Login with identifiers
|
|
238
|
-
const identifiers = new InsiderIdentifier()
|
|
239
|
-
.addEmail('user@example.com')
|
|
240
|
-
.addPhoneNumber('+1234567890')
|
|
241
|
-
.addUserID('user123')
|
|
242
|
-
.addCustomIdentifier('custom_key', 'custom_value');
|
|
243
|
-
|
|
244
|
-
user.login(identifiers);
|
|
245
|
-
|
|
246
|
-
// Login with callback to get Insider ID
|
|
247
|
-
user.login(identifiers, (insiderID) => {
|
|
248
|
-
console.log('Insider ID:', insiderID);
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// Logout
|
|
252
|
-
user.logout();
|
|
253
|
-
|
|
254
|
-
// Sign-up confirmation
|
|
255
|
-
Insider.signUpConfirmation();
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### Event Tracking
|
|
259
|
-
|
|
260
|
-
```typescript
|
|
261
|
-
// Simple event
|
|
262
|
-
Insider.tagEvent('app_opened').build();
|
|
263
|
-
|
|
264
|
-
// Event with parameters
|
|
265
|
-
Insider.tagEvent('product_viewed')
|
|
266
|
-
.addParameterWithString('product_id', 'SKU123')
|
|
267
|
-
.addParameterWithString('category', 'Electronics')
|
|
268
|
-
.addParameterWithDouble('price', 299.99)
|
|
269
|
-
.addParameterWithInt('quantity', 1)
|
|
270
|
-
.addParameterWithBoolean('in_stock', true)
|
|
271
|
-
.addParameterWithDate('viewed_at', new Date())
|
|
272
|
-
.addParameterWithArray('tags', ['featured', 'sale'])
|
|
273
|
-
.addParameterWithStringArray('colors', ['red', 'blue'])
|
|
274
|
-
.addParameterWithNumericArray('ratings', [4.5, 5.0])
|
|
89
|
+
// Tag a custom event with typed parameters.
|
|
90
|
+
Insider.tagEvent('add_to_favorites')
|
|
91
|
+
.addParameterWithString('product_id', 'sku-123')
|
|
92
|
+
.addParameterWithDouble('price', 29.99)
|
|
275
93
|
.build();
|
|
276
94
|
```
|
|
277
95
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
#### Create a Product
|
|
281
|
-
|
|
282
|
-
```typescript
|
|
283
|
-
const product = Insider.createNewProduct(
|
|
284
|
-
'product_id', // Product ID
|
|
285
|
-
'Product Name', // Product name
|
|
286
|
-
['Category', 'Subcategory'], // Taxonomy (array)
|
|
287
|
-
'https://example.com/image.jpg', // Image URL
|
|
288
|
-
99.99, // Price
|
|
289
|
-
'USD' // Currency
|
|
290
|
-
);
|
|
291
|
-
|
|
292
|
-
// Add optional attributes
|
|
293
|
-
product
|
|
294
|
-
.setColor('Blue')
|
|
295
|
-
.setSize('M')
|
|
296
|
-
.setBrand('BrandName')
|
|
297
|
-
.setSalePrice(79.99)
|
|
298
|
-
.setStock(100)
|
|
299
|
-
.setQuantity(1)
|
|
300
|
-
.setSku('SKU-123')
|
|
301
|
-
.setVoucherName('SUMMER2024')
|
|
302
|
-
.setVoucherDiscount(20)
|
|
303
|
-
.setPromotionName('Summer Sale')
|
|
304
|
-
.setPromotionDiscount(15)
|
|
305
|
-
.setShippingCost(5.99)
|
|
306
|
-
.setGender('Unisex')
|
|
307
|
-
.setDescription('Product description')
|
|
308
|
-
.setTags(['featured', 'bestseller'])
|
|
309
|
-
.setInStock(true);
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
#### Cart Operations
|
|
313
|
-
|
|
314
|
-
```typescript
|
|
315
|
-
// Add to cart
|
|
316
|
-
Insider.itemAddedToCart(product);
|
|
317
|
-
|
|
318
|
-
// Remove from cart
|
|
319
|
-
Insider.itemRemovedFromCart('product_id');
|
|
320
|
-
|
|
321
|
-
// Clear cart
|
|
322
|
-
Insider.cartCleared();
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
#### Wishlist Operations
|
|
326
|
-
|
|
327
|
-
```typescript
|
|
328
|
-
// Add to wishlist
|
|
329
|
-
Insider.itemAddedToWishlist(product);
|
|
330
|
-
|
|
331
|
-
// Remove from wishlist
|
|
332
|
-
Insider.itemRemovedFromWishlist('product_id');
|
|
333
|
-
|
|
334
|
-
// Clear wishlist
|
|
335
|
-
Insider.wishlistCleared();
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
#### Purchase
|
|
339
|
-
|
|
340
|
-
```typescript
|
|
341
|
-
Insider.itemPurchased('unique_sale_id_12345', product);
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### Page Visits
|
|
345
|
-
|
|
346
|
-
```typescript
|
|
347
|
-
// Home page
|
|
348
|
-
Insider.visitHomePage();
|
|
349
|
-
|
|
350
|
-
// Listing/Category page
|
|
351
|
-
Insider.visitListingPage(['Category', 'Subcategory']);
|
|
352
|
-
|
|
353
|
-
// Product detail page
|
|
354
|
-
Insider.visitProductDetailPage(product);
|
|
355
|
-
|
|
356
|
-
// Cart page with products
|
|
357
|
-
Insider.visitCartPage([product1, product2]);
|
|
358
|
-
|
|
359
|
-
// Wishlist page
|
|
360
|
-
Insider.visitWishlistPage([product1, product2]);
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
### Smart Recommendations
|
|
364
|
-
|
|
365
|
-
```typescript
|
|
366
|
-
// Basic recommendation
|
|
367
|
-
Insider.getSmartRecommendation(
|
|
368
|
-
12345, // Recommendation ID
|
|
369
|
-
'en_US', // Locale
|
|
370
|
-
'USD', // Currency
|
|
371
|
-
(recommendation) => {
|
|
372
|
-
console.log('Recommendations:', recommendation);
|
|
373
|
-
}
|
|
374
|
-
);
|
|
375
|
-
|
|
376
|
-
// Recommendation with product context
|
|
377
|
-
Insider.getSmartRecommendationWithProduct(
|
|
378
|
-
product, // Current product
|
|
379
|
-
12345, // Recommendation ID
|
|
380
|
-
'en_US', // Locale
|
|
381
|
-
(recommendation) => {
|
|
382
|
-
console.log('Related products:', recommendation);
|
|
383
|
-
}
|
|
384
|
-
);
|
|
385
|
-
|
|
386
|
-
// Recommendation with product IDs
|
|
387
|
-
Insider.getSmartRecommendationWithProductIDs(
|
|
388
|
-
['prod1', 'prod2'], // Product IDs array
|
|
389
|
-
12345, // Recommendation ID
|
|
390
|
-
'en_US', // Locale
|
|
391
|
-
'USD', // Currency
|
|
392
|
-
(recommendation) => {
|
|
393
|
-
console.log('Recommendations:', recommendation);
|
|
394
|
-
}
|
|
395
|
-
);
|
|
396
|
-
|
|
397
|
-
// Track recommendation click
|
|
398
|
-
Insider.clickSmartRecommendationProduct(12345, product);
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
### Message Center
|
|
96
|
+
TypeScript definitions for the full surface ship with the package
|
|
97
|
+
(`index.d.ts` and `src/*.d.ts`).
|
|
402
98
|
|
|
403
|
-
|
|
404
|
-
Insider.getMessageCenterData(
|
|
405
|
-
20, // Limit
|
|
406
|
-
new Date('2024-01-01'), // Start date
|
|
407
|
-
new Date(), // End date
|
|
408
|
-
(messages) => {
|
|
409
|
-
console.log('Messages:', messages);
|
|
410
|
-
}
|
|
411
|
-
);
|
|
412
|
-
```
|
|
99
|
+
### Multiple apps under one partner
|
|
413
100
|
|
|
414
|
-
|
|
101
|
+
If your partner account serves several apps, pass the app identifier Insider
|
|
102
|
+
gave you as the optional last argument (`appIdentifier`), so sessions and push targeting are
|
|
103
|
+
attributed to the right app:
|
|
415
104
|
|
|
416
105
|
```typescript
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
// Get string content
|
|
420
|
-
Insider.getContentStringWithName(
|
|
421
|
-
'variable_name',
|
|
422
|
-
'default_value',
|
|
423
|
-
ContentOptimizerDataType.Content, // Content: 0, Element: 1
|
|
424
|
-
(value) => {
|
|
425
|
-
console.log('Content:', value);
|
|
426
|
-
}
|
|
427
|
-
);
|
|
428
|
-
|
|
429
|
-
// Get boolean content
|
|
430
|
-
Insider.getContentBoolWithName(
|
|
431
|
-
'feature_enabled',
|
|
432
|
-
false,
|
|
433
|
-
ContentOptimizerDataType.Element,
|
|
434
|
-
(value) => {
|
|
435
|
-
console.log('Feature enabled:', value);
|
|
436
|
-
}
|
|
437
|
-
);
|
|
438
|
-
|
|
439
|
-
// Get integer content
|
|
440
|
-
Insider.getContentIntWithName(
|
|
441
|
-
'max_items',
|
|
442
|
-
10,
|
|
443
|
-
ContentOptimizerDataType.Content,
|
|
444
|
-
(value) => {
|
|
445
|
-
console.log('Max items:', value);
|
|
446
|
-
}
|
|
447
|
-
);
|
|
106
|
+
Insider.init('YOUR_PARTNER_NAME', 'group.com.example.app', onInsiderCallback, 'my_app');
|
|
448
107
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
'
|
|
452
|
-
'
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
console.log('Fresh content:', value);
|
|
456
|
-
}
|
|
108
|
+
Insider.initWithCustomEndpoint(
|
|
109
|
+
'YOUR_PARTNER_NAME',
|
|
110
|
+
'group.com.example.app',
|
|
111
|
+
'https://your.custom.endpoint',
|
|
112
|
+
onInsiderCallback,
|
|
113
|
+
'my_app',
|
|
457
114
|
);
|
|
458
115
|
```
|
|
459
116
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
// Handle foreground push
|
|
469
|
-
Insider.setForegroundPushCallback((notification) => {
|
|
470
|
-
console.log('Foreground push:', notification);
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
// Set active foreground push view
|
|
474
|
-
Insider.setActiveForegroundPushView();
|
|
475
|
-
|
|
476
|
-
// Enable IDFA collection
|
|
477
|
-
Insider.enableIDFACollection(true);
|
|
478
|
-
|
|
479
|
-
// Disable in-app message templates (iOS)
|
|
480
|
-
Insider.disableTemplatesForIOS();
|
|
481
|
-
|
|
482
|
-
// Re-enable templates (iOS)
|
|
483
|
-
Insider.reenableTemplatesForIOS();
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
#### Android Configuration
|
|
487
|
-
|
|
488
|
-
```typescript
|
|
489
|
-
// Set hybrid push token (Android only)
|
|
490
|
-
Insider.setHybridPushToken('your_fcm_token');
|
|
491
|
-
|
|
492
|
-
// Handle universal links (Android only)
|
|
493
|
-
Insider.handleUniversalLink('https://your-link.com/path');
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
#### General Push Methods
|
|
497
|
-
|
|
498
|
-
```typescript
|
|
499
|
-
// Handle notification manually
|
|
500
|
-
Insider.handleNotification(notificationData);
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
### In-App Messages
|
|
504
|
-
|
|
505
|
-
```typescript
|
|
506
|
-
// Remove current in-app message
|
|
507
|
-
Insider.removeInapp();
|
|
508
|
-
|
|
509
|
-
// Disable in-app messages
|
|
510
|
-
Insider.disableInAppMessages();
|
|
511
|
-
|
|
512
|
-
// Enable in-app messages
|
|
513
|
-
Insider.enableInAppMessages();
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
### Geofencing
|
|
517
|
-
|
|
518
|
-
```typescript
|
|
519
|
-
// Start tracking geofences
|
|
520
|
-
Insider.startTrackingGeofence();
|
|
521
|
-
|
|
522
|
-
// Allow background location updates (iOS)
|
|
523
|
-
Insider.setAllowsBackgroundLocationUpdates(true);
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
### GDPR & Privacy
|
|
527
|
-
|
|
528
|
-
```typescript
|
|
529
|
-
// Set GDPR consent
|
|
530
|
-
Insider.setGDPRConsent(true);
|
|
531
|
-
|
|
532
|
-
// Set mobile app access
|
|
533
|
-
Insider.setMobileAppAccess(true);
|
|
534
|
-
|
|
535
|
-
// Enable/disable data collection
|
|
536
|
-
Insider.enableLocationCollection(true);
|
|
537
|
-
Insider.enableIpCollection(true);
|
|
538
|
-
Insider.enableCarrierCollection(true);
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
### Insider ID
|
|
542
|
-
|
|
543
|
-
```typescript
|
|
544
|
-
// Get current Insider ID (returns a Promise)
|
|
545
|
-
const insiderID = await Insider.getInsiderID();
|
|
546
|
-
console.log('Insider ID:', insiderID);
|
|
547
|
-
|
|
548
|
-
// Listen for Insider ID changes
|
|
549
|
-
Insider.insiderIDListener((insiderID) => {
|
|
550
|
-
console.log('Insider ID updated:', insiderID);
|
|
551
|
-
});
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
### Miscellaneous
|
|
555
|
-
|
|
556
|
-
```typescript
|
|
557
|
-
// Show native app review dialog
|
|
558
|
-
Insider.showNativeAppReview();
|
|
559
|
-
|
|
560
|
-
// Reinitialize with new partner name
|
|
561
|
-
Insider.reinitWithPartnerName('new_partner_name');
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
## TypeScript Support
|
|
565
|
-
|
|
566
|
-
The SDK includes full TypeScript definitions:
|
|
567
|
-
|
|
568
|
-
```typescript
|
|
569
|
-
import Insider from 'react-native-insider';
|
|
570
|
-
import InsiderGender from 'react-native-insider/src/InsiderGender';
|
|
571
|
-
import InsiderIdentifier from 'react-native-insider/src/InsiderIdentifier';
|
|
572
|
-
import InsiderCallbackType from 'react-native-insider/src/InsiderCallbackType';
|
|
573
|
-
import ContentOptimizerDataType from 'react-native-insider/src/ContentOptimizerDataType';
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
## Enums
|
|
577
|
-
|
|
578
|
-
### InsiderGender
|
|
579
|
-
|
|
580
|
-
```typescript
|
|
581
|
-
InsiderGender.Male // 0
|
|
582
|
-
InsiderGender.Female // 1
|
|
583
|
-
InsiderGender.Other // 2
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
### InsiderCallbackType
|
|
587
|
-
|
|
588
|
-
```typescript
|
|
589
|
-
InsiderCallbackType.NOTIFICATION_OPEN // 0
|
|
590
|
-
InsiderCallbackType.INAPP_BUTTON_CLICK // 1
|
|
591
|
-
InsiderCallbackType.TEMP_STORE_PURCHASE // 2
|
|
592
|
-
InsiderCallbackType.TEMP_STORE_ADDED_TO_CART // 3
|
|
593
|
-
InsiderCallbackType.TEMP_STORE_CUSTOM_ACTION // 4
|
|
594
|
-
InsiderCallbackType.INAPP_SEEN // 5
|
|
595
|
-
InsiderCallbackType.SESSION_STARTED // 6
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
### ContentOptimizerDataType
|
|
599
|
-
|
|
600
|
-
```typescript
|
|
601
|
-
ContentOptimizerDataType.Content // 0
|
|
602
|
-
ContentOptimizerDataType.Element // 1
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
## Complete Example
|
|
606
|
-
|
|
607
|
-
```typescript
|
|
608
|
-
import React, { useEffect } from 'react';
|
|
609
|
-
import { Platform, Linking } from 'react-native';
|
|
610
|
-
import Insider from 'react-native-insider';
|
|
611
|
-
import InsiderGender from 'react-native-insider/src/InsiderGender';
|
|
612
|
-
import InsiderIdentifier from 'react-native-insider/src/InsiderIdentifier';
|
|
613
|
-
import InsiderCallbackType from 'react-native-insider/src/InsiderCallbackType';
|
|
614
|
-
|
|
615
|
-
function App() {
|
|
616
|
-
useEffect(() => {
|
|
617
|
-
// Initialize SDK
|
|
618
|
-
Insider.init('your_partner_name', 'group.com.your.app', (type, data) => {
|
|
619
|
-
switch(type) {
|
|
620
|
-
case InsiderCallbackType.NOTIFICATION_OPEN:
|
|
621
|
-
console.log('Notification clicked:', data);
|
|
622
|
-
break;
|
|
623
|
-
case InsiderCallbackType.INAPP_BUTTON_CLICK:
|
|
624
|
-
console.log('In-app button clicked:', data);
|
|
625
|
-
break;
|
|
626
|
-
case InsiderCallbackType.SESSION_STARTED:
|
|
627
|
-
console.log('Session started');
|
|
628
|
-
break;
|
|
629
|
-
}
|
|
630
|
-
});
|
|
631
|
-
|
|
632
|
-
// Configure SDK
|
|
633
|
-
Insider.registerWithQuietPermission(false);
|
|
634
|
-
Insider.setActiveForegroundPushView();
|
|
635
|
-
Insider.startTrackingGeofence();
|
|
636
|
-
Insider.enableIDFACollection(true);
|
|
637
|
-
Insider.enableLocationCollection(true);
|
|
638
|
-
|
|
639
|
-
// Handle deep links (Android)
|
|
640
|
-
if (Platform.OS === 'android') {
|
|
641
|
-
Linking.getInitialURL().then((url) => {
|
|
642
|
-
if (url) {
|
|
643
|
-
Insider.handleUniversalLink(url);
|
|
644
|
-
}
|
|
645
|
-
});
|
|
646
|
-
|
|
647
|
-
const urlListener = Linking.addEventListener('url', (event) => {
|
|
648
|
-
Insider.handleUniversalLink(event.url);
|
|
649
|
-
});
|
|
650
|
-
|
|
651
|
-
return () => urlListener.remove();
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
// Set up user
|
|
655
|
-
const user = Insider.getCurrentUser();
|
|
656
|
-
user
|
|
657
|
-
.setName('Jane')
|
|
658
|
-
.setEmail('jane@example.com')
|
|
659
|
-
.setAge(25)
|
|
660
|
-
.setGender(InsiderGender.Female);
|
|
661
|
-
|
|
662
|
-
// Login user
|
|
663
|
-
const identifiers = new InsiderIdentifier()
|
|
664
|
-
.addEmail('jane@example.com')
|
|
665
|
-
.addUserID('user_123');
|
|
666
|
-
user.login(identifiers);
|
|
667
|
-
|
|
668
|
-
// Track page visit
|
|
669
|
-
Insider.visitHomePage();
|
|
670
|
-
|
|
671
|
-
// Track custom event
|
|
672
|
-
Insider.tagEvent('app_opened')
|
|
673
|
-
.addParameterWithString('source', 'direct')
|
|
674
|
-
.addParameterWithDate('timestamp', new Date())
|
|
675
|
-
.build();
|
|
676
|
-
|
|
677
|
-
// Create and track product
|
|
678
|
-
const product = Insider.createNewProduct(
|
|
679
|
-
'SKU001',
|
|
680
|
-
'Premium T-Shirt',
|
|
681
|
-
['Clothing', 'T-Shirts'],
|
|
682
|
-
'https://example.com/tshirt.jpg',
|
|
683
|
-
29.99,
|
|
684
|
-
'USD'
|
|
685
|
-
);
|
|
686
|
-
|
|
687
|
-
product.setColor('Blue').setSize('M');
|
|
688
|
-
Insider.visitProductDetailPage(product);
|
|
689
|
-
}, []);
|
|
690
|
-
|
|
691
|
-
return <YourApp />;
|
|
692
|
-
}
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
## Requirements
|
|
117
|
+
- The identifier must match `^[a-z0-9][a-z0-9_]{0,49}$`. The native SDK
|
|
118
|
+
validates it: an invalid value is logged and ignored, and initialization
|
|
119
|
+
still completes.
|
|
120
|
+
- Omit it (or pass an empty string) to initialize without one; nothing about
|
|
121
|
+
your integration changes. A non-string value logs a warning and is ignored.
|
|
122
|
+
- `reinitWithPartnerName` clears the app identifier on both platforms when it
|
|
123
|
+
switches to a different partner name; the native SDK skips a reinit with the
|
|
124
|
+
same name, so the identifier is kept.
|
|
696
125
|
|
|
697
|
-
|
|
698
|
-
- iOS >= 11.0
|
|
699
|
-
- Android >= API 21 (Android 5.0)
|
|
126
|
+
## Documentation
|
|
700
127
|
|
|
701
|
-
|
|
128
|
+
- Integration guide: <https://academy.insiderone.com/docs/react-native-basic-sdk-setup>
|
|
129
|
+
- Changelog: <https://academy.insiderone.com/docs/react-native-changelogs>
|
|
130
|
+
- Sample app: <https://github.com/useinsider/ReactNativeDemo>
|
|
131
|
+
- Insider website: <https://insiderone.com/>
|
|
132
|
+
- Issue tracker: <https://github.com/useinsider/ReactNativeDemo/issues>
|
|
702
133
|
|
|
703
|
-
-
|
|
704
|
-
|
|
705
|
-
- **Issues**: [Report issues](https://github.com/useinsider/react-native-insider/issues)
|
|
706
|
-
- **Email**: Contact your Insider representative
|
|
134
|
+
For panel-side setup — partner name, campaign and placement configuration —
|
|
135
|
+
contact your Insider account manager.
|
|
707
136
|
|
|
708
137
|
## License
|
|
709
138
|
|
|
710
|
-
|
|
139
|
+
react-native-insider is released under the MIT License. See [LICENSE](LICENSE).
|