@attentive-mobile/attentive-react-native-sdk 2.0.0-beta.4 → 2.0.0-beta.6

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.
Files changed (27) hide show
  1. package/README.md +146 -10
  2. package/android/build.gradle +4 -1
  3. package/android/src/main/AndroidManifest.xml +2 -0
  4. package/android/src/main/kotlin/com/attentivereactnativesdk/AttentiveNotificationStore.kt +60 -0
  5. package/android/src/main/kotlin/com/attentivereactnativesdk/AttentivePushHelper.kt +101 -0
  6. package/android/src/main/kotlin/com/attentivereactnativesdk/AttentiveReactNativeSdkModule.kt +192 -134
  7. package/android/src/test/kotlin/com/attentivereactnativesdk/AttentiveNotificationStoreTest.kt +103 -0
  8. package/ios/AttentiveReactNativeSdk.mm +49 -2
  9. package/ios/AttentiveReactNativeSdk.xcodeproj/project.xcworkspace/xcuserdata/zheref.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  10. package/ios/Bridging/ATTNNativeSDK.swift +35 -28
  11. package/lib/commonjs/NativeAttentiveReactNativeSdk.js +1 -1
  12. package/lib/commonjs/NativeAttentiveReactNativeSdk.js.map +1 -1
  13. package/lib/commonjs/eventTypes.js.map +1 -1
  14. package/lib/commonjs/index.js +64 -10
  15. package/lib/commonjs/index.js.map +1 -1
  16. package/lib/module/NativeAttentiveReactNativeSdk.js +2 -2
  17. package/lib/module/NativeAttentiveReactNativeSdk.js.map +1 -1
  18. package/lib/module/eventTypes.js.map +1 -1
  19. package/lib/module/index.js +64 -12
  20. package/lib/module/index.js.map +1 -1
  21. package/lib/typescript/NativeAttentiveReactNativeSdk.d.ts +21 -2
  22. package/lib/typescript/NativeAttentiveReactNativeSdk.d.ts.map +1 -1
  23. package/lib/typescript/index.d.ts +55 -10
  24. package/lib/typescript/index.d.ts.map +1 -1
  25. package/package.json +9 -4
  26. package/src/NativeAttentiveReactNativeSdk.ts +79 -53
  27. package/src/index.tsx +65 -11
