reactnative-plugin-appice 1.7.42 → 1.7.44
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/TransactionalCampaign.js +60 -0
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/appice/react/AppICEUtils.java +119 -89
- package/android/src/main/java/com/appice/react/AppIceReactPluginModule.java +65 -9
- package/android/src/main/java/com/appice/react/EnumConstants.java +31 -1
- package/android/src/main/java/com/appice/react/StringConstants.java +1 -0
- package/campaign.js +43 -0
- package/example/package.json +1 -1
- package/index.js +94 -65
- package/ios/AppICEReactEvent.m +11 -2
- package/ios/AppIceReactPlugin.h +7 -1
- package/ios/AppIceReactPlugin.m +198 -60
- package/ios/AppIceReactPlugin.xcworkspace/xcuserdata/artherajesh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/package.json +2 -1
- package/reactnative-plugin-appice.podspec +1 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// ===============================
|
|
2
|
+
// TransactionalCampaign
|
|
3
|
+
// ===============================
|
|
4
|
+
const Campaign = require('./campaign');
|
|
5
|
+
|
|
6
|
+
class TransactionalCampaign extends Campaign {
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
this._data.id = null;
|
|
10
|
+
this._data.p = null;
|
|
11
|
+
this._data.name = null;
|
|
12
|
+
this._data.custom = null;
|
|
13
|
+
this._data.delay = 0;
|
|
14
|
+
this._data.users = [];
|
|
15
|
+
this._data.emails = [];
|
|
16
|
+
this._data.msisdns = [];
|
|
17
|
+
this._data.tokens = [];
|
|
18
|
+
this._data.segment = "";
|
|
19
|
+
this._data.payload = [];
|
|
20
|
+
}
|
|
21
|
+
set setCampId(v) {
|
|
22
|
+
this._data.id = v;
|
|
23
|
+
}
|
|
24
|
+
set setPlatform(v) {
|
|
25
|
+
this._data.p = v;
|
|
26
|
+
}
|
|
27
|
+
set setName(v) {
|
|
28
|
+
this._data.name = v;
|
|
29
|
+
}
|
|
30
|
+
set setCustom(v) {
|
|
31
|
+
this._data.custom = v;
|
|
32
|
+
}
|
|
33
|
+
set setDelay(v) {
|
|
34
|
+
this._data.delay = v;
|
|
35
|
+
}
|
|
36
|
+
set setUsers(v) {
|
|
37
|
+
this._data.users = v;
|
|
38
|
+
}
|
|
39
|
+
set setEmails(v) {
|
|
40
|
+
this._data.emails = v;
|
|
41
|
+
}
|
|
42
|
+
set setMsisdns(v) {
|
|
43
|
+
this._data.msisdns = v;
|
|
44
|
+
}
|
|
45
|
+
set setTokens(v) {
|
|
46
|
+
this._data.tokens = v;
|
|
47
|
+
}
|
|
48
|
+
set setSegment(v) {
|
|
49
|
+
this._data.segment = v;
|
|
50
|
+
}
|
|
51
|
+
addPayload(payloadObj) {
|
|
52
|
+
this._data.payload.push(payloadObj.toJSON());
|
|
53
|
+
}
|
|
54
|
+
toRequestPayload() {
|
|
55
|
+
return JSON.stringify(this._data);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default TransactionalCampaign;
|
|
60
|
+
module.exports = TransactionalCampaign;
|
package/android/build.gradle
CHANGED
|
@@ -97,7 +97,7 @@ dependencies {
|
|
|
97
97
|
annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.3.1"
|
|
98
98
|
|
|
99
99
|
//appice
|
|
100
|
-
implementation "appice.io.android:sdk:2.6.
|
|
100
|
+
implementation "appice.io.android:sdk:2.6.39"
|
|
101
101
|
|
|
102
102
|
//glide
|
|
103
103
|
implementation "com.github.bumptech.glide:glide:4.11.0"
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
package com.appice.react;
|
|
2
2
|
|
|
3
|
+
import static com.appice.react.AppIceReactPluginModule.isDeviceReadyFlag;
|
|
4
|
+
import static com.appice.react.AppIceReactPluginModule.pendingEventQueue;
|
|
5
|
+
|
|
3
6
|
import android.content.Context;
|
|
4
7
|
import android.content.Intent;
|
|
5
8
|
import android.os.Bundle;
|
|
@@ -8,7 +11,7 @@ import androidx.annotation.NonNull;
|
|
|
8
11
|
import androidx.annotation.Nullable;
|
|
9
12
|
|
|
10
13
|
import com.facebook.react.bridge.Arguments;
|
|
11
|
-
import com.facebook.react.bridge.
|
|
14
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
12
15
|
import com.facebook.react.bridge.ReadableArray;
|
|
13
16
|
import com.facebook.react.bridge.ReadableMap;
|
|
14
17
|
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
@@ -17,30 +20,28 @@ import com.facebook.react.bridge.WritableArray;
|
|
|
17
20
|
import com.facebook.react.bridge.WritableMap;
|
|
18
21
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
19
22
|
|
|
20
|
-
import java.util.ArrayDeque;
|
|
21
23
|
import java.util.ArrayList;
|
|
22
|
-
import java.util.
|
|
24
|
+
import java.util.Arrays;
|
|
23
25
|
import java.util.HashMap;
|
|
24
26
|
import java.util.Iterator;
|
|
25
27
|
import java.util.List;
|
|
26
28
|
import java.util.Map;
|
|
27
|
-
import java.util.concurrent.atomic.AtomicBoolean;
|
|
28
29
|
|
|
29
30
|
import org.json.JSONArray;
|
|
30
31
|
import org.json.JSONObject;
|
|
31
32
|
|
|
33
|
+
import semusi.activitysdk.ContextSdk;
|
|
34
|
+
import semusi.context.counthandler.CampaignActionListener;
|
|
32
35
|
import semusi.context.ui.appInbox.AppICEInboxMessage;
|
|
33
|
-
|
|
36
|
+
|
|
34
37
|
import semusi.context.utility.Utility;
|
|
35
38
|
import semusi.model.campaign.Campaign;
|
|
36
|
-
import semusi.model.campaign.TransactionalCampaign;
|
|
37
39
|
import semusi.model.user.User;
|
|
40
|
+
import semusi.ruleengine.pushmanager.NotificationClickHandler;
|
|
38
41
|
|
|
39
42
|
|
|
40
43
|
public class AppICEUtils {
|
|
41
44
|
private static final String TAG = "AppICEUtils";
|
|
42
|
-
static final Deque<Event> EVENT_QUEUE = new ArrayDeque<>();
|
|
43
|
-
static final AtomicBoolean IS_FLUSHING = new AtomicBoolean(false);
|
|
44
45
|
|
|
45
46
|
static class Event {
|
|
46
47
|
final String name;
|
|
@@ -52,86 +53,29 @@ public class AppICEUtils {
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
static void sendEventHelper(String eventName, @Nullable WritableMap params, ReactContext context) {
|
|
56
|
-
if (context == null || !context.hasActiveCatalystInstance()) {
|
|
57
|
-
synchronized (EVENT_QUEUE) {
|
|
58
|
-
WritableMap queued = null;
|
|
59
|
-
if (params != null) {
|
|
60
|
-
try {
|
|
61
|
-
queued = cloneReadableMap(params);
|
|
62
|
-
} catch (Exception ex) {
|
|
63
|
-
printLog(TAG, "sendEvent: failed to clone params for queue " + eventName + " - " + ex.getMessage());
|
|
64
|
-
queued = null;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
EVENT_QUEUE.add(new Event(eventName, queued));
|
|
68
|
-
}
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
WritableMap emitCopy = null;
|
|
73
|
-
if (params != null) {
|
|
74
|
-
try {
|
|
75
|
-
emitCopy = cloneReadableMap(params);
|
|
76
|
-
} catch (Exception ex) {
|
|
77
|
-
emitCopy = null;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
83
|
-
.emit(eventName, emitCopy);
|
|
84
|
-
printLog(TAG, "Successfully emitted event: " + eventName);
|
|
85
|
-
} catch (Exception e) {
|
|
86
|
-
printLog(TAG, "emit failed for " + eventName + " - " + e.getMessage());
|
|
87
|
-
synchronized (EVENT_QUEUE) {
|
|
88
|
-
WritableMap queued = null;
|
|
89
|
-
if (params != null) {
|
|
90
|
-
try {
|
|
91
|
-
queued = cloneReadableMap(params);
|
|
92
|
-
} catch (Exception ex) {
|
|
93
|
-
queued = null;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
EVENT_QUEUE.add(new Event(eventName, queued));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
56
|
|
|
101
|
-
|
|
102
|
-
|
|
57
|
+
// removed old logic that became overcomplicated with AI. later on when I reworked think
|
|
58
|
+
//of using different approach which flushevent when flag got updated
|
|
59
|
+
protected static void flushEventQueue(ReactApplicationContext ctx) {
|
|
60
|
+
if (!isDeviceReadyFlag || pendingEventQueue.isEmpty()) {
|
|
61
|
+
printLog("ActionPushDebug flushEventQueue", "Nothing to flush. flag=" + isDeviceReadyFlag + " queueSize=" + pendingEventQueue.size());
|
|
103
62
|
return;
|
|
104
63
|
}
|
|
105
64
|
|
|
106
|
-
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
65
|
+
printLog("ActionPushDebug flushEventQueue", "Flushing " + pendingEventQueue.size() + " events");
|
|
109
66
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
toEmit = event.params;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
125
|
-
.emit(event.name, toEmit);
|
|
126
|
-
printLog(TAG, "Successfully flushed event: " + event.name + ". Remaining in queue: " + EVENT_QUEUE.size());
|
|
127
|
-
} catch (Exception e) {
|
|
128
|
-
EVENT_QUEUE.addFirst(event);
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
67
|
+
List<Map<String, Object>> toFlush = new ArrayList<>(pendingEventQueue);
|
|
68
|
+
pendingEventQueue.clear();
|
|
69
|
+
|
|
70
|
+
for (Map<String, Object> event : toFlush) {
|
|
71
|
+
try {
|
|
72
|
+
String eventName = (String) event.get("eventName");
|
|
73
|
+
WritableMap params = (WritableMap) event.get("param");
|
|
74
|
+
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
|
|
75
|
+
printLog("ActionPushDebug flushEventQueue", "Flushed: " + eventName);
|
|
76
|
+
} catch (Exception e) {
|
|
77
|
+
printLog("ActionPushDebug flushEventQueue", "Flush failed: " + e.getMessage());
|
|
132
78
|
}
|
|
133
|
-
} finally {
|
|
134
|
-
IS_FLUSHING.set(false);
|
|
135
79
|
}
|
|
136
80
|
}
|
|
137
81
|
|
|
@@ -295,7 +239,6 @@ public class AppICEUtils {
|
|
|
295
239
|
}
|
|
296
240
|
|
|
297
241
|
|
|
298
|
-
|
|
299
242
|
public static WritableMap toWritableMap(Map<String, Object> map) {
|
|
300
243
|
WritableMap writableMap = Arguments.createMap();
|
|
301
244
|
Iterator iterator = map.entrySet().iterator();
|
|
@@ -452,7 +395,7 @@ public class AppICEUtils {
|
|
|
452
395
|
}
|
|
453
396
|
}
|
|
454
397
|
return jsonObject;
|
|
455
|
-
}catch (Throwable t){
|
|
398
|
+
} catch (Throwable t) {
|
|
456
399
|
return null;
|
|
457
400
|
}
|
|
458
401
|
}
|
|
@@ -487,7 +430,7 @@ public class AppICEUtils {
|
|
|
487
430
|
}
|
|
488
431
|
}
|
|
489
432
|
return jsonArray;
|
|
490
|
-
}catch (Throwable t){
|
|
433
|
+
} catch (Throwable t) {
|
|
491
434
|
return null;
|
|
492
435
|
}
|
|
493
436
|
}
|
|
@@ -496,9 +439,10 @@ public class AppICEUtils {
|
|
|
496
439
|
System.out.println(TAG + ", " + message);
|
|
497
440
|
}
|
|
498
441
|
|
|
499
|
-
|
|
442
|
+
|
|
443
|
+
public static boolean handleAppICEPayload(@NonNull Intent intent, Context context) {
|
|
500
444
|
try {
|
|
501
|
-
if (intent.getExtras() != null){
|
|
445
|
+
if (intent.getExtras() != null) {
|
|
502
446
|
Bundle bundle = intent.getExtras();
|
|
503
447
|
boolean isAppICEPush = bundle.getBoolean("ai_push", false);
|
|
504
448
|
if (isAppICEPush) {
|
|
@@ -507,9 +451,95 @@ public class AppICEUtils {
|
|
|
507
451
|
intent.removeExtra("ai_push");
|
|
508
452
|
}
|
|
509
453
|
}
|
|
510
|
-
}catch (Throwable t){
|
|
511
|
-
printLog("PUSH", " exception in click "+t);
|
|
454
|
+
} catch (Throwable t) {
|
|
455
|
+
printLog("PUSH", " exception in click " + t);
|
|
512
456
|
}
|
|
513
457
|
return false;
|
|
514
458
|
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Handles app link actions triggered from a notification click.
|
|
462
|
+
* <p>
|
|
463
|
+
* Flow:
|
|
464
|
+
* 1. Extracts NotificationClickHandler from the incoming Intent.
|
|
465
|
+
* 2. Retrieves the payload associated with the notification.
|
|
466
|
+
* 3. Validates the payload before processing.
|
|
467
|
+
* 4. If valid:
|
|
468
|
+
* - Triggers deep link handling via ContextSdk.handleOpenLinkUrl().
|
|
469
|
+
* - Logs the click event via ContextSdk.pushNotificationClicked().
|
|
470
|
+
* - Clears the intent to prevent duplicate processing.
|
|
471
|
+
* <p>
|
|
472
|
+
* Edge Cases Handled:
|
|
473
|
+
* - Null intent
|
|
474
|
+
* - Missing or invalid NotificationClickHandler
|
|
475
|
+
* - Empty or invalid payload
|
|
476
|
+
* - Any unexpected runtime exception
|
|
477
|
+
*
|
|
478
|
+
* @param intent Incoming intent containing notification click data
|
|
479
|
+
* @param context Application context used for handling actions
|
|
480
|
+
*/
|
|
481
|
+
public static void handleAppLink(Intent intent, Context context) {
|
|
482
|
+
try {
|
|
483
|
+
if (intent != null) {
|
|
484
|
+
NotificationClickHandler clickHandler = NotificationClickHandler.fromIntent(intent);
|
|
485
|
+
if (clickHandler != null) {
|
|
486
|
+
String payload = clickHandler.getPayload();
|
|
487
|
+
printLog("handleAppLink","handleAppLink payload " + payload);
|
|
488
|
+
if (Utility.isValidObject(payload)) {
|
|
489
|
+
ContextSdk.handleOpenLinkUrl(payload, context);
|
|
490
|
+
ContextSdk.pushNotificationClicked(payload, context);
|
|
491
|
+
clickHandler.deleteIntent(intent);
|
|
492
|
+
} else
|
|
493
|
+
printLog("handleAppLink","payload is not valid");
|
|
494
|
+
}
|
|
495
|
+
} else
|
|
496
|
+
printLog("handleAppLink","intent is null ");
|
|
497
|
+
} catch (Throwable e) {
|
|
498
|
+
printLog("handleAppLink","exception in null ");
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// this function will handle both normal push and action button push.
|
|
503
|
+
// through listner user will identify.
|
|
504
|
+
public static void handleClickOnPush(Intent intent, Context context) {
|
|
505
|
+
try {
|
|
506
|
+
if (intent != null) {
|
|
507
|
+
if (intent.getExtras() != null) {
|
|
508
|
+
Bundle bundle = intent.getExtras();
|
|
509
|
+
boolean isAppICEPush = bundle.getBoolean("ai_push", false);
|
|
510
|
+
if (isAppICEPush) {
|
|
511
|
+
CampaignCampsReceiver campsReceiver = new CampaignCampsReceiver();
|
|
512
|
+
campsReceiver.sendCallback(bundle, context);
|
|
513
|
+
intent.removeExtra("ai_push");
|
|
514
|
+
}else {
|
|
515
|
+
NotificationClickHandler.handleClickCallback(intent, context, new CampaignActionListener() {
|
|
516
|
+
@Override
|
|
517
|
+
public void onActionButtonClicked(Campaign campaign) {
|
|
518
|
+
WritableMap params = Arguments.createMap();
|
|
519
|
+
JSONObject campaignJson = campaign.toJson();
|
|
520
|
+
|
|
521
|
+
if (campaignJson != null && campaignJson.length() > 0) {
|
|
522
|
+
String campaignStr = campaignJson.toString();
|
|
523
|
+
params.putString(EnumConstants.APPICE_PUSH_NOTIFICATION_ACTION_BUTTON_CLICKED.getValue(), campaignStr);
|
|
524
|
+
|
|
525
|
+
printLog("ActionPushDebug onActionButtonClicked", "action button clicked | campaign: " + campaignStr);
|
|
526
|
+
printLog("ActionPushDebug onActionButtonClicked", "isDeviceReadyFlag: " + isDeviceReadyFlag);
|
|
527
|
+
printLog("ActionPushDebug onActionButtonClicked", "queue size before send: " + pendingEventQueue.size());
|
|
528
|
+
|
|
529
|
+
AppIceReactPluginModule.sendEvent(EnumConstants.APPICE_PUSH_NOTIFICATION_ACTION_BUTTON_CLICKED.getValue(), params);
|
|
530
|
+
|
|
531
|
+
printLog("ActionPushDebug onActionButtonClicked", "queue size after send: " + pendingEventQueue.size());
|
|
532
|
+
} else {
|
|
533
|
+
printLog("ActionPushDebug onActionButtonClicked", "campaignJson is null or empty — event NOT sent");
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
} else
|
|
540
|
+
printLog("ActionPushDebug", " | intent is null ");
|
|
541
|
+
} catch (Throwable e) {
|
|
542
|
+
printLog("ActionPushDebug"," | exception in null ");
|
|
543
|
+
}
|
|
544
|
+
}
|
|
515
545
|
}
|
|
@@ -20,7 +20,9 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
|
20
20
|
import com.facebook.react.bridge.ReactMethod;
|
|
21
21
|
import com.facebook.react.bridge.ReadableMap;
|
|
22
22
|
|
|
23
|
+
|
|
23
24
|
import android.os.Handler;
|
|
25
|
+
|
|
24
26
|
import semusi.activitysdk.Api;
|
|
25
27
|
import semusi.activitysdk.ContextSdk;
|
|
26
28
|
import semusi.activitysdk.IAppICEDeviceRegisterCallback;
|
|
@@ -34,6 +36,7 @@ import semusi.model.campaign.TransactionalCampaign;
|
|
|
34
36
|
import semusi.model.user.User;
|
|
35
37
|
|
|
36
38
|
import java.util.*;
|
|
39
|
+
import java.util.concurrent.ConcurrentHashMap;
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
import androidx.annotation.NonNull;
|
|
@@ -43,6 +46,7 @@ import com.facebook.react.bridge.ReadableArray;
|
|
|
43
46
|
import com.facebook.react.bridge.WritableArray;
|
|
44
47
|
import com.facebook.react.bridge.WritableMap;
|
|
45
48
|
import com.facebook.react.module.annotations.ReactModule;
|
|
49
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
46
50
|
|
|
47
51
|
import org.json.JSONObject;
|
|
48
52
|
|
|
@@ -50,6 +54,9 @@ import org.json.JSONObject;
|
|
|
50
54
|
public class AppIceReactPluginModule extends ReactContextBaseJavaModule {
|
|
51
55
|
private static ReactApplicationContext context = null;
|
|
52
56
|
public static final String NAME = "AppIceReactPlugin";
|
|
57
|
+
protected static volatile boolean isDeviceReadyFlag;
|
|
58
|
+
protected static final List<Map<String, Object>> pendingEventQueue =
|
|
59
|
+
Collections.synchronizedList(new ArrayList<>());
|
|
53
60
|
|
|
54
61
|
public AppIceReactPluginModule(ReactApplicationContext reactContext) {
|
|
55
62
|
super(reactContext);
|
|
@@ -97,7 +104,8 @@ public class AppIceReactPluginModule extends ReactContextBaseJavaModule {
|
|
|
97
104
|
, context);
|
|
98
105
|
|
|
99
106
|
Api.startContext(context, config);
|
|
100
|
-
|
|
107
|
+
String token= ContextSdk.getFCMToken(context);
|
|
108
|
+
printLog("AppICE","| firebase token = "+token);
|
|
101
109
|
} catch (Exception e) {
|
|
102
110
|
printLog(NAME, "Exception in startContext : " + e);
|
|
103
111
|
}
|
|
@@ -637,17 +645,30 @@ public class AppIceReactPluginModule extends ReactContextBaseJavaModule {
|
|
|
637
645
|
Context context = getReactApplicationContext();
|
|
638
646
|
callback.invoke(ContextSdk.getInternalId(context));
|
|
639
647
|
}
|
|
640
|
-
|
|
641
|
-
public void
|
|
642
|
-
if (
|
|
643
|
-
|
|
644
|
-
|
|
648
|
+
|
|
649
|
+
public static void sendEvent(String eventName, @Nullable WritableMap params) {
|
|
650
|
+
if (isDeviceReadyFlag) {
|
|
651
|
+
try {
|
|
652
|
+
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
|
|
653
|
+
printLog("ActionPushDebug sendEvent", "Successfully emitted event: " + eventName);
|
|
654
|
+
} catch (Exception e) {
|
|
655
|
+
printLog("ActionPushDebug sendEvent", "emit failed for " + eventName + " - " + e.getMessage());
|
|
656
|
+
}
|
|
657
|
+
} else {
|
|
658
|
+
Map<String, Object> pending = new HashMap<>();
|
|
659
|
+
pending.put("eventName", eventName);
|
|
660
|
+
pending.put("param", params);
|
|
661
|
+
pendingEventQueue.add(pending);
|
|
662
|
+
printLog("ActionPushDebug sendEvent", "Queued event: " + eventName + " Queue size: " + pendingEventQueue.size());
|
|
645
663
|
}
|
|
646
664
|
}
|
|
647
665
|
|
|
648
|
-
|
|
649
|
-
public
|
|
650
|
-
|
|
666
|
+
@ReactMethod
|
|
667
|
+
public void isDeviceReady(Boolean flag) {
|
|
668
|
+
ReactApplicationContext ctx = getReactApplicationContext();
|
|
669
|
+
isDeviceReadyFlag = flag;
|
|
670
|
+
printLog("ActionPushDebug", "isDeviceReadyFlag " + isDeviceReadyFlag);
|
|
671
|
+
flushEventQueue(ctx);
|
|
651
672
|
}
|
|
652
673
|
|
|
653
674
|
private static AppICEInboxMessage getMediaPreProcessing(ReadableMap inboxMessage,Context context) {
|
|
@@ -863,6 +884,7 @@ public class AppIceReactPluginModule extends ReactContextBaseJavaModule {
|
|
|
863
884
|
@ReactMethod
|
|
864
885
|
public void scheduleTransactionalCampaign(String transactionalStringPayload){
|
|
865
886
|
Context context = getReactApplicationContext();
|
|
887
|
+
printLog("AppIceReactPluginModule", "scheduleTransactionalCampaign, payload = "+transactionalStringPayload );
|
|
866
888
|
TransactionalCampaign transactionalCampaign = TransactionalCampaign.toTransactionalCampaign(transactionalStringPayload);
|
|
867
889
|
ContextSdk.scheduleCampaign(transactionalCampaign, context);
|
|
868
890
|
}
|
|
@@ -883,6 +905,35 @@ public class AppIceReactPluginModule extends ReactContextBaseJavaModule {
|
|
|
883
905
|
}
|
|
884
906
|
}
|
|
885
907
|
|
|
908
|
+
//======================================================
|
|
909
|
+
// INAPP
|
|
910
|
+
//======================================================
|
|
911
|
+
|
|
912
|
+
@ReactMethod
|
|
913
|
+
public void resumeInApp(){
|
|
914
|
+
Context context = getReactApplicationContext();
|
|
915
|
+
ContextSdk.resumeInApp(context);
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
@ReactMethod
|
|
919
|
+
public void suspendInApp(){
|
|
920
|
+
Context context = getReactApplicationContext();
|
|
921
|
+
ContextSdk.suspendInApp(context);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
@ReactMethod
|
|
925
|
+
public void discardInApp(){
|
|
926
|
+
Context context = getReactApplicationContext();
|
|
927
|
+
ContextSdk.discardInApp(context);
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
@ReactMethod
|
|
931
|
+
public void dismissInApp(){
|
|
932
|
+
ContextSdk.dismissInApp();
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
//================================================================
|
|
936
|
+
|
|
886
937
|
@Nullable
|
|
887
938
|
@Override
|
|
888
939
|
public Map<String, Object> getConstants() {
|
|
@@ -899,6 +950,7 @@ public class AppIceReactPluginModule extends ReactContextBaseJavaModule {
|
|
|
899
950
|
constants.put(EnumConstants.APPICE_USER_AGE.getConstants(), EnumConstants.APPICE_USER_AGE.getValue());
|
|
900
951
|
constants.put(EnumConstants.APPICE_USER_GENDER.getConstants(), EnumConstants.APPICE_USER_GENDER.getValue());
|
|
901
952
|
constants.put(EnumConstants.APPICE_PUSH_NOTIFICATION_CLICKED.getConstants(), EnumConstants.APPICE_PUSH_NOTIFICATION_CLICKED.getValue());
|
|
953
|
+
constants.put(EnumConstants.APPICE_PUSH_NOTIFICATION_ACTION_BUTTON_CLICKED.getConstants(), EnumConstants.APPICE_PUSH_NOTIFICATION_ACTION_BUTTON_CLICKED.getValue());
|
|
902
954
|
constants.put(EnumConstants.APPICE_INAPP_NOTIFICATION_CLICKED.getConstants(), EnumConstants.APPICE_INAPP_NOTIFICATION_CLICKED.getValue());
|
|
903
955
|
constants.put(EnumConstants.FIRST_SEEN.getConstants(), EnumConstants.FIRST_SEEN.getValue());
|
|
904
956
|
constants.put(EnumConstants.LAST_SEEN.getConstants(), EnumConstants.LAST_SEEN.getValue());
|
|
@@ -921,6 +973,10 @@ public class AppIceReactPluginModule extends ReactContextBaseJavaModule {
|
|
|
921
973
|
constants.put(EnumConstants.ACTION_URL.getConstants(), EnumConstants.ACTION_URL.getValue());
|
|
922
974
|
constants.put(EnumConstants.ACTION_TYPE.getConstants(), EnumConstants.ACTION_TYPE.getValue());
|
|
923
975
|
constants.put(EnumConstants.CUSTOMDATA.getConstants(), EnumConstants.CUSTOMDATA.getValue());
|
|
976
|
+
constants.put(EnumConstants.ACTION_TYPE_CUSTOM.getConstants(), EnumConstants.ACTION_TYPE_CUSTOM.getValue());
|
|
977
|
+
constants.put(EnumConstants.ACTION_TYPE_DEEPLINK.getConstants(), EnumConstants.ACTION_TYPE_DEEPLINK.getValue());
|
|
978
|
+
constants.put(EnumConstants.ACTION_TYPE_REPLY.getConstants(), EnumConstants.ACTION_TYPE_REPLY.getValue());
|
|
979
|
+
constants.put(EnumConstants.ACTION_TYPE_REMIND_ME_LATER.getConstants(), EnumConstants.ACTION_TYPE_REMIND_ME_LATER.getValue());
|
|
924
980
|
|
|
925
981
|
return constants;
|
|
926
982
|
}
|
|
@@ -31,6 +31,7 @@ public enum EnumConstants {
|
|
|
31
31
|
//PUSH
|
|
32
32
|
//============================
|
|
33
33
|
APPICE_PUSH_NOTIFICATION_CLICKED("AppICEPushNotificationClicked"),
|
|
34
|
+
APPICE_PUSH_NOTIFICATION_ACTION_BUTTON_CLICKED("AppICEPushNotificationActionButtonClicked"),
|
|
34
35
|
|
|
35
36
|
//===========================
|
|
36
37
|
//IN-APP
|
|
@@ -88,7 +89,16 @@ public enum EnumConstants {
|
|
|
88
89
|
CAMP_ID("CAMP_ID"),
|
|
89
90
|
ACTION_URL("ACTION_URL"),
|
|
90
91
|
ACTION_TYPE("ACTION_TYPE"),
|
|
91
|
-
CUSTOMDATA("CUSTOMDATA")
|
|
92
|
+
CUSTOMDATA("CUSTOMDATA"),
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
//=======================
|
|
96
|
+
// ACTION TYPES
|
|
97
|
+
//=======================
|
|
98
|
+
ACTION_TYPE_CUSTOM("ACTION_TYPE_CUSTOM"),
|
|
99
|
+
ACTION_TYPE_DEEPLINK("ACTION_TYPE_DEEPLINK"),
|
|
100
|
+
ACTION_TYPE_REPLY("ACTION_TYPE_REPLY"),
|
|
101
|
+
ACTION_TYPE_REMIND_ME_LATER("ACTION_TYPE_REMIND_ME_LATER");
|
|
92
102
|
|
|
93
103
|
private String constants;
|
|
94
104
|
|
|
@@ -148,6 +158,10 @@ public enum EnumConstants {
|
|
|
148
158
|
return StringConstants.APPICE_PUSH_NOTIFICATION_CLICKED;
|
|
149
159
|
}
|
|
150
160
|
|
|
161
|
+
case APPICE_PUSH_NOTIFICATION_ACTION_BUTTON_CLICKED:{
|
|
162
|
+
return StringConstants.APPICE_PUSH_NOTIFICATION_ACTION_BUTTON_CLICKED;
|
|
163
|
+
}
|
|
164
|
+
|
|
151
165
|
case APPICE_INAPP_NOTIFICATION_CLICKED:{
|
|
152
166
|
return StringConstants.APPICE_INAPP_NOTIFICATION_CLICKED;
|
|
153
167
|
}
|
|
@@ -272,6 +286,22 @@ public enum EnumConstants {
|
|
|
272
286
|
case CUSTOMDATA:{
|
|
273
287
|
return CUSTOM_DATA;
|
|
274
288
|
}
|
|
289
|
+
|
|
290
|
+
case ACTION_TYPE_CUSTOM:{
|
|
291
|
+
return CampaignConstants.CUSTOM;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
case ACTION_TYPE_DEEPLINK:{
|
|
295
|
+
return CampaignConstants.DEEP_LINK;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
case ACTION_TYPE_REPLY:{
|
|
299
|
+
return CampaignConstants.REPLY;
|
|
300
|
+
}
|
|
301
|
+
case ACTION_TYPE_REMIND_ME_LATER:{
|
|
302
|
+
return CampaignConstants.REMIND_LATER;
|
|
303
|
+
}
|
|
304
|
+
|
|
275
305
|
default:
|
|
276
306
|
return "";
|
|
277
307
|
}
|
|
@@ -8,6 +8,7 @@ public interface StringConstants{
|
|
|
8
8
|
String MEDIA_THUMBNAIL = "mediaThumbnail";
|
|
9
9
|
String MEDIA_DATA = "mediaData";
|
|
10
10
|
String APPICE_PUSH_NOTIFICATION_CLICKED = "AppICEPushNotificationClicked";
|
|
11
|
+
String APPICE_PUSH_NOTIFICATION_ACTION_BUTTON_CLICKED = "AppICEPushNotificationActionButtonClicked";
|
|
11
12
|
String APPICE_INAPP_NOTIFICATION_CLICKED = "AppICEInAppClicked";
|
|
12
13
|
String INBOX_MESSAGE = "message";
|
|
13
14
|
String INBOX_TITLE = "title";
|
package/campaign.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const { Linking, Platform } = require('react-native');
|
|
2
2
|
|
|
3
3
|
async function handleClickOnPush(campaign) {
|
|
4
|
+
if (campaign && campaign._data) {
|
|
5
|
+
campaign = campaign._data;
|
|
6
|
+
}
|
|
7
|
+
|
|
4
8
|
const url = campaign.actionUrl || campaign.acu || campaign.eurl;
|
|
5
9
|
const actionType = campaign.actionType || campaign.act || campaign.et;
|
|
6
10
|
|
|
@@ -14,6 +18,7 @@ async function handleClickOnPush(campaign) {
|
|
|
14
18
|
if (httpUrls) {
|
|
15
19
|
try {
|
|
16
20
|
if (Platform.OS === 'ios') {
|
|
21
|
+
campaign = normalizeCampaignPayloadForPlatform(campaign);
|
|
17
22
|
return campaign;
|
|
18
23
|
// iOS handle redirection on native side for landing page.
|
|
19
24
|
}
|
|
@@ -31,6 +36,28 @@ async function handleClickOnPush(campaign) {
|
|
|
31
36
|
}
|
|
32
37
|
}
|
|
33
38
|
|
|
39
|
+
|
|
40
|
+
const PAYLOAD_KEYS = Object.freeze({
|
|
41
|
+
DATA: 'data',
|
|
42
|
+
MESSAGE: 'message',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// iOS push click payload often nests campaign fields under data.message.
|
|
46
|
+
// Android payload already comes in campaign shape.
|
|
47
|
+
function normalizeCampaignPayloadForPlatform(data) {
|
|
48
|
+
if (!data || typeof data !== 'object') return data;
|
|
49
|
+
if (Platform.OS !== 'ios') return data;
|
|
50
|
+
|
|
51
|
+
const dataNode = data[PAYLOAD_KEYS.DATA];
|
|
52
|
+
if (!dataNode || typeof dataNode !== 'object') return data;
|
|
53
|
+
|
|
54
|
+
const messageNode = dataNode[PAYLOAD_KEYS.MESSAGE];
|
|
55
|
+
if (messageNode && typeof messageNode === 'object') {
|
|
56
|
+
return messageNode;
|
|
57
|
+
}
|
|
58
|
+
return data;
|
|
59
|
+
}
|
|
60
|
+
|
|
34
61
|
// ===============================
|
|
35
62
|
// Campaign (merged backward-compatible)
|
|
36
63
|
// ===============================
|
|
@@ -46,6 +73,9 @@ class Campaign {
|
|
|
46
73
|
// if parse fails, keep eventData as-is (object expected)
|
|
47
74
|
data = eventData || {};
|
|
48
75
|
}
|
|
76
|
+
|
|
77
|
+
// Keep app-side listener thin by normalizing payload shape in campaign layer.
|
|
78
|
+
data = normalizeCampaignPayloadForPlatform(data);
|
|
49
79
|
const isLegacy = data && (data.camp_id || data.eurl || data.et || data.abt || data.act || data.acc);
|
|
50
80
|
|
|
51
81
|
if (isLegacy) {
|
|
@@ -200,6 +230,19 @@ class Campaign {
|
|
|
200
230
|
return this._data.customData ? this._data.customData[key] || '' : '';
|
|
201
231
|
}
|
|
202
232
|
|
|
233
|
+
//Action button
|
|
234
|
+
getSelectedActionTitle() {
|
|
235
|
+
return this._data.selectedActionTitle;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
getSelectedActionType() {
|
|
239
|
+
return this._data.selectedActionType;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
getSelectedActionUrl() {
|
|
243
|
+
return this._data.selectedActionUrl;
|
|
244
|
+
}
|
|
245
|
+
|
|
203
246
|
// Convert to JSON
|
|
204
247
|
toJSON() {
|
|
205
248
|
return this._data;
|