cordova-plugin-reteno 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -4
- package/docs/android.md +19 -1
- package/docs/api.md +12 -4
- package/docs/ios.md +14 -8
- package/package.json +6 -3
- package/plugin.xml +2 -2
- package/src/android/app/build.gradle +2 -2
- package/src/android/app/src/main/java/com/reteno/plugin/RetenoPlugin.java +33 -5
- package/src/android/reteno.gradle +1 -1
- package/src/ios/RetenoPlugin.swift +34 -8
- package/types/index.ts +7 -0
- package/www/cordova-plugin-reteno.js +41 -33
package/README.md
CHANGED
|
@@ -4,12 +4,25 @@ Reteno SDK for Cordova and Capacitor apps.
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install cordova-plugin-reteno
|
|
9
|
+
```
|
|
9
10
|
|
|
10
|
-
##
|
|
11
|
+
## Documentation
|
|
11
12
|
|
|
12
|
-
- [
|
|
13
|
+
- [Cordova SDK Overview](https://docs.reteno.com/reference/cordova-sdk-setup)
|
|
14
|
+
- [Ionic SDK Overview](https://docs.reteno.com/reference/ionic-sdk)
|
|
15
|
+
|
|
16
|
+
### Setup Guides
|
|
17
|
+
|
|
18
|
+
- [Cordova iOS SDK Setup](https://docs.reteno.com/reference/cordova-ios-sdk-setup)
|
|
19
|
+
- [Cordova Android SDK Setup](https://docs.reteno.com/reference/cordova-android-sdk-setup)
|
|
20
|
+
- [Ionic iOS SDK Setup](https://docs.reteno.com/reference/ionic-ios-sdk-setup)
|
|
21
|
+
- [Ionic Android SDK Setup](https://docs.reteno.com/reference/ionic-ios-sdk-android)
|
|
22
|
+
|
|
23
|
+
### Additional
|
|
24
|
+
|
|
25
|
+
- [Release Notes](https://github.com/reteno-com/cordova-plugin-reteno/releases)
|
|
13
26
|
|
|
14
27
|
## License
|
|
15
28
|
|
package/docs/android.md
CHANGED
|
@@ -60,6 +60,24 @@ RetenoPlugin
|
|
|
60
60
|
});
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
For Android SDK `2.9.4+`, you can also configure session duration and split session lifecycle flags during init:
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
RetenoPlugin.init({
|
|
67
|
+
// Optional: session reset duration
|
|
68
|
+
sessionDurationSeconds: 30 * 60,
|
|
69
|
+
lifecycleTrackingOptions: {
|
|
70
|
+
appLifecycleEnabled: true,
|
|
71
|
+
// ApplicationForgrounded/ApplicationBackgrounded events (disabled by default in 2.9.4)
|
|
72
|
+
foregroundLifecycleEnabled: false,
|
|
73
|
+
pushSubscriptionEnabled: true,
|
|
74
|
+
// SessionStart/SessionEnd can now be managed separately
|
|
75
|
+
sessionStartEventsEnabled: true,
|
|
76
|
+
sessionEndEventsEnabled: false,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
63
81
|
If you need advanced Reteno configuration (custom `RetenoConfig`, custom device id provider, etc), you can initialize Reteno in your custom `Application` as described here:
|
|
64
82
|
[link](https://docs.reteno.com/reference/android-sdk-setup#step-4-initialize-the-reteno-sdk).
|
|
65
83
|
|
|
@@ -68,7 +86,7 @@ If you need advanced Reteno configuration (custom `RetenoConfig`, custom device
|
|
|
68
86
|
|
|
69
87
|
## Push notification listeners
|
|
70
88
|
|
|
71
|
-
The plugin uses the listener-based API (`EventListener` / `Procedure`) for all push events.
|
|
89
|
+
The plugin uses the listener-based API (`EventListener` / `Procedure`, Android SDK `2.9.4`) for all push events.
|
|
72
90
|
|
|
73
91
|
- `setOnRetenoPushDismissedListener(listener)` — called when a push notification is dismissed (swiped away).
|
|
74
92
|
- `setOnRetenoCustomPushReceivedListener(listener)` — called when a custom push notification is received.
|
package/docs/api.md
CHANGED
|
@@ -12,7 +12,7 @@ Notes:
|
|
|
12
12
|
|
|
13
13
|
| Method | Supported platform | Description |
|
|
14
14
|
| --- | --- | --- |
|
|
15
|
-
| [init](../www/cordova-plugin-reteno.js) | iOS, Android | Initializes Reteno SDK. Accepts optional `RetenoInitializeOptions` with `accessKey`, `pauseInAppMessages`, `pausePushInAppMessages`, `inAppMessagesPauseBehaviour` (iOS), `lifecycleTrackingOptions`, `isAutomaticScreenReportingEnabled` (iOS; see note below) and `isDebugMode`. [Types](../types/index.ts) |
|
|
15
|
+
| [init](../www/cordova-plugin-reteno.js) | iOS, Android | Initializes Reteno SDK. Accepts optional `RetenoInitializeOptions` with `accessKey`, `pauseInAppMessages`, `pausePushInAppMessages`, `inAppMessagesPauseBehaviour` (iOS), `lifecycleTrackingOptions`, `sessionDurationSeconds` (Android 2.9.4+, iOS 2.7.0+), `isAutomaticScreenReportingEnabled` (iOS; see note below) and `isDebugMode`. [Types](../types/index.ts) |
|
|
16
16
|
| [requestNotificationPermission](../www/cordova-plugin-reteno.js) | iOS, Android | Requests push permission (iOS) or `POST_NOTIFICATIONS` (Android 13+). Returns `0` or `1` on Android (`RequestNotificationPermissionResult`) in [types](../types/index.ts). |
|
|
17
17
|
| [setLifecycleTrackingOptions](../www/cordova-plugin-reteno.js) | iOS, Android | Configures automatic tracking for app lifecycle, push subscription, and session events. Android: applies immediately. iOS: supported only before initialization (stored and applied during `init(...)`). [Types](../types/index.ts) |
|
|
18
18
|
|
|
@@ -99,6 +99,7 @@ RetenoPlugin.init()
|
|
|
99
99
|
// pausePushInAppMessages: pauses in-app messages triggered by push notifications.
|
|
100
100
|
// inAppMessagesPauseBehaviour: (iOS) defines handling while paused: 'SKIP_IN_APPS' or 'POSTPONE_IN_APPS'.
|
|
101
101
|
// lifecycleTrackingOptions: configures app lifecycle, push subscription, and session event tracking ('ALL', 'NONE', or an object).
|
|
102
|
+
// sessionDurationSeconds (Android 2.9.4+, iOS 2.7.0+): optional session reset duration.
|
|
102
103
|
// isAutomaticScreenReportingEnabled: enables automatic native screen view tracking on iOS.
|
|
103
104
|
// Keep this false in Cordova/Ionic WebView apps (including Android demos).
|
|
104
105
|
// Defaults to false. Note: in Cordova/Ionic apps the UI runs inside a single WebView,
|
|
@@ -115,10 +116,13 @@ RetenoPlugin.init({
|
|
|
115
116
|
inAppMessagesPauseBehaviour: 'SKIP_IN_APPS', // iOS
|
|
116
117
|
isAutomaticScreenReportingEnabled: false, // keep false for hybrid/WebView apps
|
|
117
118
|
isDebugMode: true, // enables debug mode
|
|
119
|
+
sessionDurationSeconds: 30 * 60, // Android 2.9.4+, iOS 2.7.0+: 30 minutes
|
|
118
120
|
lifecycleTrackingOptions: {
|
|
119
121
|
appLifecycleEnabled: true,
|
|
122
|
+
foregroundLifecycleEnabled: false,
|
|
120
123
|
pushSubscriptionEnabled: true,
|
|
121
|
-
|
|
124
|
+
sessionStartEventsEnabled: true,
|
|
125
|
+
sessionEndEventsEnabled: false, // Android 2.9.4 default
|
|
122
126
|
},
|
|
123
127
|
})
|
|
124
128
|
.then(() => console.log('init: OK'))
|
|
@@ -129,6 +133,8 @@ RetenoPlugin.init({
|
|
|
129
133
|
// Shorthand lifecycle tracking values:
|
|
130
134
|
RetenoPlugin.init({ lifecycleTrackingOptions: 'ALL' });
|
|
131
135
|
RetenoPlugin.init({ lifecycleTrackingOptions: 'NONE' });
|
|
136
|
+
// Legacy alias (deprecated): sessionEventsEnabled controls both start/end at once.
|
|
137
|
+
RetenoPlugin.init({ lifecycleTrackingOptions: { sessionEventsEnabled: false } });
|
|
132
138
|
```
|
|
133
139
|
|
|
134
140
|
### setUserAttributes payload example
|
|
@@ -236,9 +242,11 @@ RetenoPlugin.setMultiAccountUserAttributes(
|
|
|
236
242
|
// Unspecified fields default to true.
|
|
237
243
|
// Android: applies immediately.
|
|
238
244
|
// iOS: this works only BEFORE SDK initialization (before calling init()).
|
|
245
|
+
// Deprecated: sessionEventsEnabled (if used) toggles both sessionStart and sessionEnd.
|
|
239
246
|
RetenoPlugin.setLifecycleTrackingOptions(
|
|
240
247
|
{
|
|
241
|
-
|
|
248
|
+
sessionStartEventsEnabled: true,
|
|
249
|
+
sessionEndEventsEnabled: true,
|
|
242
250
|
}
|
|
243
251
|
)
|
|
244
252
|
.then(() => console.log('setLifecycleTrackingOptions: OK'))
|
|
@@ -485,7 +493,7 @@ Subscribe to push received events while the app is running.
|
|
|
485
493
|
|
|
486
494
|
Notes:
|
|
487
495
|
|
|
488
|
-
- On Android this is based on the SDK 2.9.
|
|
496
|
+
- On Android this is based on the SDK 2.9.4 `EventListener` / `Procedure` API (`RetenoNotifications.getReceived()`).
|
|
489
497
|
- This listener is not a replacement for `getInitialNotification()` (cold start): if the app was launched by tapping a notification, use `getInitialNotification()`.
|
|
490
498
|
|
|
491
499
|
```js
|
package/docs/ios.md
CHANGED
|
@@ -68,12 +68,12 @@ target 'App' do
|
|
|
68
68
|
|
|
69
69
|
target 'NotificationServiceExtension' do
|
|
70
70
|
inherit! :search_paths
|
|
71
|
-
pod 'Reteno', '2.
|
|
71
|
+
pod 'Reteno', '2.7.0'
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
target 'NotificationContentExtension' do
|
|
75
75
|
inherit! :search_paths
|
|
76
|
-
pod 'Reteno', '2.
|
|
76
|
+
pod 'Reteno', '2.7.0'
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
```
|
|
@@ -187,12 +187,12 @@ target 'App' do
|
|
|
187
187
|
|
|
188
188
|
target 'NotificationServiceExtension' do
|
|
189
189
|
inherit! :search_paths
|
|
190
|
-
pod 'Reteno', '2.
|
|
190
|
+
pod 'Reteno', '2.7.0'
|
|
191
191
|
end
|
|
192
192
|
|
|
193
193
|
target 'NotificationContentExtension' do
|
|
194
194
|
inherit! :search_paths
|
|
195
|
-
pod 'Reteno', '2.
|
|
195
|
+
pod 'Reteno', '2.7.0'
|
|
196
196
|
end
|
|
197
197
|
end
|
|
198
198
|
```
|
|
@@ -458,12 +458,17 @@ Lifecycle tracking note for iOS:
|
|
|
458
458
|
- iOS lifecycle tracking is configured during SDK initialization (`RetenoPlugin.init({ lifecycleTrackingOptions: ... })`).
|
|
459
459
|
- Calling `setLifecycleTrackingOptions(...)` after initialization is not supported on iOS.
|
|
460
460
|
- `lifecycleTrackingOptions` accepts:
|
|
461
|
-
- `'ALL'` -> enables app lifecycle, push subscription, and session
|
|
462
|
-
- `'NONE'` -> disables
|
|
461
|
+
- `'ALL'` -> enables app lifecycle, foreground lifecycle (`ApplicationOpened`/`ApplicationBackgrounded`), push subscription, and session start/end tracking.
|
|
462
|
+
- `'NONE'` -> disables these automatic events.
|
|
463
463
|
- object:
|
|
464
464
|
- `appLifecycleEnabled`
|
|
465
|
+
- `foregroundLifecycleEnabled`
|
|
465
466
|
- `pushSubscriptionEnabled`
|
|
466
|
-
- `
|
|
467
|
+
- `sessionStartEventsEnabled`
|
|
468
|
+
- `sessionEndEventsEnabled`
|
|
469
|
+
- `sessionEventsEnabled` (legacy alias; deprecated)
|
|
470
|
+
- Session duration can be configured during `init(...)` via:
|
|
471
|
+
- `sessionDurationSeconds`
|
|
467
472
|
|
|
468
473
|
## App Lifecycle Events (iOS)
|
|
469
474
|
|
|
@@ -479,7 +484,8 @@ When automatic tracking is enabled, the native iOS SDK can report these events:
|
|
|
479
484
|
Related automatic events controlled by the same init options:
|
|
480
485
|
|
|
481
486
|
- Push subscription status events (`pushSubscriptionEnabled`)
|
|
482
|
-
- Session events (`
|
|
487
|
+
- Session events (`sessionStartEventsEnabled` / `sessionEndEventsEnabled`)
|
|
488
|
+
- Foreground lifecycle events (`foregroundLifecycleEnabled`)
|
|
483
489
|
|
|
484
490
|
Screen view tracking:
|
|
485
491
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cordova-plugin-reteno",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "The Reteno Cordova Plugin for Mobile Customer Engagement and Analytics solutions",
|
|
5
5
|
"types": "./types/index.ts",
|
|
6
6
|
"files": [
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
"LICENSE*"
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
|
+
"test": "jest --coverage",
|
|
27
|
+
"test:watch": "jest --watch",
|
|
26
28
|
"lint": "eslint \"www/**/*.js\"",
|
|
27
29
|
"lint:fix": "eslint --fix \"www/**/*.js\"",
|
|
28
30
|
"format": "prettier --write \"{www,types,docs}/**/*.{js,ts,md,json,xml}\"",
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
},
|
|
40
42
|
"keywords": [
|
|
41
43
|
"ecosystem:cordova",
|
|
42
|
-
"cordova-android",
|
|
44
|
+
"cordova-android",
|
|
43
45
|
"cordova-ios"
|
|
44
46
|
],
|
|
45
47
|
"author": "mobile-sdk@reteno.com",
|
|
@@ -49,11 +51,12 @@
|
|
|
49
51
|
},
|
|
50
52
|
"homepage": "https://github.com/reteno-com/cordova-plugin-reteno#readme",
|
|
51
53
|
"license": "MIT",
|
|
52
|
-
"dependencies": {},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@cordova/eslint-config": "^5.0.0",
|
|
55
56
|
"eslint": "^8.57.1",
|
|
56
57
|
"eslint-config-prettier": "^9.1.0",
|
|
58
|
+
"jest": "^30.3.0",
|
|
59
|
+
"jest-environment-jsdom": "^30.3.0",
|
|
57
60
|
"prettier": "^3.4.2",
|
|
58
61
|
"typescript": "^5.7.3"
|
|
59
62
|
}
|
package/plugin.xml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<?xml version='1.0' encoding='utf-8'?>
|
|
2
|
-
<plugin id="cordova-plugin-reteno" version="2.0.
|
|
2
|
+
<plugin id="cordova-plugin-reteno" version="2.0.4" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
|
|
3
3
|
<name>cordova-plugin-reteno</name>
|
|
4
4
|
<engines>
|
|
5
5
|
<engine name="cordova-android" version=">=12.0.0" />
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
|
|
59
59
|
<podspec>
|
|
60
60
|
<pods>
|
|
61
|
-
<pod name="Reteno" spec="2.
|
|
61
|
+
<pod name="Reteno" spec="2.7.0" />
|
|
62
62
|
<pod name="FirebaseMessaging" />
|
|
63
63
|
</pods>
|
|
64
64
|
</podspec>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
apply plugin: 'com.android.application'
|
|
2
2
|
|
|
3
|
-
def retenoFcmVersion = '2.9.
|
|
3
|
+
def retenoFcmVersion = '2.9.4'
|
|
4
4
|
|
|
5
5
|
android {
|
|
6
6
|
namespace 'com.reteno.plugin'
|
|
@@ -40,4 +40,4 @@ dependencies {
|
|
|
40
40
|
testImplementation 'junit:junit:4.13.2'
|
|
41
41
|
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
|
42
42
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
|
43
|
-
}
|
|
43
|
+
}
|
|
@@ -572,6 +572,13 @@ public class RetenoPlugin extends CordovaPlugin {
|
|
|
572
572
|
}
|
|
573
573
|
}
|
|
574
574
|
|
|
575
|
+
if (options != null && options.has("sessionDurationSeconds")) {
|
|
576
|
+
long sessionDurationSeconds = options.optLong("sessionDurationSeconds", -1L);
|
|
577
|
+
if (sessionDurationSeconds > 0L) {
|
|
578
|
+
builder.sessionDuration(sessionDurationSeconds * 1000L);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
575
582
|
// Ensure AndroidX Startup initializer has created the Reteno instance.
|
|
576
583
|
// We intentionally do not short-circuit initialization just because getInstance() is non-null;
|
|
577
584
|
// the SDK still needs to receive config (access key/debug/etc.).
|
|
@@ -601,7 +608,7 @@ public class RetenoPlugin extends CordovaPlugin {
|
|
|
601
608
|
}
|
|
602
609
|
|
|
603
610
|
/**
|
|
604
|
-
* Register notification event listeners using the SDK 2.9.
|
|
611
|
+
* Register notification event listeners using the SDK 2.9.4 EventListener API.
|
|
605
612
|
* Each listener is a direct {@link Procedure} implementation — no reflection needed.
|
|
606
613
|
*/
|
|
607
614
|
private void registerNotificationListeners() {
|
|
@@ -1145,10 +1152,10 @@ public class RetenoPlugin extends CordovaPlugin {
|
|
|
1145
1152
|
if (value instanceof String) {
|
|
1146
1153
|
String str = ((String) value).trim();
|
|
1147
1154
|
if ("ALL".equalsIgnoreCase(str)) {
|
|
1148
|
-
return new LifecycleTrackingOptions(true, true, true);
|
|
1155
|
+
return new LifecycleTrackingOptions(true, true, true, true, true);
|
|
1149
1156
|
}
|
|
1150
1157
|
if ("NONE".equalsIgnoreCase(str)) {
|
|
1151
|
-
return new LifecycleTrackingOptions(false, false, false);
|
|
1158
|
+
return new LifecycleTrackingOptions(false, false, false, false, false);
|
|
1152
1159
|
}
|
|
1153
1160
|
return null;
|
|
1154
1161
|
}
|
|
@@ -1158,13 +1165,34 @@ public class RetenoPlugin extends CordovaPlugin {
|
|
|
1158
1165
|
boolean appLifecycleEnabled = payload.has("appLifecycleEnabled")
|
|
1159
1166
|
? payload.optBoolean("appLifecycleEnabled", true)
|
|
1160
1167
|
: true;
|
|
1168
|
+
boolean foregroundLifecycleEnabled = payload.has("foregroundLifecycleEnabled")
|
|
1169
|
+
? payload.optBoolean("foregroundLifecycleEnabled", false)
|
|
1170
|
+
: false;
|
|
1161
1171
|
boolean pushSubscriptionEnabled = payload.has("pushSubscriptionEnabled")
|
|
1162
1172
|
? payload.optBoolean("pushSubscriptionEnabled", true)
|
|
1163
1173
|
: true;
|
|
1164
|
-
|
|
1174
|
+
|
|
1175
|
+
// Back-compat flag from <=2.9.2 plugin API.
|
|
1176
|
+
boolean legacySessionEventsEnabled = payload.has("sessionEventsEnabled")
|
|
1165
1177
|
? payload.optBoolean("sessionEventsEnabled", true)
|
|
1166
1178
|
: true;
|
|
1167
|
-
|
|
1179
|
+
|
|
1180
|
+
boolean sessionStartEventsEnabled = payload.has("sessionStartEventsEnabled")
|
|
1181
|
+
? payload.optBoolean("sessionStartEventsEnabled", legacySessionEventsEnabled)
|
|
1182
|
+
: legacySessionEventsEnabled;
|
|
1183
|
+
|
|
1184
|
+
// SDK 2.9.4 default for session end is disabled unless explicitly enabled.
|
|
1185
|
+
boolean sessionEndEventsEnabled = payload.has("sessionEndEventsEnabled")
|
|
1186
|
+
? payload.optBoolean("sessionEndEventsEnabled", false)
|
|
1187
|
+
: (payload.has("sessionEventsEnabled") ? legacySessionEventsEnabled : false);
|
|
1188
|
+
|
|
1189
|
+
return new LifecycleTrackingOptions(
|
|
1190
|
+
appLifecycleEnabled,
|
|
1191
|
+
foregroundLifecycleEnabled,
|
|
1192
|
+
pushSubscriptionEnabled,
|
|
1193
|
+
sessionStartEventsEnabled,
|
|
1194
|
+
sessionEndEventsEnabled
|
|
1195
|
+
);
|
|
1168
1196
|
}
|
|
1169
1197
|
|
|
1170
1198
|
return null;
|
|
@@ -69,13 +69,15 @@ class RetenoPlugin: CDVPlugin {
|
|
|
69
69
|
let lifecycleOptionsInput = options["lifecycleTrackingOptions"]
|
|
70
70
|
let lifecycleOptions: (
|
|
71
71
|
appLifecycleEnabled: Bool,
|
|
72
|
+
foregroundLifecycleEnabled: Bool,
|
|
72
73
|
pushSubscriptionEnabled: Bool,
|
|
73
|
-
|
|
74
|
+
sessionStartEventsEnabled: Bool,
|
|
75
|
+
sessionEndEventsEnabled: Bool
|
|
74
76
|
)?
|
|
75
77
|
if let lifecycleOptionsInput, !(lifecycleOptionsInput is NSNull) {
|
|
76
78
|
guard let parsedOptions = parseLifecycleTrackingOptions(lifecycleOptionsInput) else {
|
|
77
79
|
sendError(
|
|
78
|
-
"Invalid argument: lifecycleTrackingOptions. Expected 'ALL', 'NONE', or { appLifecycleEnabled, pushSubscriptionEnabled,
|
|
80
|
+
"Invalid argument: lifecycleTrackingOptions. Expected 'ALL', 'NONE', or { appLifecycleEnabled, foregroundLifecycleEnabled, pushSubscriptionEnabled, sessionStartEventsEnabled, sessionEndEventsEnabled }.",
|
|
79
81
|
to: command
|
|
80
82
|
)
|
|
81
83
|
return
|
|
@@ -85,8 +87,21 @@ class RetenoPlugin: CDVPlugin {
|
|
|
85
87
|
lifecycleOptions = nil
|
|
86
88
|
}
|
|
87
89
|
let lifecycleAppEnabled = lifecycleOptions?.appLifecycleEnabled ?? true
|
|
90
|
+
let lifecycleForegroundEnabled = lifecycleOptions?.foregroundLifecycleEnabled ?? false
|
|
88
91
|
let lifecyclePushEnabled = lifecycleOptions?.pushSubscriptionEnabled ?? true
|
|
89
|
-
let
|
|
92
|
+
let lifecycleSessionStartEnabled = lifecycleOptions?.sessionStartEventsEnabled ?? true
|
|
93
|
+
let lifecycleSessionEndEnabled = lifecycleOptions?.sessionEndEventsEnabled ?? false
|
|
94
|
+
|
|
95
|
+
let sessionDurationSeconds: TimeInterval = {
|
|
96
|
+
if let seconds = options["sessionDurationSeconds"] as? Double, seconds > 0 {
|
|
97
|
+
return seconds
|
|
98
|
+
}
|
|
99
|
+
if let seconds = options["sessionDurationSeconds"] as? Int, seconds > 0 {
|
|
100
|
+
return Double(seconds)
|
|
101
|
+
}
|
|
102
|
+
return RetenoSessionConfiguration.default.sessionDuration
|
|
103
|
+
}()
|
|
104
|
+
|
|
90
105
|
let screenReportingEnabled = (options["isAutomaticScreenReportingEnabled"] as? Bool) ?? false
|
|
91
106
|
let isDebugMode = (options["isDebugMode"] as? Bool) ?? false
|
|
92
107
|
|
|
@@ -101,8 +116,13 @@ class RetenoPlugin: CDVPlugin {
|
|
|
101
116
|
let configuration = RetenoConfiguration(
|
|
102
117
|
isAutomaticScreenReportingEnabled: screenReportingEnabled,
|
|
103
118
|
isAutomaticAppLifecycleReportingEnabled: lifecycleAppEnabled,
|
|
119
|
+
isApplicationForegroundLifecycleReportingEnabled: lifecycleForegroundEnabled,
|
|
104
120
|
isAutomaticPushSubsriptionReportingEnabled: lifecyclePushEnabled,
|
|
105
|
-
|
|
121
|
+
sessionConfiguration: RetenoSessionConfiguration(
|
|
122
|
+
sessionDuration: sessionDurationSeconds,
|
|
123
|
+
isSessionStartReportingEnabled: lifecycleSessionStartEnabled,
|
|
124
|
+
isSessionEndReportingEnabled: lifecycleSessionEndEnabled
|
|
125
|
+
),
|
|
106
126
|
isPausedInAppMessages: pauseInAppMessages,
|
|
107
127
|
inAppMessagesPauseBehaviour: inAppMessagesPauseBehaviour,
|
|
108
128
|
isDebugMode: isDebugMode,
|
|
@@ -1359,24 +1379,30 @@ class RetenoPlugin: CDVPlugin {
|
|
|
1359
1379
|
|
|
1360
1380
|
private func parseLifecycleTrackingOptions(_ value: Any?) -> (
|
|
1361
1381
|
appLifecycleEnabled: Bool,
|
|
1382
|
+
foregroundLifecycleEnabled: Bool,
|
|
1362
1383
|
pushSubscriptionEnabled: Bool,
|
|
1363
|
-
|
|
1384
|
+
sessionStartEventsEnabled: Bool,
|
|
1385
|
+
sessionEndEventsEnabled: Bool
|
|
1364
1386
|
)? {
|
|
1365
1387
|
if let raw = stringValue(value) {
|
|
1366
1388
|
if raw.caseInsensitiveCompare("ALL") == .orderedSame {
|
|
1367
|
-
return (true, true, true)
|
|
1389
|
+
return (true, true, true, true, true)
|
|
1368
1390
|
}
|
|
1369
1391
|
if raw.caseInsensitiveCompare("NONE") == .orderedSame {
|
|
1370
|
-
return (false, false, false)
|
|
1392
|
+
return (false, false, false, false, false)
|
|
1371
1393
|
}
|
|
1372
1394
|
return nil
|
|
1373
1395
|
}
|
|
1374
1396
|
|
|
1375
1397
|
guard let payload = dictionaryValue(value) else { return nil }
|
|
1398
|
+
let legacySessionEventsEnabled = (payload["sessionEventsEnabled"] as? Bool) ?? true
|
|
1376
1399
|
return (
|
|
1377
1400
|
appLifecycleEnabled: (payload["appLifecycleEnabled"] as? Bool) ?? true,
|
|
1401
|
+
foregroundLifecycleEnabled: (payload["foregroundLifecycleEnabled"] as? Bool) ?? false,
|
|
1378
1402
|
pushSubscriptionEnabled: (payload["pushSubscriptionEnabled"] as? Bool) ?? true,
|
|
1379
|
-
|
|
1403
|
+
sessionStartEventsEnabled: (payload["sessionStartEventsEnabled"] as? Bool) ?? legacySessionEventsEnabled,
|
|
1404
|
+
sessionEndEventsEnabled: (payload["sessionEndEventsEnabled"] as? Bool) ??
|
|
1405
|
+
(payload.keys.contains("sessionEventsEnabled") ? legacySessionEventsEnabled : false)
|
|
1380
1406
|
)
|
|
1381
1407
|
}
|
|
1382
1408
|
|
package/types/index.ts
CHANGED
|
@@ -77,8 +77,13 @@ export type NotificationResponseHandlerOptions = {
|
|
|
77
77
|
export type LifecycleTrackingOptions =
|
|
78
78
|
| {
|
|
79
79
|
appLifecycleEnabled?: boolean | null;
|
|
80
|
+
foregroundLifecycleEnabled?: boolean | null;
|
|
80
81
|
pushSubscriptionEnabled?: boolean | null;
|
|
82
|
+
/** @deprecated Use sessionStartEventsEnabled/sessionEndEventsEnabled instead. */
|
|
83
|
+
/** Backward-compatible alias for setting both sessionStart/sessionEnd */
|
|
81
84
|
sessionEventsEnabled?: boolean | null;
|
|
85
|
+
sessionStartEventsEnabled?: boolean | null;
|
|
86
|
+
sessionEndEventsEnabled?: boolean | null;
|
|
82
87
|
}
|
|
83
88
|
| 'ALL'
|
|
84
89
|
| 'NONE'
|
|
@@ -92,6 +97,8 @@ export type RetenoInitializeOptions = {
|
|
|
92
97
|
inAppMessagesPauseBehaviour?: InAppPauseBehaviour;
|
|
93
98
|
isAutomaticScreenReportingEnabled?: boolean;
|
|
94
99
|
lifecycleTrackingOptions?: LifecycleTrackingOptions;
|
|
100
|
+
/** Session reset duration in seconds (Android 2.9.4+, iOS 2.7.0+). */
|
|
101
|
+
sessionDurationSeconds?: number;
|
|
95
102
|
/** Enables Reteno debug mode for near real-time event monitoring. Use only with test devices. */
|
|
96
103
|
isDebugMode?: boolean;
|
|
97
104
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
const exec = require('cordova/exec');
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const PLUGIN_NAME = 'RetenoPlugin';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const __retenoState = {
|
|
6
6
|
initialized: false,
|
|
7
7
|
initPromise: null,
|
|
8
8
|
pendingInitOptions: {},
|
|
@@ -23,7 +23,7 @@ function __promiseExec(action, args) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function __callWithExec(action, args, success, error) {
|
|
26
|
-
|
|
26
|
+
const p = __promiseExec(action, args);
|
|
27
27
|
if (__isFn(success) || __isFn(error)) {
|
|
28
28
|
p.then(function (res) {
|
|
29
29
|
if (__isFn(success)) success(res);
|
|
@@ -45,8 +45,8 @@ function __ensureInit(options) {
|
|
|
45
45
|
return __retenoState.initPromise;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
const pendingOptions = __retenoState.pendingInitOptions || {};
|
|
49
|
+
const opts = Object.assign({}, pendingOptions, options || {});
|
|
50
50
|
__retenoState.initPromise = __promiseExec('initialize', [opts])
|
|
51
51
|
.then(function (res) {
|
|
52
52
|
__retenoState.initialized = true;
|
|
@@ -64,7 +64,7 @@ function __ensureInit(options) {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
function __callWithAutoInit(action, args, success, error) {
|
|
67
|
-
|
|
67
|
+
const p = __ensureInit().then(function () {
|
|
68
68
|
return __promiseExec(action, args);
|
|
69
69
|
});
|
|
70
70
|
if (__isFn(success) || __isFn(error)) {
|
|
@@ -134,7 +134,7 @@ var urlutil = require('cordova/urlutil');
|
|
|
134
134
|
})();
|
|
135
135
|
*/
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
const RetenoPluginFunctions = {
|
|
138
138
|
/*
|
|
139
139
|
options: {
|
|
140
140
|
accessKey?: string,
|
|
@@ -143,7 +143,15 @@ var RetenoPluginFunctions = {
|
|
|
143
143
|
inAppMessagesPauseBehaviour?: 'SKIP_IN_APPS' | 'POSTPONE_IN_APPS',
|
|
144
144
|
isAutomaticScreenReportingEnabled?: boolean,
|
|
145
145
|
isDebugMode?: boolean,
|
|
146
|
-
|
|
146
|
+
sessionDurationSeconds?: number, // Android 2.9.4+, iOS 2.7.0+
|
|
147
|
+
lifecycleTrackingOptions?: {
|
|
148
|
+
appLifecycleEnabled?: boolean,
|
|
149
|
+
foregroundLifecycleEnabled?: boolean,
|
|
150
|
+
pushSubscriptionEnabled?: boolean,
|
|
151
|
+
sessionEventsEnabled?: boolean, // backward-compatible alias
|
|
152
|
+
sessionStartEventsEnabled?: boolean,
|
|
153
|
+
sessionEndEventsEnabled?: boolean
|
|
154
|
+
}
|
|
147
155
|
}
|
|
148
156
|
*/
|
|
149
157
|
init: function (arg0, success, error) {
|
|
@@ -154,8 +162,8 @@ var RetenoPluginFunctions = {
|
|
|
154
162
|
arg0 = {};
|
|
155
163
|
}
|
|
156
164
|
|
|
157
|
-
|
|
158
|
-
|
|
165
|
+
const options = arg0 || {};
|
|
166
|
+
const p = __ensureInit(options);
|
|
159
167
|
if (__isFn(success) || __isFn(error)) {
|
|
160
168
|
p.then(function (res) {
|
|
161
169
|
if (__isFn(success)) success(res);
|
|
@@ -185,7 +193,7 @@ var RetenoPluginFunctions = {
|
|
|
185
193
|
*/
|
|
186
194
|
logEcommerceEvent: function (arg0, success, error) {
|
|
187
195
|
// Accept either `payload` or legacy `[payload]`.
|
|
188
|
-
|
|
196
|
+
const payload = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
189
197
|
if (!payload || typeof payload !== 'object') {
|
|
190
198
|
return Promise.reject(new Error('Missing argument: payload'));
|
|
191
199
|
}
|
|
@@ -200,7 +208,7 @@ var RetenoPluginFunctions = {
|
|
|
200
208
|
*/
|
|
201
209
|
setUserAttributes: function (arg0, success, error) {
|
|
202
210
|
// Accept either `payload` or legacy `[payload]`.
|
|
203
|
-
|
|
211
|
+
const payload = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
204
212
|
if (
|
|
205
213
|
!payload ||
|
|
206
214
|
!payload.externalUserId ||
|
|
@@ -216,7 +224,7 @@ var RetenoPluginFunctions = {
|
|
|
216
224
|
*/
|
|
217
225
|
setAnonymousUserAttributes: function (arg0, success, error) {
|
|
218
226
|
// Accept either `payload` or legacy `[payload]`.
|
|
219
|
-
|
|
227
|
+
const payload = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
220
228
|
if (!payload || typeof payload !== 'object') {
|
|
221
229
|
return Promise.reject(new Error('Missing argument: payload'));
|
|
222
230
|
}
|
|
@@ -247,7 +255,7 @@ var RetenoPluginFunctions = {
|
|
|
247
255
|
*/
|
|
248
256
|
setMultiAccountUserAttributes: function (arg0, success, error) {
|
|
249
257
|
// Accept either `payload` or legacy `[payload]`.
|
|
250
|
-
|
|
258
|
+
const payload = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
251
259
|
if (
|
|
252
260
|
!payload ||
|
|
253
261
|
!payload.externalUserId ||
|
|
@@ -270,7 +278,7 @@ var RetenoPluginFunctions = {
|
|
|
270
278
|
// Back-compat:
|
|
271
279
|
// - setOnRetenoPushReceivedListener(listener)
|
|
272
280
|
// - setOnRetenoPushReceivedListener(reteno, listener) (legacy)
|
|
273
|
-
|
|
281
|
+
const listener = typeof arg0 === 'function' ? arg0 : arg1;
|
|
274
282
|
if (typeof listener !== 'function') return;
|
|
275
283
|
document.addEventListener('reteno-push-received', listener);
|
|
276
284
|
},
|
|
@@ -279,7 +287,7 @@ var RetenoPluginFunctions = {
|
|
|
279
287
|
// Back-compat:
|
|
280
288
|
// - setOnRetenoNotificationClickedListener(listener)
|
|
281
289
|
// - setOnRetenoNotificationClickedListener(reteno, listener) (legacy)
|
|
282
|
-
|
|
290
|
+
const listener = typeof arg0 === 'function' ? arg0 : arg1;
|
|
283
291
|
if (typeof listener !== 'function') return;
|
|
284
292
|
document.addEventListener('reteno-notification-clicked', listener);
|
|
285
293
|
},
|
|
@@ -298,20 +306,20 @@ var RetenoPluginFunctions = {
|
|
|
298
306
|
// Back-compat:
|
|
299
307
|
// - setOnInAppMessageCustomDataReceivedListener(listener)
|
|
300
308
|
// - setOnInAppMessageCustomDataReceivedListener(reteno, listener) (legacy)
|
|
301
|
-
|
|
309
|
+
const listener = typeof arg0 === 'function' ? arg0 : arg1;
|
|
302
310
|
if (typeof listener !== 'function') return;
|
|
303
311
|
document.addEventListener('reteno-in-app-custom-data', listener);
|
|
304
312
|
},
|
|
305
313
|
|
|
306
314
|
removeOnInAppMessageCustomDataReceivedListener: function (arg0, arg1) {
|
|
307
|
-
|
|
315
|
+
const listener = typeof arg0 === 'function' ? arg0 : arg1;
|
|
308
316
|
if (typeof listener !== 'function') return;
|
|
309
317
|
document.removeEventListener('reteno-in-app-custom-data', listener);
|
|
310
318
|
},
|
|
311
319
|
|
|
312
320
|
// Push notification dismissed (swiped away)
|
|
313
321
|
setOnRetenoPushDismissedListener: function (arg0, arg1) {
|
|
314
|
-
|
|
322
|
+
const listener = typeof arg0 === 'function' ? arg0 : arg1;
|
|
315
323
|
if (typeof listener !== 'function') return;
|
|
316
324
|
document.addEventListener('reteno-push-dismissed', listener);
|
|
317
325
|
},
|
|
@@ -323,7 +331,7 @@ var RetenoPluginFunctions = {
|
|
|
323
331
|
|
|
324
332
|
// Custom push notification received
|
|
325
333
|
setOnRetenoCustomPushReceivedListener: function (arg0, arg1) {
|
|
326
|
-
|
|
334
|
+
const listener = typeof arg0 === 'function' ? arg0 : arg1;
|
|
327
335
|
if (typeof listener !== 'function') return;
|
|
328
336
|
document.addEventListener('reteno-custom-push-received', listener);
|
|
329
337
|
},
|
|
@@ -335,7 +343,7 @@ var RetenoPluginFunctions = {
|
|
|
335
343
|
|
|
336
344
|
// Push notification action button clicked (iOS & Android)
|
|
337
345
|
setOnRetenoPushButtonClickedListener: function (arg0, arg1) {
|
|
338
|
-
|
|
346
|
+
const listener = typeof arg0 === 'function' ? arg0 : arg1;
|
|
339
347
|
if (typeof listener !== 'function') return;
|
|
340
348
|
document.addEventListener('reteno-push-button-clicked', listener);
|
|
341
349
|
},
|
|
@@ -361,7 +369,7 @@ var RetenoPluginFunctions = {
|
|
|
361
369
|
},
|
|
362
370
|
|
|
363
371
|
setOnInAppLifecycleCallback: function (arg0, arg1) {
|
|
364
|
-
|
|
372
|
+
const listener = typeof arg0 === 'function' ? arg0 : arg1;
|
|
365
373
|
if (arg0 === null || listener === null) {
|
|
366
374
|
return __callWithAutoInit('setInAppLifecycleCallback', [null]);
|
|
367
375
|
}
|
|
@@ -384,13 +392,13 @@ var RetenoPluginFunctions = {
|
|
|
384
392
|
*/
|
|
385
393
|
setLifecycleTrackingOptions: function (arg0, success, error) {
|
|
386
394
|
// Accept either `options` or legacy `[options]`.
|
|
387
|
-
|
|
395
|
+
const options = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
388
396
|
if (!options) {
|
|
389
397
|
return Promise.reject(new Error('Missing argument: options'));
|
|
390
398
|
}
|
|
391
399
|
|
|
392
400
|
if (__isIosPlatform()) {
|
|
393
|
-
|
|
401
|
+
let p;
|
|
394
402
|
if (__retenoState.initialized || __retenoState.initPromise) {
|
|
395
403
|
p = Promise.reject(
|
|
396
404
|
new Error('iOS supports lifecycleTrackingOptions only during init(...) before SDK initialization.')
|
|
@@ -449,7 +457,7 @@ var RetenoPluginFunctions = {
|
|
|
449
457
|
isPaused: boolean
|
|
450
458
|
*/
|
|
451
459
|
pauseInAppMessages: function (arg0, success, error) {
|
|
452
|
-
|
|
460
|
+
const isPaused = !!arg0;
|
|
453
461
|
return __callWithAutoInit('pauseInAppMessages', [isPaused], success, error);
|
|
454
462
|
},
|
|
455
463
|
|
|
@@ -495,7 +503,7 @@ var RetenoPluginFunctions = {
|
|
|
495
503
|
*/
|
|
496
504
|
updateDefaultNotificationChannel: function (arg0, success, error) {
|
|
497
505
|
// Accept either `config` or legacy `[config]`.
|
|
498
|
-
|
|
506
|
+
const config = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
499
507
|
if (!config || typeof config !== 'object') {
|
|
500
508
|
return Promise.reject(new Error('Missing argument: config'));
|
|
501
509
|
}
|
|
@@ -518,7 +526,7 @@ var RetenoPluginFunctions = {
|
|
|
518
526
|
*/
|
|
519
527
|
getAppInboxMessages: function (arg0, success, error) {
|
|
520
528
|
// Accept either `payload` or legacy `[payload]`.
|
|
521
|
-
|
|
529
|
+
const payload = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
522
530
|
if (!payload || typeof payload !== 'object') {
|
|
523
531
|
return Promise.reject(new Error('Missing argument: payload'));
|
|
524
532
|
}
|
|
@@ -536,8 +544,8 @@ var RetenoPluginFunctions = {
|
|
|
536
544
|
},
|
|
537
545
|
|
|
538
546
|
subscribeOnMessagesCountChanged: function (arg0, arg1) {
|
|
539
|
-
|
|
540
|
-
|
|
547
|
+
const success = typeof arg0 === 'function' ? arg0 : arg1;
|
|
548
|
+
const error = typeof arg0 === 'function' ? arg1 : undefined;
|
|
541
549
|
return __ensureInit().then(function () {
|
|
542
550
|
exec(success, error, PLUGIN_NAME, 'subscribeOnMessagesCountChanged', []);
|
|
543
551
|
return 1;
|
|
@@ -553,7 +561,7 @@ var RetenoPluginFunctions = {
|
|
|
553
561
|
*/
|
|
554
562
|
markAsOpened: function (arg0, success, error) {
|
|
555
563
|
// Accept either `messageId` or legacy `[messageId]`.
|
|
556
|
-
|
|
564
|
+
const messageId = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
557
565
|
if (!messageId || typeof messageId !== 'string' || messageId.trim().length === 0) {
|
|
558
566
|
return Promise.reject(new Error('Missing argument: messageId'));
|
|
559
567
|
}
|
|
@@ -569,7 +577,7 @@ var RetenoPluginFunctions = {
|
|
|
569
577
|
*/
|
|
570
578
|
getRecommendations: function (arg0, success, error) {
|
|
571
579
|
// Accept either `payload` or legacy `[payload]`.
|
|
572
|
-
|
|
580
|
+
const payload = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
573
581
|
if (!payload || typeof payload !== 'object') {
|
|
574
582
|
return Promise.reject(new Error('Missing argument: payload'));
|
|
575
583
|
}
|
|
@@ -588,7 +596,7 @@ var RetenoPluginFunctions = {
|
|
|
588
596
|
*/
|
|
589
597
|
logRecommendations: function (arg0, success, error) {
|
|
590
598
|
// Accept either `payload` or legacy `[payload]`.
|
|
591
|
-
|
|
599
|
+
const payload = Array.isArray(arg0) ? arg0[0] : arg0;
|
|
592
600
|
if (!payload || typeof payload !== 'object') {
|
|
593
601
|
return Promise.reject(new Error('Missing argument: payload'));
|
|
594
602
|
}
|