@@ -1,4 +1,4 @@
1
- import type { TurboModule } from "react-native/Libraries/TurboModule/RCTExport";
1
+ import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport';
2
2
  export interface Spec extends TurboModule {
3
3
  initialize: (attentiveDomain: string, mode: string, skipFatigueOnCreatives: boolean, enableDebugger: boolean) => void;
4
4
  triggerCreative: (creativeId?: string) => void;
@@ -41,9 +41,17 @@ export interface Spec extends TurboModule {
41
41
  exportDebugLogs: () => Promise<string>;
42
42
  /**
43
43
  * Request push notification permission from the user.
44
- * iOS only - Android is a no-op.
44
+ * On iOS, triggers the system permission dialog.
45
+ * On Android 13+, requests POST_NOTIFICATIONS; on older versions, no-op.
45
46
  */
46
47
  registerForPushNotifications: () => void;
48
+ /**
49
+ * Get the current push notification authorization status.
50
+ * On Android, uses POST_NOTIFICATIONS (API 33+); on older versions returns 'authorized'.
51
+ * On iOS, use PushNotificationIOS.checkPermissions instead; this method is for Android parity.
52
+ * @returns Promise resolving to 'authorized' | 'denied' | 'notDetermined'
53
+ */
54
+ getPushAuthorizationStatus: () => Promise<string>;
47
55
  /**
48
56
  * Register the device token received from APNs (simple version without callback).
49
57
  * iOS only - Android is a no-op.
@@ -97,6 +105,17 @@ export interface Spec extends TurboModule {
97
105
  * @param authorizationStatus - Current push authorization status
98
106
  */
99
107
  handlePushOpen: (userInfo: Object, authorizationStatus: string) => void;
108
+ /**
109
+ * Returns the push notification payload that launched the app from a killed state
110
+ * (i.e. the user tapped a notification when the app was not running), then clears it
111
+ * so it is only delivered once.
112
+ *
113
+ * Android only — on iOS use `PushNotificationIOS.getInitialNotification()` instead.
114
+ *
115
+ * @returns Promise resolving to a notification data map, or null if the app was not
116
+ * launched from a push notification tap.
117
+ */
118
+ getInitialPushNotification: () => Promise<Object | null>;
100
119
  }
101
120
  declare const _default: Spec | null;
102
121
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"NativeAttentiveReactNativeSdk.d.ts","sourceRoot":"","sources":["../../src/NativeAttentiveReactNativeSdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8CAA8C,CAAC;AAGhF,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,UAAU,EAAE,CACV,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM,EACZ,sBAAsB,EAAE,OAAO,EAC/B,cAAc,EAAE,OAAO,KACpB,IAAI,CAAC;IACV,eAAe,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,CACR,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,iBAAiB,CAAC,EAAE,MAAM,KACvB,IAAI,CAAC;IACV,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,oBAAoB,EAAE,CACpB,KAAK,EAAE,KAAK,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,EACF,QAAQ,CAAC,EAAE,MAAM,KACd,IAAI,CAAC;IACV,sBAAsB,EAAE,CACtB,KAAK,EAAE,KAAK,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,EACF,QAAQ,CAAC,EAAE,MAAM,KACd,IAAI,CAAC;IACV,mBAAmB,EAAE,CACnB,KAAK,EAAE,KAAK,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,EACF,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,KAChB,IAAI,CAAC;IACV,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,0BAA0B,EAAE,MAAM,IAAI,CAAC;IACvC,eAAe,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAGvC;;;OAGG;IACH,4BAA4B,EAAE,MAAM,IAAI,CAAC;IAEzC;;;;;OAKG;IACH,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1E;;;;;;;OAOG;IACH,+BAA+B,EAAE,CAC/B,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,KAC/E,IAAI,CAAC;IAEV;;;;;OAKG;IACH,iBAAiB,EAAE,CAAC,mBAAmB,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzD;;;;;;OAMG;IACH,gBAAgB,EAAE,CAChB,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,EACxB,mBAAmB,EAAE,MAAM,KACxB,IAAI,CAAC;IAEV;;;;OAIG;IACH,4BAA4B,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzD;;;;;;OAMG;IACH,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,KAAK,IAAI,CAAC;IAE9E;;;;;;OAMG;IACH,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,KAAK,IAAI,CAAC;CACzE;;AAUD,wBAA4D"}
1
+ {"version":3,"file":"NativeAttentiveReactNativeSdk.d.ts","sourceRoot":"","sources":["../../src/NativeAttentiveReactNativeSdk.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,11 @@
1
1
  import type { UserIdentifiers, AttentiveSdkConfiguration, ProductView, Purchase, AddToCart, CustomEvent, Item, PushAuthorizationStatus, ApplicationState, PushNotificationUserInfo, PushRegistrationResult } from './eventTypes';
2
2
  /**
3
- * Initialize the Attentive SDK with the provided configuration
3
+ * Initialize the Attentive SDK with the provided configuration.
4
+ * This is the only supported entry point: the app (e.g. Bonni) must call this from TypeScript
5
+ * once at startup; the call is forwarded to the native module on each platform (iOS/Android),
6
+ * which then initializes the platform Attentive SDK. Native code must not initialize the SDK
7
+ * on its own (e.g. in Application onCreate or AppDelegate).
8
+ *
4
9
  * @param configuration - Configuration object for the Attentive SDK
5
10
  */
6
11
  declare function initialize(configuration: AttentiveSdkConfiguration): void;
@@ -59,7 +64,7 @@ declare function exportDebugLogs(): Promise<string>;
59
64
  /**
60
65
  * Request push notification permission from the user.
61
66
  * On iOS, this will trigger the system permission dialog.
62
- * On Android, this is currently a no-op (TODO: implement FCM integration).
67
+ * On Android 13+, this requests POST_NOTIFICATIONS; on older versions, no-op.
63
68
  *
64
69
  * @example
65
70
  * ```typescript
@@ -70,12 +75,27 @@ declare function exportDebugLogs(): Promise<string>;
70
75
  * ```
71
76
  */
72
77
  declare function registerForPushNotifications(): void;
78
+ /**
79
+ * Get the current push notification authorization status.
80
+ * On Android, uses the SDK's native check (POST_NOTIFICATIONS on API 33+).
81
+ * On iOS, uses UNUserNotificationCenter notification settings.
82
+ *
83
+ * @returns Promise resolving to 'authorized' | 'denied' | 'notDetermined' (and on iOS possibly 'provisional' | 'ephemeral')
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * import { getPushAuthorizationStatus, handleRegularOpen } from 'attentive-react-native-sdk';
88
+ *
89
+ * getPushAuthorizationStatus().then((status) => handleRegularOpen(status));
90
+ * ```
91
+ */
92
+ declare function getPushAuthorizationStatus(): Promise<PushAuthorizationStatus>;
73
93
  /**
74
94
  * Register the device token received from APNs/FCM with the Attentive backend.
75
95
  * Call this from your AppDelegate's didRegisterForRemoteNotificationsWithDeviceToken.
76
96
  *
77
97
  * On iOS, the token should be the hex-encoded string representation of the device token Data.
78
- * On Android, this is currently a no-op (TODO: implement FCM integration).
98
+ * On Android, registers the FCM token when provided by the host app.
79
99
  *
80
100
  * @param token - The device token as a hex-encoded string
81
101
  * @param authorizationStatus - Current push authorization status
@@ -95,7 +115,7 @@ declare function registerDeviceToken(token: string, authorizationStatus: PushAut
95
115
  *
96
116
  * On iOS, this will register the device token with the Attentive SDK and invoke the callback
97
117
  * after the registration completes (success or failure).
98
- * On Android, this is currently a no-op (TODO: implement FCM integration).
118
+ * On Android, registers the FCM token when provided by the host app.
99
119
  *
100
120
  * @param token - The hex-encoded device token string from APNs
101
121
  * @param authorizationStatus - Current push authorization status
@@ -139,7 +159,7 @@ declare function registerDeviceTokenWithCallback(token: string, authorizationSta
139
159
  *
140
160
  * On iOS, this will notify the Attentive SDK that the app was opened directly
141
161
  * (not from a push notification tap).
142
- * On Android, this is currently a no-op (TODO: implement FCM integration).
162
+ * On Android, registers the FCM token when provided by the host app.
143
163
  *
144
164
  * @param authorizationStatus - Current push authorization status
145
165
  *
@@ -175,7 +195,7 @@ declare function handleRegularOpen(authorizationStatus: PushAuthorizationStatus)
175
195
  *
176
196
  * On iOS, this will track the push open event and handle the notification appropriately
177
197
  * based on whether the app was in the foreground, background, or not running.
178
- * On Android, this is currently a no-op (TODO: implement FCM integration).
198
+ * On Android, registers the FCM token when provided by the host app.
179
199
  *
180
200
  * @param userInfo - The notification payload from the push notification
181
201
  * @param applicationState - The app state when the notification was opened ('active', 'inactive', 'background')
@@ -199,7 +219,7 @@ declare function handlePushOpened(userInfo: PushNotificationUserInfo, applicatio
199
219
  * Call this from your notification handler when a notification is received while the app is active.
200
220
  *
201
221
  * On iOS, this allows the Attentive SDK to track the notification event.
202
- * On Android, this is currently a no-op (TODO: implement FCM integration).
222
+ * On Android, registers the FCM token when provided by the host app.
203
223
  *
204
224
  * @param userInfo - The notification payload from the push notification
205
225
  *
@@ -224,7 +244,7 @@ declare function handleForegroundNotification(userInfo: PushNotificationUserInfo
224
244
  * ```
225
245
  *
226
246
  * On iOS, this properly tracks foreground push notifications.
227
- * On Android, this is currently a no-op (TODO: implement FCM integration).
247
+ * On Android, registers the FCM token when provided by the host app.
228
248
  *
229
249
  * @param userInfo - The notification payload from the push notification
230
250
  * @param authorizationStatus - Current push authorization status
@@ -254,7 +274,7 @@ declare function handleForegroundPush(userInfo: PushNotificationUserInfo, author
254
274
  * ```
255
275
  *
256
276
  * On iOS, this properly tracks push notification opens.
257
- * On Android, this is currently a no-op (TODO: implement FCM integration).
277
+ * On Android, registers the FCM token when provided by the host app.
258
278
  *
259
279
  * @param userInfo - The notification payload from the push notification
260
280
  * @param authorizationStatus - Current push authorization status
@@ -272,6 +292,31 @@ declare function handleForegroundPush(userInfo: PushNotificationUserInfo, author
272
292
  * ```
273
293
  */
274
294
  declare function handlePushOpen(userInfo: PushNotificationUserInfo, authorizationStatus: PushAuthorizationStatus): void;
275
- export { initialize, triggerCreative, destroyCreative, updateDomain, identify, clearUser, recordAddToCartEvent, recordProductViewEvent, recordPurchaseEvent, recordCustomEvent, invokeAttentiveDebugHelper, exportDebugLogs, registerForPushNotifications, registerDeviceToken, registerDeviceTokenWithCallback, handleRegularOpen, handlePushOpened, handleForegroundNotification, handleForegroundPush, handlePushOpen, };
295
+ /**
296
+ * Returns the push notification payload that launched the app from a killed state
297
+ * (i.e. the user tapped an FCM notification while the app was not running) and clears
298
+ * it so it is only delivered once.
299
+ *
300
+ * **Android only.** On iOS, use `PushNotificationIOS.getInitialNotification()` to
301
+ * achieve the same result — the Attentive iOS SDK event is tracked natively in
302
+ * `AppDelegate.userNotificationCenter(_:didReceive:withCompletionHandler:)` via
303
+ * `AttentiveSDKManager.shared`.
304
+ *
305
+ * Call this once at app startup (after `initialize()`) to detect and handle the
306
+ * killed-state push-open scenario:
307
+ *
308
+ * ```typescript
309
+ * const initial = await getInitialPushNotification()
310
+ * if (initial) {
311
+ * const authStatus = await getPushAuthorizationStatus()
312
+ * handlePushOpen(initial as PushNotificationUserInfo, authStatus)
313
+ * }
314
+ * ```
315
+ *
316
+ * @returns A promise that resolves to the notification data object, or `null` if the
317
+ * app was not launched via a push notification tap.
318
+ */
319
+ declare function getInitialPushNotification(): Promise<Record<string, string> | null>;
320
+ export { initialize, triggerCreative, destroyCreative, updateDomain, identify, clearUser, recordAddToCartEvent, recordProductViewEvent, recordPurchaseEvent, recordCustomEvent, invokeAttentiveDebugHelper, exportDebugLogs, registerForPushNotifications, getPushAuthorizationStatus, registerDeviceToken, registerDeviceTokenWithCallback, handleRegularOpen, handlePushOpened, handleForegroundNotification, handleForegroundPush, handlePushOpen, getInitialPushNotification, };
276
321
  export type { UserIdentifiers, AttentiveSdkConfiguration, ProductView, Purchase, AddToCart, CustomEvent, Item, PushAuthorizationStatus, ApplicationState, PushNotificationUserInfo, PushRegistrationResult, };
277
322
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@attentive-mobile/attentive-react-native-sdk",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.6",
4
4
  "description": "React Native Module for the Attentive SDK",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -48,7 +48,10 @@
48
48
  "ios",
49
49
  "android"
50
50
  ],
51
- "repository": "https://github.com/attentive-mobile/attentive-react-native-sdk",
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "git+https://github.com/attentive-mobile/attentive-react-native-sdk.git"
54
+ },
52
55
  "author": "Attentive <epd-accounts+npm@attentivemobile.com> (https://www.attentive.com)",
53
56
  "contributors": [
54
57
  "Wyatt Davis"
@@ -59,7 +62,8 @@
59
62
  },
60
63
  "homepage": "https://github.com/attentive-mobile/attentive-react-native-sdk#readme",
61
64
  "publishConfig": {
62
- "registry": "https://registry.npmjs.org/"
65
+ "registry": "https://registry.npmjs.org/",
66
+ "access": "public"
63
67
  },
64
68
  "devDependencies": {
65
69
  "@commitlint/config-conventional": "^17.0.2",
@@ -176,6 +180,7 @@
176
180
  }
177
181
  },
