@attentive-mobile/attentive-react-native-sdk 2.0.0-beta.5 → 2.0.0-beta.7
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 +117 -11
- package/android/build.gradle +4 -1
- package/android/src/main/kotlin/com/attentivereactnativesdk/AttentiveNotificationStore.kt +60 -0
- package/android/src/main/kotlin/com/attentivereactnativesdk/AttentivePushHelper.kt +15 -7
- package/android/src/main/kotlin/com/attentivereactnativesdk/AttentiveReactNativeSdkModule.kt +370 -140
- package/android/src/test/kotlin/com/attentivereactnativesdk/AttentiveNotificationStoreTest.kt +103 -0
- package/attentive-react-native-sdk.podspec +1 -1
- package/ios/AttentiveReactNativeSdk.mm +17 -2
- package/ios/AttentiveReactNativeSdk.xcodeproj/project.xcworkspace/xcuserdata/zheref.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Bridging/ATTNNativeSDK.swift +116 -46
- package/ios/Bridging/AttentiveSDKManager.swift +196 -27
- package/ios/Podfile +1 -1
- package/lib/commonjs/NativeAttentiveReactNativeSdk.js +1 -1
- package/lib/commonjs/NativeAttentiveReactNativeSdk.js.map +1 -1
- package/lib/commonjs/eventTypes.js.map +1 -1
- package/lib/commonjs/index.js +50 -17
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/NativeAttentiveReactNativeSdk.js +2 -2
- package/lib/module/NativeAttentiveReactNativeSdk.js.map +1 -1
- package/lib/module/eventTypes.js.map +1 -1
- package/lib/module/index.js +50 -18
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/NativeAttentiveReactNativeSdk.d.ts +12 -1
- package/lib/typescript/NativeAttentiveReactNativeSdk.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +46 -18
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/NativeAttentiveReactNativeSdk.ts +69 -52
- package/src/index.tsx +53 -17
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TurboModule } from
|
|
2
|
-
import { TurboModuleRegistry, NativeModules } from
|
|
1
|
+
import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport'
|
|
2
|
+
import { TurboModuleRegistry, NativeModules } from 'react-native'
|
|
3
3
|
|
|
4
4
|
export interface Spec extends TurboModule {
|
|
5
5
|
initialize: (
|
|
@@ -7,10 +7,10 @@ export interface Spec extends TurboModule {
|
|
|
7
7
|
mode: string,
|
|
8
8
|
skipFatigueOnCreatives: boolean,
|
|
9
9
|
enableDebugger: boolean
|
|
10
|
-
) => void
|
|
11
|
-
triggerCreative: (creativeId?: string) => void
|
|
12
|
-
destroyCreative: () => void
|
|
13
|
-
updateDomain: (domain: string) => void
|
|
10
|
+
) => void
|
|
11
|
+
triggerCreative: (creativeId?: string) => void
|
|
12
|
+
destroyCreative: () => void
|
|
13
|
+
updateDomain: (domain: string) => void
|
|
14
14
|
identify: (
|
|
15
15
|
phone?: string,
|
|
16
16
|
email?: string,
|
|
@@ -18,52 +18,52 @@ export interface Spec extends TurboModule {
|
|
|
18
18
|
shopifyId?: string,
|
|
19
19
|
clientUserId?: string,
|
|
20
20
|
customIdentifiers?: Object
|
|
21
|
-
) => void
|
|
22
|
-
clearUser: () => void
|
|
21
|
+
) => void
|
|
22
|
+
clearUser: () => void
|
|
23
23
|
recordAddToCartEvent: (
|
|
24
24
|
items: Array<{
|
|
25
|
-
productId: string
|
|
26
|
-
productVariantId: string
|
|
27
|
-
price: string
|
|
28
|
-
currency: string
|
|
29
|
-
productImage?: string
|
|
30
|
-
name?: string
|
|
31
|
-
quantity?: number
|
|
32
|
-
category?: string
|
|
25
|
+
productId: string
|
|
26
|
+
productVariantId: string
|
|
27
|
+
price: string
|
|
28
|
+
currency: string
|
|
29
|
+
productImage?: string
|
|
30
|
+
name?: string
|
|
31
|
+
quantity?: number
|
|
32
|
+
category?: string
|
|
33
33
|
}>,
|
|
34
34
|
deeplink?: string
|
|
35
|
-
) => void
|
|
35
|
+
) => void
|
|
36
36
|
recordProductViewEvent: (
|
|
37
37
|
items: Array<{
|
|
38
|
-
productId: string
|
|
39
|
-
productVariantId: string
|
|
40
|
-
price: string
|
|
41
|
-
currency: string
|
|
42
|
-
productImage?: string
|
|
43
|
-
name?: string
|
|
44
|
-
quantity?: number
|
|
45
|
-
category?: string
|
|
38
|
+
productId: string
|
|
39
|
+
productVariantId: string
|
|
40
|
+
price: string
|
|
41
|
+
currency: string
|
|
42
|
+
productImage?: string
|
|
43
|
+
name?: string
|
|
44
|
+
quantity?: number
|
|
45
|
+
category?: string
|
|
46
46
|
}>,
|
|
47
47
|
deeplink?: string
|
|
48
|
-
) => void
|
|
48
|
+
) => void
|
|
49
49
|
recordPurchaseEvent: (
|
|
50
50
|
items: Array<{
|
|
51
|
-
productId: string
|
|
52
|
-
productVariantId: string
|
|
53
|
-
price: string
|
|
54
|
-
currency: string
|
|
55
|
-
productImage?: string
|
|
56
|
-
name?: string
|
|
57
|
-
quantity?: number
|
|
58
|
-
category?: string
|
|
51
|
+
productId: string
|
|
52
|
+
productVariantId: string
|
|
53
|
+
price: string
|
|
54
|
+
currency: string
|
|
55
|
+
productImage?: string
|
|
56
|
+
name?: string
|
|
57
|
+
quantity?: number
|
|
58
|
+
category?: string
|
|
59
59
|
}>,
|
|
60
60
|
orderId: string,
|
|
61
61
|
cartId?: string,
|
|
62
62
|
cartCoupon?: string
|
|
63
|
-
) => void
|
|
64
|
-
recordCustomEvent: (type: string, properties: Object) => void
|
|
65
|
-
invokeAttentiveDebugHelper: () => void
|
|
66
|
-
exportDebugLogs: () => Promise<string
|
|
63
|
+
) => void
|
|
64
|
+
recordCustomEvent: (type: string, properties: Object) => void
|
|
65
|
+
invokeAttentiveDebugHelper: () => void
|
|
66
|
+
exportDebugLogs: () => Promise<string>
|
|
67
67
|
|
|
68
68
|
// Push Notification Methods
|
|
69
69
|
/**
|
|
@@ -71,7 +71,7 @@ export interface Spec extends TurboModule {
|
|
|
71
71
|
* On iOS, triggers the system permission dialog.
|
|
72
72
|
* On Android 13+, requests POST_NOTIFICATIONS; on older versions, no-op.
|
|
73
73
|
*/
|
|
74
|
-
registerForPushNotifications: () => void
|
|
74
|
+
registerForPushNotifications: () => void
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Get the current push notification authorization status.
|
|
@@ -79,7 +79,7 @@ export interface Spec extends TurboModule {
|
|
|
79
79
|
* On iOS, use PushNotificationIOS.checkPermissions instead; this method is for Android parity.
|
|
80
80
|
* @returns Promise resolving to 'authorized' | 'denied' | 'notDetermined'
|
|
81
81
|
*/
|
|
82
|
-
getPushAuthorizationStatus: () => Promise<string
|
|
82
|
+
getPushAuthorizationStatus: () => Promise<string>
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
85
|
* Register the device token received from APNs (simple version without callback).
|
|
@@ -87,7 +87,7 @@ export interface Spec extends TurboModule {
|
|
|
87
87
|
* @param token - The hex-encoded device token string
|
|
88
88
|
* @param authorizationStatus - Current push authorization status
|
|
89
89
|
*/
|
|
90
|
-
registerDeviceToken: (token: string, authorizationStatus: string) => void
|
|
90
|
+
registerDeviceToken: (token: string, authorizationStatus: string) => void
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
93
|
* Register the device token received from APNs with a callback.
|
|
@@ -100,8 +100,13 @@ export interface Spec extends TurboModule {
|
|
|
100
100
|
registerDeviceTokenWithCallback: (
|
|
101
101
|
token: string,
|
|
102
102
|
authorizationStatus: string,
|
|
103
|
-
callback: (
|
|
104
|
-
|
|
103
|
+
callback: (
|
|
104
|
+
data?: Object,
|
|
105
|
+
url?: string,
|
|
106
|
+
response?: Object,
|
|
107
|
+
error?: Object
|
|
108
|
+
) => void
|
|
109
|
+
) => void
|
|
105
110
|
|
|
106
111
|
/**
|
|
107
112
|
* Handle regular/direct app open (not from a push notification).
|
|
@@ -109,7 +114,7 @@ export interface Spec extends TurboModule {
|
|
|
109
114
|
* This should be called after device token registration to track app opens.
|
|
110
115
|
* @param authorizationStatus - Current push authorization status
|
|
111
116
|
*/
|
|
112
|
-
handleRegularOpen: (authorizationStatus: string) => void
|
|
117
|
+
handleRegularOpen: (authorizationStatus: string) => void
|
|
113
118
|
|
|
114
119
|
/**
|
|
115
120
|
* Handle when a push notification is opened by the user.
|
|
@@ -122,14 +127,14 @@ export interface Spec extends TurboModule {
|
|
|
122
127
|
userInfo: Object,
|
|
123
128
|
applicationState: string,
|
|
124
129
|
authorizationStatus: string
|
|
125
|
-
) => void
|
|
130
|
+
) => void
|
|
126
131
|
|
|
127
132
|
/**
|
|
128
133
|
* Handle when a push notification arrives while the app is in foreground.
|
|
129
134
|
* iOS only - Android is a no-op.
|
|
130
135
|
* @param userInfo - The notification payload
|
|
131
136
|
*/
|
|
132
|
-
handleForegroundNotification: (userInfo: Object) => void
|
|
137
|
+
handleForegroundNotification: (userInfo: Object) => void
|
|
133
138
|
|
|
134
139
|
/**
|
|
135
140
|
* Handle a push notification when the app is in the foreground (active state).
|
|
@@ -138,7 +143,7 @@ export interface Spec extends TurboModule {
|
|
|
138
143
|
* @param userInfo - The notification payload
|
|
139
144
|
* @param authorizationStatus - Current push authorization status
|
|
140
145
|
*/
|
|
141
|
-
handleForegroundPush: (userInfo: Object, authorizationStatus: string) => void
|
|
146
|
+
handleForegroundPush: (userInfo: Object, authorizationStatus: string) => void
|
|
142
147
|
|
|
143
148
|
/**
|
|
144
149
|
* Handle when a push notification is opened by the user (app in background/inactive state).
|
|
@@ -147,15 +152,27 @@ export interface Spec extends TurboModule {
|
|
|
147
152
|
* @param userInfo - The notification payload
|
|
148
153
|
* @param authorizationStatus - Current push authorization status
|
|
149
154
|
*/
|
|
150
|
-
handlePushOpen: (userInfo: Object, authorizationStatus: string) => void
|
|
155
|
+
handlePushOpen: (userInfo: Object, authorizationStatus: string) => void
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Returns the push notification payload that launched the app from a killed state
|
|
159
|
+
* (i.e. the user tapped a notification when the app was not running), then clears it
|
|
160
|
+
* so it is only delivered once.
|
|
161
|
+
*
|
|
162
|
+
* Android only — on iOS use `PushNotificationIOS.getInitialNotification()` instead.
|
|
163
|
+
*
|
|
164
|
+
* @returns Promise resolving to a notification data map, or null if the app was not
|
|
165
|
+
* launched from a push notification tap.
|
|
166
|
+
*/
|
|
167
|
+
getInitialPushNotification: () => Promise<Object | null>
|
|
151
168
|
}
|
|
152
169
|
|
|
153
170
|
// Try to load via TurboModule first (new architecture)
|
|
154
171
|
// Fall back to NativeModules for old architecture
|
|
155
|
-
const isTurboModuleEnabled = (global as any).__turboModuleProxy != null
|
|
172
|
+
const isTurboModuleEnabled = (global as any).__turboModuleProxy != null
|
|
156
173
|
|
|
157
174
|
const AttentiveReactNativeSdkModule = isTurboModuleEnabled
|
|
158
|
-
? TurboModuleRegistry.get<Spec>(
|
|
159
|
-
: NativeModules.AttentiveReactNativeSdk
|
|
175
|
+
? TurboModuleRegistry.get<Spec>('AttentiveReactNativeSdk')
|
|
176
|
+
: NativeModules.AttentiveReactNativeSdk
|
|
160
177
|
|
|
161
|
-
export default AttentiveReactNativeSdkModule as Spec | null
|
|
178
|
+
export default AttentiveReactNativeSdkModule as Spec | null
|
package/src/index.tsx
CHANGED
|
@@ -39,7 +39,12 @@ const AttentiveReactNativeSdk = (
|
|
|
39
39
|
) as Spec
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
* Initialize the Attentive SDK with the provided configuration
|
|
42
|
+
* Initialize the Attentive SDK with the provided configuration.
|
|
43
|
+
* This is the only supported entry point: the app (e.g. Bonni) must call this from TypeScript
|
|
44
|
+
* once at startup; the call is forwarded to the native module on each platform (iOS/Android),
|
|
45
|
+
* which then initializes the platform Attentive SDK. Native code must not initialize the SDK
|
|
46
|
+
* on its own (e.g. in Application onCreate or AppDelegate).
|
|
47
|
+
*
|
|
43
48
|
* @param configuration - Configuration object for the Attentive SDK
|
|
44
49
|
*/
|
|
45
50
|
function initialize(configuration: AttentiveSdkConfiguration) {
|
|
@@ -380,17 +385,16 @@ function handleForegroundNotification(
|
|
|
380
385
|
|
|
381
386
|
/**
|
|
382
387
|
* Handle a push notification when the app is in the foreground (active state).
|
|
383
|
-
* This is the React Native equivalent of the native iOS handleForegroundPush method.
|
|
384
388
|
*
|
|
385
389
|
* Call this when you receive a notification response and the app state is 'active'.
|
|
386
|
-
* This is part of implementing the native iOS pattern:
|
|
387
|
-
* ```swift
|
|
388
|
-
* case .active:
|
|
389
|
-
* self.attentiveSdk?.handleForegroundPush(response: response, authorizationStatus: authStatus)
|
|
390
|
-
* ```
|
|
391
390
|
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
391
|
+
* **iOS prerequisite:** Your AppDelegate's
|
|
392
|
+
* `userNotificationCenter(_:didReceive:withCompletionHandler:)` must call
|
|
393
|
+
* `AttentiveSDKManager.shared.handleNotificationResponse(response)` so that
|
|
394
|
+
* the SDK can cache the `UNNotificationResponse` required by the native iOS SDK.
|
|
395
|
+
* Without that one line of native code, this function cannot track the event.
|
|
396
|
+
*
|
|
397
|
+
* On Android, this tracks the foreground push as a custom event.
|
|
394
398
|
*
|
|
395
399
|
* @param userInfo - The notification payload from the push notification
|
|
396
400
|
* @param authorizationStatus - Current push authorization status
|
|
@@ -419,17 +423,16 @@ function handleForegroundPush(
|
|
|
419
423
|
|
|
420
424
|
/**
|
|
421
425
|
* Handle when a push notification is opened by the user (app in background/inactive state).
|
|
422
|
-
* This is the React Native equivalent of the native iOS handlePushOpen method.
|
|
423
426
|
*
|
|
424
427
|
* Call this when you receive a notification response and the app state is 'background' or 'inactive'.
|
|
425
|
-
* This is part of implementing the native iOS pattern:
|
|
426
|
-
* ```swift
|
|
427
|
-
* case .background, .inactive:
|
|
428
|
-
* self.attentiveSdk?.handlePushOpen(response: response, authorizationStatus: authStatus)
|
|
429
|
-
* ```
|
|
430
428
|
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
429
|
+
* **iOS prerequisite:** Your AppDelegate's
|
|
430
|
+
* `userNotificationCenter(_:didReceive:withCompletionHandler:)` must call
|
|
431
|
+
* `AttentiveSDKManager.shared.handleNotificationResponse(response)` so that
|
|
432
|
+
* the SDK can cache the `UNNotificationResponse` required by the native iOS SDK.
|
|
433
|
+
* Without that one line of native code, this function cannot track the event.
|
|
434
|
+
*
|
|
435
|
+
* On Android, this tracks the push open as a custom event.
|
|
433
436
|
*
|
|
434
437
|
* @param userInfo - The notification payload from the push notification
|
|
435
438
|
* @param authorizationStatus - Current push authorization status
|
|
@@ -456,6 +459,38 @@ function handlePushOpen(
|
|
|
456
459
|
)
|
|
457
460
|
}
|
|
458
461
|
|
|
462
|
+
/**
|
|
463
|
+
* Returns the push notification payload that launched the app from a killed state
|
|
464
|
+
* (i.e. the user tapped an FCM notification while the app was not running) and clears
|
|
465
|
+
* it so it is only delivered once.
|
|
466
|
+
*
|
|
467
|
+
* **Android only.** On iOS, use `PushNotificationIOS.getInitialNotification()` to
|
|
468
|
+
* achieve the same result — the Attentive iOS SDK event is tracked natively in
|
|
469
|
+
* `AppDelegate.userNotificationCenter(_:didReceive:withCompletionHandler:)` via
|
|
470
|
+
* `AttentiveSDKManager.shared`.
|
|
471
|
+
*
|
|
472
|
+
* Call this once at app startup (after `initialize()`) to detect and handle the
|
|
473
|
+
* killed-state push-open scenario:
|
|
474
|
+
*
|
|
475
|
+
* ```typescript
|
|
476
|
+
* const initial = await getInitialPushNotification()
|
|
477
|
+
* if (initial) {
|
|
478
|
+
* const authStatus = await getPushAuthorizationStatus()
|
|
479
|
+
* handlePushOpen(initial as PushNotificationUserInfo, authStatus)
|
|
480
|
+
* }
|
|
481
|
+
* ```
|
|
482
|
+
*
|
|
483
|
+
* @returns A promise that resolves to the notification data object, or `null` if the
|
|
484
|
+
* app was not launched via a push notification tap.
|
|
485
|
+
*/
|
|
486
|
+
async function getInitialPushNotification(): Promise<Record<
|
|
487
|
+
string,
|
|
488
|
+
string
|
|
489
|
+
> | null> {
|
|
490
|
+
const result = await AttentiveReactNativeSdk.getInitialPushNotification()
|
|
491
|
+
return result as Record<string, string> | null
|
|
492
|
+
}
|
|
493
|
+
|
|
459
494
|
export {
|
|
460
495
|
initialize,
|
|
461
496
|
triggerCreative,
|
|
@@ -479,6 +514,7 @@ export {
|
|
|
479
514
|
handleForegroundNotification,
|
|
480
515
|
handleForegroundPush,
|
|
481
516
|
handlePushOpen,
|
|
517
|
+
getInitialPushNotification,
|
|
482
518
|
}
|
|
483
519
|
|
|
484
520
|
export type {
|