cordova-plugin-reteno 2.1.0 → 2.2.1
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 +4 -0
- package/docs/Cordova/Action Buttons/README.md +62 -0
- package/docs/Cordova/AppInbox/README.md +55 -0
- package/docs/Cordova/AppLifeCycleEvents/README.md +80 -0
- package/docs/Cordova/Ecommerce/README.md +144 -0
- package/docs/Cordova/InAppMessages/README.md +72 -0
- package/docs/Cordova/Push notification/README.md +124 -0
- package/docs/Cordova/Recommendations/README.md +62 -0
- package/docs/Cordova/SetupGuide/Android.md +135 -0
- package/docs/Cordova/SetupGuide/IOS.md +325 -0
- package/docs/Cordova/SetupGuide/README.md +91 -0
- package/docs/Cordova/Tracking user behaviour/README.md +52 -0
- package/docs/Cordova/Tracking user information/README.md +112 -0
- package/docs/Ionic/Action Buttons/README.md +66 -0
- package/docs/Ionic/AppInbox/README.md +61 -0
- package/docs/Ionic/AppLifeCycleEvents/README.md +77 -0
- package/docs/Ionic/Ecommerce/README.md +139 -0
- package/docs/Ionic/InAppMessages/README.md +65 -0
- package/docs/Ionic/Push notification/README.md +128 -0
- package/docs/Ionic/Recommendations/README.md +46 -0
- package/docs/Ionic/SetupGuide/Android.md +173 -0
- package/docs/Ionic/SetupGuide/IOS.md +354 -0
- package/docs/Ionic/SetupGuide/README.md +167 -0
- package/docs/Ionic/Tracking user behaviour/README.md +31 -0
- package/docs/Ionic/Tracking user information/README.md +98 -0
- package/package.json +1 -1
- package/plugin.xml +30 -2
- package/scripts/ios-podfile-use-modular-headers.js +109 -0
- package/scripts/validate-install.js +37 -9
- package/src/android/app/build.gradle +1 -1
- package/src/android/app/src/main/AndroidManifest.xml +6 -1
- package/src/android/app/src/main/java/com/reteno/plugin/RetenoNotificationGroupingRuleProvider.java +117 -0
- package/src/android/app/src/main/java/com/reteno/plugin/RetenoNotificationSummaryManager.java +262 -0
- package/src/android/app/src/main/java/com/reteno/plugin/RetenoPlugin.java +99 -11
- package/src/android/reteno.gradle +19 -9
- package/src/ios/RetenoPlugin.swift +38 -6
- package/src/ios/RetenoPluginBootstrap.m +117 -0
- package/types/index.ts +11 -3
- package/www/cordova-plugin-reteno.js +39 -1
- package/docs/android.md +0 -247
- package/docs/api.md +0 -714
- package/docs/ios.md +0 -495
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Reteno SDK for Cordova and Capacitor apps.
|
|
4
4
|
|
|
5
|
+
Version 2.2.1 includes Reteno Android SDK 2.10.2 and Reteno iOS SDK 2.7.4.
|
|
6
|
+
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
7
9
|
```bash
|
|
@@ -10,6 +12,8 @@ npm install cordova-plugin-reteno
|
|
|
10
12
|
|
|
11
13
|
## Documentation
|
|
12
14
|
|
|
15
|
+
- [Bundled Cordova documentation](docs/Cordova/SetupGuide/README.md)
|
|
16
|
+
- [Bundled Ionic documentation](docs/Ionic/SetupGuide/README.md)
|
|
13
17
|
- [Cordova SDK Overview](https://docs.reteno.com/reference/cordova-sdk-setup)
|
|
14
18
|
- [Ionic SDK Overview](https://docs.reteno.com/reference/ionic-sdk)
|
|
15
19
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Action Buttons
|
|
2
|
+
|
|
3
|
+
## Configuring Action Buttons
|
|
4
|
+
|
|
5
|
+
When creating mobile push notifications, you can add action buttons.
|
|
6
|
+
|
|
7
|
+
- iOS supports up to 4 buttons in one notification.
|
|
8
|
+
- Android supports up to 3 buttons in one notification.
|
|
9
|
+
|
|
10
|
+
### Adding Action Buttons
|
|
11
|
+
|
|
12
|
+
1. In Reteno, open `Messages -> Mobile Push`.
|
|
13
|
+
2. Create a push or edit existing one.
|
|
14
|
+
3. Configure the `Buttons` section.
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<img src="https://raw.githubusercontent.com/reteno-com/reteno-mobile-documentation/main/Cordova/Action%20Buttons/Resources/action_button_setup.png" width="100%"/>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
Use unique `Action ID` values for different buttons.
|
|
21
|
+
|
|
22
|
+
| Parameter | Notes |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| Action ID | Unique button action identifier |
|
|
25
|
+
| Text | Text shown on the button |
|
|
26
|
+
| iOS icon path | Available on iOS 15+. Name of image from app bundle |
|
|
27
|
+
| Launch URL | URL/deeplink to open |
|
|
28
|
+
| Custom data | Additional JSON payload |
|
|
29
|
+
|
|
30
|
+
## Handle Action Button click
|
|
31
|
+
|
|
32
|
+
Enable handler for iOS event emission:
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
await RetenoPlugin.setNotificationActionHandler({ emitEvent: true });
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Subscribe:
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
function onPushButtonClicked(event) {
|
|
42
|
+
const detail = event && event.detail !== undefined ? event.detail : event;
|
|
43
|
+
console.log('reteno-push-button-clicked:', detail);
|
|
44
|
+
// detail.actionId
|
|
45
|
+
// detail.link
|
|
46
|
+
// detail.customData
|
|
47
|
+
// detail.userInfo
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
RetenoPlugin.setOnRetenoPushButtonClickedListener(onPushButtonClicked);
|
|
51
|
+
|
|
52
|
+
// later
|
|
53
|
+
RetenoPlugin.removeOnRetenoPushButtonClickedListener(onPushButtonClicked);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Disable handler:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
await RetenoPlugin.setNotificationActionHandler(false);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Android note: `setNotificationActionHandler(...)` is no-op on Android. Action button clicks are detected automatically.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# App inbox
|
|
2
|
+
|
|
3
|
+
## Get App Inbox messages
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
RetenoPlugin.getAppInboxMessages({
|
|
7
|
+
page: 1,
|
|
8
|
+
pageSize: 20,
|
|
9
|
+
status: 'UNOPENED', // optional: OPENED | UNOPENED
|
|
10
|
+
})
|
|
11
|
+
.then((result) => {
|
|
12
|
+
console.log('messages:', result.messages);
|
|
13
|
+
console.log('totalPages:', result.totalPages);
|
|
14
|
+
})
|
|
15
|
+
.catch((err) => console.error('getAppInboxMessages: ERROR', err));
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Get unread messages count
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
RetenoPlugin.getAppInboxMessagesCount()
|
|
22
|
+
.then((count) => console.log('Unread messages:', count))
|
|
23
|
+
.catch((err) => console.error('getAppInboxMessagesCount: ERROR', err));
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Subscribe to count changes
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
function onInboxCountChanged(count) {
|
|
30
|
+
console.log('App Inbox count changed:', count);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
RetenoPlugin.subscribeOnMessagesCountChanged(onInboxCountChanged, (err) => {
|
|
34
|
+
console.error('subscribeOnMessagesCountChanged: ERROR', err);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// unsubscribe
|
|
38
|
+
RetenoPlugin.unsubscribeMessagesCountChanged();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Mark message as opened
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
RetenoPlugin.markAsOpened('message-id')
|
|
45
|
+
.then(() => console.log('markAsOpened: OK'))
|
|
46
|
+
.catch((err) => console.error('markAsOpened: ERROR', err));
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Mark all messages as opened
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
RetenoPlugin.markAllMessagesAsOpened()
|
|
53
|
+
.then(() => console.log('markAllMessagesAsOpened: OK'))
|
|
54
|
+
.catch((err) => console.error('markAllMessagesAsOpened: ERROR', err));
|
|
55
|
+
```
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# App Lifecycle Events
|
|
2
|
+
|
|
3
|
+
Reteno can automatically track app lifecycle, foreground lifecycle, push subscription, and session events.
|
|
4
|
+
|
|
5
|
+
## Tracked app lifecycle events
|
|
6
|
+
|
|
7
|
+
When `appLifecycleEnabled` is enabled:
|
|
8
|
+
|
|
9
|
+
- `ApplicationInstalled`
|
|
10
|
+
- `ApplicationUpdated`
|
|
11
|
+
- `ApplicationOpened`
|
|
12
|
+
- `ApplicationBackgrounded`
|
|
13
|
+
|
|
14
|
+
## Tracked foreground lifecycle events
|
|
15
|
+
|
|
16
|
+
When `foregroundLifecycleEnabled` is enabled:
|
|
17
|
+
|
|
18
|
+
- `ApplicationOpened`
|
|
19
|
+
- `ApplicationBackgrounded`
|
|
20
|
+
|
|
21
|
+
## Tracked push subscription events
|
|
22
|
+
|
|
23
|
+
When `pushSubscriptionEnabled` is enabled:
|
|
24
|
+
|
|
25
|
+
- `PushNotificationsSubscribed`
|
|
26
|
+
- `PushNotificationsUnsubscribed`
|
|
27
|
+
|
|
28
|
+
## Tracked session events
|
|
29
|
+
|
|
30
|
+
When `sessionStartEventsEnabled` / `sessionEndEventsEnabled` are enabled:
|
|
31
|
+
|
|
32
|
+
- `SessionStarted`
|
|
33
|
+
- `SessionEnded`
|
|
34
|
+
|
|
35
|
+
## Configure lifecycle tracking
|
|
36
|
+
|
|
37
|
+
Configure during initialization:
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
RetenoPlugin.init({
|
|
41
|
+
lifecycleTrackingOptions: {
|
|
42
|
+
appLifecycleEnabled: true,
|
|
43
|
+
foregroundLifecycleEnabled: false,
|
|
44
|
+
pushSubscriptionEnabled: true,
|
|
45
|
+
sessionStartEventsEnabled: true,
|
|
46
|
+
sessionEndEventsEnabled: false,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or with shortcuts:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
RetenoPlugin.init({ lifecycleTrackingOptions: 'ALL' });
|
|
55
|
+
RetenoPlugin.init({ lifecycleTrackingOptions: 'NONE' });
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
You can also call:
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
RetenoPlugin.setLifecycleTrackingOptions({
|
|
62
|
+
sessionStartEventsEnabled: true,
|
|
63
|
+
sessionEndEventsEnabled: true,
|
|
64
|
+
});
|
|
65
|
+
RetenoPlugin.setLifecycleTrackingOptions('ALL');
|
|
66
|
+
RetenoPlugin.setLifecycleTrackingOptions('NONE');
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
iOS note: `setLifecycleTrackingOptions(...)` must be called before `init()`.
|
|
70
|
+
Legacy note: `sessionEventsEnabled` is still supported as an alias that toggles both session start and end events.
|
|
71
|
+
|
|
72
|
+
## Screen tracking in Cordova
|
|
73
|
+
|
|
74
|
+
For Cordova apps, manual screen tracking is recommended:
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
RetenoPlugin.logScreenView('HomeScreen');
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Automatic native screen tracking in hybrid WebView apps does not reflect JS route changes.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Ecommerce Activity Tracking
|
|
2
|
+
|
|
3
|
+
Reteno tracks ecommerce activity using `logEcommerceEvent(...)`.
|
|
4
|
+
|
|
5
|
+
Supported `eventType` values:
|
|
6
|
+
|
|
7
|
+
- `productViewed`
|
|
8
|
+
- `productCategoryViewed`
|
|
9
|
+
- `productAddedToWishlist`
|
|
10
|
+
- `cartUpdated`
|
|
11
|
+
- `orderCreated`
|
|
12
|
+
- `orderUpdated`
|
|
13
|
+
- `orderDelivered`
|
|
14
|
+
- `orderCancelled`
|
|
15
|
+
- `searchRequest`
|
|
16
|
+
|
|
17
|
+
## Product viewed
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
RetenoPlugin.logEcommerceEvent({
|
|
21
|
+
eventType: 'productViewed',
|
|
22
|
+
product: {
|
|
23
|
+
productId: 'SKU-123',
|
|
24
|
+
price: 29.99,
|
|
25
|
+
isInStock: true,
|
|
26
|
+
attributes: [{ name: 'color', value: ['red', 'blue'] }],
|
|
27
|
+
},
|
|
28
|
+
currencyCode: 'USD',
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Product category viewed
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
RetenoPlugin.logEcommerceEvent({
|
|
36
|
+
eventType: 'productCategoryViewed',
|
|
37
|
+
category: {
|
|
38
|
+
productCategoryId: 'CATEGORY-01',
|
|
39
|
+
attributes: [{ name: 'gender', value: ['women'] }],
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Product added to wishlist
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
RetenoPlugin.logEcommerceEvent({
|
|
48
|
+
eventType: 'productAddedToWishlist',
|
|
49
|
+
product: {
|
|
50
|
+
productId: 'SKU-123',
|
|
51
|
+
price: 29.99,
|
|
52
|
+
isInStock: true,
|
|
53
|
+
attributes: [{ name: 'color', value: ['red'] }],
|
|
54
|
+
},
|
|
55
|
+
currencyCode: 'USD',
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Cart updated
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
RetenoPlugin.logEcommerceEvent({
|
|
63
|
+
eventType: 'cartUpdated',
|
|
64
|
+
cartId: 'cart-456',
|
|
65
|
+
products: [
|
|
66
|
+
{
|
|
67
|
+
productId: 'SKU-123',
|
|
68
|
+
quantity: 2,
|
|
69
|
+
price: 29.99,
|
|
70
|
+
name: 'T-Shirt',
|
|
71
|
+
category: 'Apparel',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
currencyCode: 'USD',
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Order created
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
RetenoPlugin.logEcommerceEvent({
|
|
82
|
+
eventType: 'orderCreated',
|
|
83
|
+
order: {
|
|
84
|
+
externalOrderId: 'ORD-789',
|
|
85
|
+
totalCost: 59.98,
|
|
86
|
+
status: 'INITIALIZED',
|
|
87
|
+
date: new Date().toISOString(),
|
|
88
|
+
items: [
|
|
89
|
+
{
|
|
90
|
+
externalItemId: 'SKU-123',
|
|
91
|
+
name: 'T-Shirt',
|
|
92
|
+
category: 'Apparel',
|
|
93
|
+
quantity: 2,
|
|
94
|
+
cost: 29.99,
|
|
95
|
+
url: 'https://example.com/products/SKU-123',
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
currencyCode: 'USD',
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Order updated
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
RetenoPlugin.logEcommerceEvent({
|
|
107
|
+
eventType: 'orderUpdated',
|
|
108
|
+
order: {
|
|
109
|
+
externalOrderId: 'ORD-789',
|
|
110
|
+
totalCost: 59.98,
|
|
111
|
+
status: 'IN_PROGRESS',
|
|
112
|
+
date: new Date().toISOString(),
|
|
113
|
+
},
|
|
114
|
+
currencyCode: 'USD',
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Order delivered / cancelled
|
|
119
|
+
|
|
120
|
+
For these event types the payload requires `externalOrderId` (not full `order` object):
|
|
121
|
+
|
|
122
|
+
```js
|
|
123
|
+
RetenoPlugin.logEcommerceEvent({
|
|
124
|
+
eventType: 'orderDelivered',
|
|
125
|
+
externalOrderId: 'ORD-789',
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
RetenoPlugin.logEcommerceEvent({
|
|
129
|
+
eventType: 'orderCancelled',
|
|
130
|
+
externalOrderId: 'ORD-789',
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Search request
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
RetenoPlugin.logEcommerceEvent({
|
|
138
|
+
eventType: 'searchRequest',
|
|
139
|
+
search: 'red t-shirt',
|
|
140
|
+
isFound: true,
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Use valid [ISO-4217](https://en.wikipedia.org/wiki/ISO_4217) currency codes.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# In app messages
|
|
2
|
+
|
|
3
|
+
## Pause and resume In-App messages
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
// pause
|
|
7
|
+
RetenoPlugin.pauseInAppMessages(true)
|
|
8
|
+
.then(() => console.log('In-apps paused'))
|
|
9
|
+
.catch((err) => console.error(err));
|
|
10
|
+
|
|
11
|
+
// resume
|
|
12
|
+
RetenoPlugin.pauseInAppMessages(false)
|
|
13
|
+
.then(() => console.log('In-apps resumed'))
|
|
14
|
+
.catch((err) => console.error(err));
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Configure pause behaviour
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
// Drop in-apps received while paused
|
|
21
|
+
RetenoPlugin.setInAppMessagesPauseBehaviour('SKIP_IN_APPS');
|
|
22
|
+
|
|
23
|
+
// Queue one and show later after resume
|
|
24
|
+
RetenoPlugin.setInAppMessagesPauseBehaviour('POSTPONE_IN_APPS');
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Subscribe to In-App lifecycle events
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
function onInAppStatus(event) {
|
|
31
|
+
const detail = event.detail || event;
|
|
32
|
+
console.log('In-app status:', detail.event, detail.data);
|
|
33
|
+
// detail.event:
|
|
34
|
+
// beforeDisplay, onDisplay, beforeClose, afterClose, onError
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
RetenoPlugin.setOnInAppLifecycleCallback(onInAppStatus);
|
|
38
|
+
|
|
39
|
+
// unsubscribe
|
|
40
|
+
RetenoPlugin.setOnInAppLifecycleCallback(null);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Platform-specific payload (`detail.data`)
|
|
44
|
+
|
|
45
|
+
| Event | Android | iOS |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `beforeDisplay` | `{ id }` | `{}` (empty) |
|
|
48
|
+
| `onDisplay` | `{ id }` | `{}` (empty) |
|
|
49
|
+
| `beforeClose` | `{ id, closeAction }` | `{ closeAction, action }` |
|
|
50
|
+
| `afterClose` | `{ id, closeAction }` | `{ closeAction, action }` |
|
|
51
|
+
| `onError` | `{ id, errorMessage }` | `{ errorMessage }` |
|
|
52
|
+
|
|
53
|
+
`closeAction` values:
|
|
54
|
+
- **Android**: string from native SDK (e.g. via `InAppCloseData.getCloseAction()`)
|
|
55
|
+
- **iOS**: `"closeButtonClicked"`, `"buttonClicked"`, `"openUrlClicked"`, or `"unknown"`
|
|
56
|
+
|
|
57
|
+
`action` (iOS only): `{ isCloseButtonClicked, isButtonClicked, isOpenUrlClicked }`
|
|
58
|
+
|
|
59
|
+
## Receive custom data from In-App (Android)
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
function onInAppCustomData(event) {
|
|
63
|
+
console.log('In-app custom data:', event.detail);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
RetenoPlugin.setOnInAppMessageCustomDataReceivedListener(onInAppCustomData);
|
|
67
|
+
|
|
68
|
+
// later
|
|
69
|
+
RetenoPlugin.removeOnInAppMessageCustomDataReceivedListener(onInAppCustomData);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Important: when this listener is registered, automatic opening of In-App button links is disabled. Handle navigation yourself (for example, using `event.detail.url`).
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Push notification
|
|
2
|
+
|
|
3
|
+
## Request notification permission
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
RetenoPlugin.requestNotificationPermission()
|
|
7
|
+
.then((result) => {
|
|
8
|
+
// Android: 1 granted / 0 declined
|
|
9
|
+
console.log('Permission result:', result);
|
|
10
|
+
})
|
|
11
|
+
.catch((err) => console.error(err));
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Get initial notification
|
|
15
|
+
|
|
16
|
+
When app starts from push tap, get payload with `getInitialNotification()`:
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
RetenoPlugin.getInitialNotification()
|
|
20
|
+
.then((data) => console.log('getInitialNotification', data))
|
|
21
|
+
.catch((err) => console.error('getInitialNotification: ERROR', err));
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Listen for received push while app is active
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
function onPushReceived(event) {
|
|
28
|
+
console.log('reteno-push-received:', event);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
RetenoPlugin.setOnRetenoPushReceivedListener(onPushReceived);
|
|
32
|
+
|
|
33
|
+
// later
|
|
34
|
+
RetenoPlugin.removeOnRetenoPushReceivedListener(onPushReceived);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Listen for push click events
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
function onNotificationClicked(event) {
|
|
41
|
+
console.log('reteno-notification-clicked:', event);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
RetenoPlugin.setOnRetenoNotificationClickedListener(onNotificationClicked);
|
|
45
|
+
|
|
46
|
+
// later
|
|
47
|
+
RetenoPlugin.removeOnRetenoNotificationClickedListener(onNotificationClicked);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Android-only listeners
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
function onDismissed(payload) {
|
|
54
|
+
console.log('Push dismissed', payload);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function onCustomReceived(payload) {
|
|
58
|
+
console.log('Custom push received', payload);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
RetenoPlugin.setOnRetenoPushDismissedListener(onDismissed);
|
|
62
|
+
RetenoPlugin.setOnRetenoCustomPushReceivedListener(onCustomReceived);
|
|
63
|
+
|
|
64
|
+
// later
|
|
65
|
+
RetenoPlugin.removeOnRetenoPushDismissedListener(onDismissed);
|
|
66
|
+
RetenoPlugin.removeOnRetenoCustomPushReceivedListener(onCustomReceived);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## iOS foreground/tap handlers (optional)
|
|
70
|
+
|
|
71
|
+
These methods are **iOS-only**. On Android they are not implemented and calls will fail.
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
await RetenoPlugin.setWillPresentNotificationOptions({
|
|
75
|
+
options: ['badge', 'sound', 'banner'],
|
|
76
|
+
emitEvent: true,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
await RetenoPlugin.setDidReceiveNotificationResponseHandler({
|
|
80
|
+
enabled: true,
|
|
81
|
+
emitEvent: true,
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
If `emitEvent: true`, plugin emits JS events:
|
|
86
|
+
|
|
87
|
+
- `reteno-push-received`
|
|
88
|
+
- `reteno-notification-clicked`
|
|
89
|
+
|
|
90
|
+
## Pass token manually (if another plugin gets it)
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
await RetenoPlugin.setDeviceToken(token);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Use this when token callbacks are handled outside `cordova-plugin-reteno`.
|
|
97
|
+
|
|
98
|
+
## Android default notification channel update
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
RetenoPlugin.updateDefaultNotificationChannel({
|
|
102
|
+
name: 'New Channel Name',
|
|
103
|
+
description: 'New Channel Description',
|
|
104
|
+
})
|
|
105
|
+
.then(() => console.log('updateDefaultNotificationChannel: OK'))
|
|
106
|
+
.catch((err) => console.error('updateDefaultNotificationChannel: ERROR', err));
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Android notification grouping
|
|
110
|
+
|
|
111
|
+
Groups Android notifications by a value from the push payload or by a constant group ID. The rule is persisted natively and restored when the Android process starts, so it also applies to a push handled before the WebView is active.
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
// Group notifications by the `chatId` field in the push payload.
|
|
115
|
+
await RetenoPlugin.setNotificationGroupingRule({ payloadKey: 'chatId', showSummary: true });
|
|
116
|
+
|
|
117
|
+
// Or assign every Reteno notification to one constant group.
|
|
118
|
+
await RetenoPlugin.setNotificationGroupingRule({ groupId: 'messages', showSummary: true });
|
|
119
|
+
|
|
120
|
+
// Disable grouping.
|
|
121
|
+
await RetenoPlugin.setNotificationGroupingRule(null);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`showSummary` is optional and defaults to `false`. When enabled, the plugin creates and maintains an Android group-summary notification for the group ("You have N new notifications") once at least two notifications share it, and removes the summary once fewer than two remain. Without `showSummary`, grouping only sets the group key on each notification — no collapsed summary row appears unless the app posts its own summary notification.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Recommendations
|
|
2
|
+
|
|
3
|
+
## Get recommendations
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
RetenoPlugin.getRecommendations({
|
|
7
|
+
recomVariantId: 'variant-id',
|
|
8
|
+
productIds: ['product-1', 'product-2'],
|
|
9
|
+
fields: ['name', 'price', 'image', 'link'],
|
|
10
|
+
})
|
|
11
|
+
.then((result) => {
|
|
12
|
+
result.recoms.forEach((item) => {
|
|
13
|
+
console.log(item.productId, item.name);
|
|
14
|
+
});
|
|
15
|
+
})
|
|
16
|
+
.catch((err) => console.error('getRecommendations: ERROR', err));
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Category-based example:
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
RetenoPlugin.getRecommendations({
|
|
23
|
+
recomVariantId: 'variant-id',
|
|
24
|
+
categoryId: 'category-1',
|
|
25
|
+
fields: ['name', 'price'],
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
With filters:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
RetenoPlugin.getRecommendations({
|
|
33
|
+
recomVariantId: 'variant-id',
|
|
34
|
+
productIds: ['product-1'],
|
|
35
|
+
fields: ['name', 'price'],
|
|
36
|
+
filters: [{ name: 'category', values: ['shoes', 'boots'] }],
|
|
37
|
+
})
|
|
38
|
+
.then((result) => console.log('getRecommendations: OK', result))
|
|
39
|
+
.catch((err) => console.error('getRecommendations: ERROR', err));
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Log recommendation events
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
RetenoPlugin.logRecommendations({
|
|
46
|
+
recomVariantId: 'variant-id',
|
|
47
|
+
recomEvents: [
|
|
48
|
+
{
|
|
49
|
+
recomEventType: 'IMPRESSIONS',
|
|
50
|
+
occurred: new Date().toISOString(),
|
|
51
|
+
productId: 'product-1',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
recomEventType: 'CLICKS',
|
|
55
|
+
occurred: new Date().toISOString(),
|
|
56
|
+
productId: 'product-2',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
})
|
|
60
|
+
.then(() => console.log('logRecommendations: OK'))
|
|
61
|
+
.catch((err) => console.error('logRecommendations: ERROR', err));
|
|
62
|
+
```
|