178
182
  "dependencies": {
179
- "@babel/runtime": "^7.27.0"
183
+ "@babel/runtime": "^7.27.0",
184
+ "metro-react-native-babel-preset": "^0.77.0"
180
185
  }
181
186
  }
@@ -1,5 +1,5 @@
1
- import type { TurboModule } from "react-native/Libraries/TurboModule/RCTExport";
2
- import { TurboModuleRegistry, NativeModules } from "react-native";
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,59 +18,68 @@ 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
- // Push Notification Methods (iOS only)
68
+ // Push Notification Methods
69
69
  /**
70
70
  * Request push notification permission from the user.
71
- * iOS only - Android is a no-op.
71
+ * On iOS, triggers the system permission dialog.
72
+ * On Android 13+, requests POST_NOTIFICATIONS; on older versions, no-op.
73
+ */
74
+ registerForPushNotifications: () => void
75
+
76
+ /**
77
+ * Get the current push notification authorization status.
78
+ * On Android, uses POST_NOTIFICATIONS (API 33+); on older versions returns 'authorized'.
79
+ * On iOS, use PushNotificationIOS.checkPermissions instead; this method is for Android parity.
80
+ * @returns Promise resolving to 'authorized' | 'denied' | 'notDetermined'
72
81
  */
73
- registerForPushNotifications: () => void;
82
+ getPushAuthorizationStatus: () => Promise<string>
74
83
 
75
84
  /**
76
85
  * Register the device token received from APNs (simple version without callback).
@@ -78,7 +87,7 @@ export interface Spec extends TurboModule {
78
87
  * @param token - The hex-encoded device token string
79
88
  * @param authorizationStatus - Current push authorization status
80
89
  */
81
- registerDeviceToken: (token: string, authorizationStatus: string) => void;
90
+ registerDeviceToken: (token: string, authorizationStatus: string) => void
82
91
 
83
92
  /**
84
93
  * Register the device token received from APNs with a callback.
@@ -91,8 +100,13 @@ export interface Spec extends TurboModule {
91
100
  registerDeviceTokenWithCallback: (
92
101
  token: string,
93
102
  authorizationStatus: string,
94
- callback: (data?: Object, url?: string, response?: Object, error?: Object) => void
95
- ) => void;
103
+ callback: (
104
+ data?: Object,
105
+ url?: string,
106
+ response?: Object,
107
+ error?: Object
108
+ ) => void
109
+ ) => void
96
110
 
97
111
  /**
98
112
  * Handle regular/direct app open (not from a push notification).
@@ -100,7 +114,7 @@ export interface Spec extends TurboModule {
100
114
  * This should be called after device token registration to track app opens.
101
115
  * @param authorizationStatus - Current push authorization status
102
116
  */
103
- handleRegularOpen: (authorizationStatus: string) => void;
117
+ handleRegularOpen: (authorizationStatus: string) => void
104
118
 
105
119
  /**
106
120
  * Handle when a push notification is opened by the user.
@@ -113,14 +127,14 @@ export interface Spec extends TurboModule {
113
127
  userInfo: Object,
114
128
  applicationState: string,
115
129
  authorizationStatus: string
116
- ) => void;
130
+ ) => void
117
131
 
118
132
  /**
119
133
  * Handle when a push notification arrives while the app is in foreground.
120
134
  * iOS only - Android is a no-op.
121
135
  * @param userInfo - The notification payload
122
136
  */
123
- handleForegroundNotification: (userInfo: Object) => void;
137
+ handleForegroundNotification: (userInfo: Object) => void
124
138
 
125
139
  /**
126
140
  * Handle a push notification when the app is in the foreground (active state).
@@ -129,7 +143,7 @@ export interface Spec extends TurboModule {
129
143
  * @param userInfo - The notification payload
130
144
  * @param authorizationStatus - Current push authorization status
131
145
  */
132
- handleForegroundPush: (userInfo: Object, authorizationStatus: string) => void;
146
+ handleForegroundPush: (userInfo: Object, authorizationStatus: string) => void
133
147
 
134
148
  /**
135
149
  * Handle when a push notification is opened by the user (app in background/inactive state).
@@ -138,15 +152,27 @@ export interface Spec extends TurboModule {
138
152
  * @param userInfo - The notification payload
139
153
  * @param authorizationStatus - Current push authorization status
140
154
  */
141
- 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>
142
168
  }
143
169
 
144
170
  // Try to load via TurboModule first (new architecture)
145
171
  // Fall back to NativeModules for old architecture
146
- const isTurboModuleEnabled = (global as any).__turboModuleProxy != null;
172
+ const isTurboModuleEnabled = (global as any).__turboModuleProxy != null
147
173
 
148
174
  const AttentiveReactNativeSdkModule = isTurboModuleEnabled
149
- ? TurboModuleRegistry.get<Spec>("AttentiveReactNativeSdk")
150
- : NativeModules.AttentiveReactNativeSdk;
175
+ ? TurboModuleRegistry.get<Spec>('AttentiveReactNativeSdk')
176
+ : NativeModules.AttentiveReactNativeSdk
151
177
 
152
- 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) {
@@ -149,13 +154,13 @@ function exportDebugLogs(): Promise<string> {
149
154
  }
150
155
 
151
156
  // =============================================================================
152
- // Push Notification Methods (iOS only - Android is no-op with TODO stubs)
157
+ // Push Notification Methods (iOS and Android)
153
158
  // =============================================================================
154
159
 
155
160
  /**
156
161
  * Request push notification permission from the user.
157
162
  * On iOS, this will trigger the system permission dialog.
158
- * On Android, this is currently a no-op (TODO: implement FCM integration).
163
+ * On Android 13+, this requests POST_NOTIFICATIONS; on older versions, no-op.
159
164
  *
160
165
  * @example
161
166
  * ```typescript
@@ -169,12 +174,30 @@ function registerForPushNotifications(): void {
169
174
  AttentiveReactNativeSdk.registerForPushNotifications()
170
175
  }
171
176
 
177
+ /**
178
+ * Get the current push notification authorization status.
179
+ * On Android, uses the SDK's native check (POST_NOTIFICATIONS on API 33+).
180
+ * On iOS, uses UNUserNotificationCenter notification settings.
181
+ *
182
+ * @returns Promise resolving to 'authorized' | 'denied' | 'notDetermined' (and on iOS possibly 'provisional' | 'ephemeral')
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * import { getPushAuthorizationStatus, handleRegularOpen } from 'attentive-react-native-sdk';
187
+ *
188
+ * getPushAuthorizationStatus().then((status) => handleRegularOpen(status));
189
+ * ```
190
+ */
191
+ function getPushAuthorizationStatus(): Promise<PushAuthorizationStatus> {
192
+ return AttentiveReactNativeSdk.getPushAuthorizationStatus() as Promise<PushAuthorizationStatus>
193
+ }
194
+
172
195
  /**
173
196
  * Register the device token received from APNs/FCM with the Attentive backend.
174
197
  * Call this from your AppDelegate's didRegisterForRemoteNotificationsWithDeviceToken.
175
198
  *
176
199
  * On iOS, the token should be the hex-encoded string representation of the device token Data.
177
- * On Android, this is currently a no-op (TODO: implement FCM integration).
200
+ * On Android, registers the FCM token when provided by the host app.
178
201
  *
179
202
  * @param token - The device token as a hex-encoded string
180
203
  * @param authorizationStatus - Current push authorization status
@@ -200,7 +223,7 @@ function registerDeviceToken(
200
223
  *
201
224
  * On iOS, this will register the device token with the Attentive SDK and invoke the callback
202
225
  * after the registration completes (success or failure).
203
- * On Android, this is currently a no-op (TODO: implement FCM integration).
226
+ * On Android, registers the FCM token when provided by the host app.
204
227
  *
205
228
  * @param token - The hex-encoded device token string from APNs
206
229
  * @param authorizationStatus - Current push authorization status
@@ -260,7 +283,7 @@ function registerDeviceTokenWithCallback(
260
283
  *
261
284
  * On iOS, this will notify the Attentive SDK that the app was opened directly
262
285
  * (not from a push notification tap).
263
- * On Android, this is currently a no-op (TODO: implement FCM integration).
286
+ * On Android, registers the FCM token when provided by the host app.
264
287
  *
265
288
  * @param authorizationStatus - Current push authorization status
266
289
  *
@@ -307,7 +330,7 @@ function handleRegularOpen(authorizationStatus: PushAuthorizationStatus): void {
307
330
  *
308
331
  * On iOS, this will track the push open event and handle the notification appropriately
309
332
  * based on whether the app was in the foreground, background, or not running.
310
- * On Android, this is currently a no-op (TODO: implement FCM integration).
333
+ * On Android, registers the FCM token when provided by the host app.
311
334
  *
312
335
  * @param userInfo - The notification payload from the push notification
313
336
  * @param applicationState - The app state when the notification was opened ('active', 'inactive', 'background')
@@ -342,7 +365,7 @@ function handlePushOpened(
342
365
  * Call this from your notification handler when a notification is received while the app is active.
343
366
  *
344
367
  * On iOS, this allows the Attentive SDK to track the notification event.
345
- * On Android, this is currently a no-op (TODO: implement FCM integration).
368
+ * On Android, registers the FCM token when provided by the host app.
346
369
  *
347
370
  * @param userInfo - The notification payload from the push notification
348
371
  *
@@ -372,7 +395,7 @@ function handleForegroundNotification(
372
395
  * ```
373
396
  *
374
397
  * On iOS, this properly tracks foreground push notifications.
375
- * On Android, this is currently a no-op (TODO: implement FCM integration).
398
+ * On Android, registers the FCM token when provided by the host app.
376
399
  *
377
400
  * @param userInfo - The notification payload from the push notification
378
401
  * @param authorizationStatus - Current push authorization status
@@ -411,7 +434,7 @@ function handleForegroundPush(
411
434
  * ```
412
435
  *
413
436
  * On iOS, this properly tracks push notification opens.
414
- * On Android, this is currently a no-op (TODO: implement FCM integration).
437
+ * On Android, registers the FCM token when provided by the host app.
415
438
  *
416
439
  * @param userInfo - The notification payload from the push notification
417
440
  * @param authorizationStatus - Current push authorization status
@@ -438,6 +461,35 @@ function handlePushOpen(
438
461
  )
439
462
  }
440
463
 
464
+ /**
465
+ * Returns the push notification payload that launched the app from a killed state
466
+ * (i.e. the user tapped an FCM notification while the app was not running) and clears
467
+ * it so it is only delivered once.
468
+ *
469
+ * **Android only.** On iOS, use `PushNotificationIOS.getInitialNotification()` to
470
+ * achieve the same result — the Attentive iOS SDK event is tracked natively in
471
+ * `AppDelegate.userNotificationCenter(_:didReceive:withCompletionHandler:)` via
472
+ * `AttentiveSDKManager.shared`.
473
+ *
474
+ * Call this once at app startup (after `initialize()`) to detect and handle the
475
+ * killed-state push-open scenario:
476
+ *
477
+ * ```typescript
478
+ * const initial = await getInitialPushNotification()
479
+ * if (initial) {
480
+ * const authStatus = await getPushAuthorizationStatus()
481
+ * handlePushOpen(initial as PushNotificationUserInfo, authStatus)
482
+ * }
483
+ * ```
484
+ *
485
+ * @returns A promise that resolves to the notification data object, or `null` if the
486
+ * app was not launched via a push notification tap.
487
+ */
488
+ async function getInitialPushNotification(): Promise<Record<string, string> | null> {
489
+ const result = await AttentiveReactNativeSdk.getInitialPushNotification()
490
+ return result as Record<string, string> | null
491
+ }
492
+
441
493
  export {
442
494
  initialize,
443
495
  triggerCreative,
@@ -451,8 +503,9 @@ export {
451
503
  recordCustomEvent,
452
504
  invokeAttentiveDebugHelper,
453
505
  exportDebugLogs,
454
- // Push Notification Methods (iOS only)
506
+ // Push Notification Methods
455
507
  registerForPushNotifications,
508
+ getPushAuthorizationStatus,
456
509
  registerDeviceToken,
457
510
  registerDeviceTokenWithCallback,
458
511
  handleRegularOpen,
@@ -460,6 +513,7 @@ export {
460
513
  handleForegroundNotification,
461
514
  handleForegroundPush,
462
515
  handlePushOpen,
516
+ getInitialPushNotification,
463
517
  }
464
518
 
465
519
  export type {