Skip to content

Commit bd6cf8d

Browse files
sumeruchatevantk91Evan Greer
authoredJan 10, 2025
MOB-10364 Support for In App JSON Only Messages (#857)
* [MOB-10364] some work on in app json only messages * [MOB-10364] fix the test * [MOB-10364] Rewrite of logic and tests * [MOB-10364] Add editorconfig * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * updates json only flag parsing * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom * [MOB-10364] Update according to new discussiom --------- Co-authored-by: Evan Takeo Kanaiaupuni Greer <[email protected]> Co-authored-by: Evan Greer <[email protected]>
1 parent fc8e552 commit bd6cf8d

File tree

9 files changed

+531
-43
lines changed

9 files changed

+531
-43
lines changed
 

Diff for: ‎.editorconfig

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 4
6+
tab_width = 4

Diff for: ‎iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,11 @@ private void onForeground() {
398398
fetchRemoteConfiguration();
399399
}
400400

401+
if (_applicationContext == null || sharedInstance.getMainActivityContext() == null) {
402+
IterableLogger.w(TAG, "onForeground: _applicationContext is null");
403+
return;
404+
}
405+
401406
boolean systemNotificationEnabled = NotificationManagerCompat.from(_applicationContext).areNotificationsEnabled();
402407
SharedPreferences sharedPref = sharedInstance.getMainActivityContext().getSharedPreferences(IterableConstants.SHARED_PREFS_FILE, Context.MODE_PRIVATE);
403408

@@ -1435,4 +1440,4 @@ public void trackEmbeddedSession(@NonNull IterableEmbeddedSession session) {
14351440
apiClient.trackEmbeddedSession(session);
14361441
}
14371442
//endregion
1438-
}
1443+
}

Diff for: ‎iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java

+1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ public final class IterableConstants {
221221
public static final String ITERABLE_IN_APP_BUTTONS = "buttons";
222222
public static final String ITERABLE_IN_APP_COLOR = "color";
223223
public static final String ITERABLE_IN_APP_CONTENT = "content";
224+
public static final String ITERABLE_IN_APP_JSON_ONLY = "jsonOnly";
224225
public static final String ITERABLE_IN_APP_COUNT = "count";
225226
public static final String ITERABLE_IN_APP_MAIN_IMAGE = "mainImage";
226227
public static final String ITERABLE_IN_APP_MESSAGE = "inAppMessages";

Diff for: ‎iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppDisplayer.java

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ boolean isShowingInApp() {
2020
}
2121

2222
boolean showMessage(@NonNull IterableInAppMessage message, IterableInAppLocation location, @NonNull final IterableHelper.IterableUrlCallback clickCallback) {
23+
// Early return for JSON-only messages
24+
if (message.isJsonOnly()) {
25+
return false;
26+
}
27+
2328
Activity currentActivity = activityMonitor.getCurrentActivity();
2429
// Prevent double display
2530
if (currentActivity != null) {

Diff for: ‎iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,6 @@ private void processMessages() {
405405
IterableLogger.printInfo();
406406

407407
List<IterableInAppMessage> messages = getMessages();
408-
409408
List<IterableInAppMessage> messagesByPriorityLevel = getMessagesSortedByPriorityLevel(messages);
410409

411410
for (IterableInAppMessage message : messagesByPriorityLevel) {
@@ -414,6 +413,14 @@ private void processMessages() {
414413
InAppResponse response = handler.onNewInApp(message);
415414
IterableLogger.d(TAG, "Response: " + response);
416415
message.setProcessed(true);
416+
417+
if (message.isJsonOnly()) {
418+
setRead(message, true, null, null);
419+
message.setConsumed(true);
420+
api.inAppConsume(message, null, null, null, null);
421+
return;
422+
}
423+
417424
if (response == InAppResponse.SHOW) {
418425
boolean consume = !message.isInboxMessage();
419426
showMessage(message, consume, null);
@@ -519,4 +526,4 @@ public void run() {
519526
}
520527
});
521528
}
522-
}
529+
}

Diff for: ‎iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppMessage.java

+64-38
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class IterableInAppMessage {
3131
private boolean loadedHtmlFromJson = false;
3232
private boolean markedForDeletion = false;
3333
private @Nullable IterableInAppStorage inAppStorageInterface;
34+
private final boolean jsonOnly;
3435

3536
IterableInAppMessage(@NonNull String messageId,
3637
@NonNull Content content,
@@ -41,7 +42,8 @@ public class IterableInAppMessage {
4142
@NonNull Double priorityLevel,
4243
@Nullable Boolean saveToInbox,
4344
@Nullable InboxMetadata inboxMetadata,
44-
@Nullable Long campaignId) {
45+
@Nullable Long campaignId,
46+
boolean jsonOnly) {
4547

4648
this.messageId = messageId;
4749
this.content = content;
@@ -50,9 +52,10 @@ public class IterableInAppMessage {
5052
this.expiresAt = expiresAt;
5153
this.trigger = trigger;
5254
this.priorityLevel = priorityLevel;
53-
this.saveToInbox = saveToInbox;
55+
this.saveToInbox = saveToInbox != null ? (saveToInbox && !jsonOnly) : null;
5456
this.inboxMetadata = inboxMetadata;
5557
this.campaignId = campaignId;
58+
this.jsonOnly = jsonOnly;
5659
}
5760

5861
static class Trigger {
@@ -246,7 +249,7 @@ public Date getExpiresAt() {
246249

247250
@NonNull
248251
public Content getContent() {
249-
if (content.html == null) {
252+
if (content.html == null && !jsonOnly) {
250253
content.html = inAppStorageInterface.getHTML(messageId);
251254
}
252255
return content;
@@ -322,70 +325,87 @@ public void markForDeletion(boolean delete) {
322325
this.markedForDeletion = delete;
323326
}
324327

328+
public boolean isJsonOnly() {
329+
return jsonOnly;
330+
}
331+
325332
static IterableInAppMessage fromJSONObject(@NonNull JSONObject messageJson, @Nullable IterableInAppStorage storageInterface) {
326333

327334
if (messageJson == null) {
328335
return null;
329336
}
330337

331-
JSONObject contentJson = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_CONTENT);
332-
if (contentJson == null) {
333-
return null;
334-
}
335-
336338
String messageId = messageJson.optString(IterableConstants.KEY_MESSAGE_ID);
337339
final Long campaignId = IterableUtil.retrieveValidCampaignIdOrNull(messageJson, IterableConstants.KEY_CAMPAIGN_ID);
340+
boolean jsonOnly = messageJson.optBoolean(IterableConstants.ITERABLE_IN_APP_JSON_ONLY, false);
341+
342+
JSONObject customPayload = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_CUSTOM_PAYLOAD);
343+
if (customPayload == null && jsonOnly) {
344+
customPayload = new JSONObject();
345+
}
346+
347+
Content content;
348+
if (jsonOnly) {
349+
content = new Content("", new Rect(), 0.0, false, new InAppDisplaySettings(false, new InAppBgColor(null, 0.0f)));
350+
} else {
351+
JSONObject contentJson = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_CONTENT);
352+
if (contentJson == null) {
353+
return null;
354+
}
355+
if (customPayload == null) {
356+
customPayload = contentJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_LEGACY_PAYLOAD);
357+
}
358+
359+
String html = contentJson.optString(IterableConstants.ITERABLE_IN_APP_HTML, null);
360+
JSONObject inAppDisplaySettingsJson = contentJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_DISPLAY_SETTINGS);
361+
Rect padding = getPaddingFromPayload(inAppDisplaySettingsJson);
362+
double backgroundAlpha = contentJson.optDouble(IterableConstants.ITERABLE_IN_APP_BACKGROUND_ALPHA, 0);
363+
boolean shouldAnimate = inAppDisplaySettingsJson.optBoolean(IterableConstants.ITERABLE_IN_APP_SHOULD_ANIMATE, false);
364+
JSONObject bgColorJson = inAppDisplaySettingsJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_BGCOLOR);
365+
366+
String bgColorInHex = null;
367+
double bgAlpha = 0.0f;
368+
if (bgColorJson != null) {
369+
bgColorInHex = bgColorJson.optString(IterableConstants.ITERABLE_IN_APP_BGCOLOR_HEX);
370+
bgAlpha = bgColorJson.optDouble(IterableConstants.ITERABLE_IN_APP_BGCOLOR_ALPHA);
371+
}
372+
373+
InAppDisplaySettings inAppDisplaySettings = new InAppDisplaySettings(shouldAnimate, new InAppBgColor(bgColorInHex, bgAlpha));
374+
content = new Content(html, padding, backgroundAlpha, shouldAnimate, inAppDisplaySettings);
375+
}
376+
338377
long createdAtLong = messageJson.optLong(IterableConstants.ITERABLE_IN_APP_CREATED_AT);
339378
Date createdAt = createdAtLong != 0 ? new Date(createdAtLong) : null;
340379
long expiresAtLong = messageJson.optLong(IterableConstants.ITERABLE_IN_APP_EXPIRES_AT);
341380
Date expiresAt = expiresAtLong != 0 ? new Date(expiresAtLong) : null;
342381

343-
String html = contentJson.optString(IterableConstants.ITERABLE_IN_APP_HTML, null);
344-
JSONObject inAppDisplaySettingsJson = contentJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_DISPLAY_SETTINGS);
345-
Rect padding = getPaddingFromPayload(inAppDisplaySettingsJson);
346-
double backgroundAlpha = contentJson.optDouble(IterableConstants.ITERABLE_IN_APP_BACKGROUND_ALPHA, 0);
347-
boolean shouldAnimate = inAppDisplaySettingsJson.optBoolean(IterableConstants.ITERABLE_IN_APP_SHOULD_ANIMATE, false);
348-
JSONObject bgColorJson = inAppDisplaySettingsJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_BGCOLOR);
349-
350-
String bgColorInHex = null;
351-
double bgAlpha = 0.0f;
352-
if (bgColorJson != null) {
353-
bgColorInHex = bgColorJson.optString(IterableConstants.ITERABLE_IN_APP_BGCOLOR_HEX);
354-
bgAlpha = bgColorJson.optDouble(IterableConstants.ITERABLE_IN_APP_BGCOLOR_ALPHA);
355-
}
356-
357-
InAppDisplaySettings inAppDisplaySettings = new InAppDisplaySettings(shouldAnimate, new InAppBgColor(bgColorInHex, bgAlpha));
358382
JSONObject triggerJson = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_TRIGGER);
359383
Trigger trigger = Trigger.fromJSONObject(triggerJson);
360-
JSONObject customPayload = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_CUSTOM_PAYLOAD);
361-
if (customPayload == null) {
362-
customPayload = contentJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_LEGACY_PAYLOAD);
363-
}
364-
if (customPayload == null) {
365-
customPayload = new JSONObject();
366-
}
367384

368-
double priorityLevel = messageJson.optDouble(IterableConstants.ITERABLE_IN_APP_PRIORITY_LEVEL, IterableConstants.ITERABLE_IN_APP_PRIORITY_LEVEL_UNASSIGNED);
385+
double priorityLevel = messageJson.optDouble(IterableConstants.ITERABLE_IN_APP_PRIORITY_LEVEL,
386+
IterableConstants.ITERABLE_IN_APP_PRIORITY_LEVEL_UNASSIGNED);
387+
388+
Boolean saveToInbox = messageJson.has(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX) ?
389+
messageJson.optBoolean(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX) : null;
369390

370-
Boolean saveToInbox = messageJson.has(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX) ? messageJson.optBoolean(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX) : null;
371391
JSONObject inboxPayloadJson = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_INBOX_METADATA);
372392
InboxMetadata inboxMetadata = InboxMetadata.fromJSONObject(inboxPayloadJson);
373393

374-
375394
IterableInAppMessage message = new IterableInAppMessage(
376395
messageId,
377-
new Content(html, padding, backgroundAlpha, shouldAnimate, inAppDisplaySettings),
396+
content,
378397
customPayload,
379398
createdAt,
380399
expiresAt,
381400
trigger,
382401
priorityLevel,
383402
saveToInbox,
384403
inboxMetadata,
385-
campaignId);
404+
campaignId,
405+
jsonOnly);
386406

387407
message.inAppStorageInterface = storageInterface;
388-
if (html != null) {
408+
if (!jsonOnly && content.html != null && !content.html.isEmpty()) {
389409
message.setLoadedHtmlFromJson(true);
390410
}
391411
message.processed = messageJson.optBoolean(IterableConstants.ITERABLE_IN_APP_PROCESSED, false);
@@ -410,6 +430,9 @@ JSONObject toJSONObject() {
410430
if (expiresAt != null) {
411431
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_EXPIRES_AT, expiresAt.getTime());
412432
}
433+
if (jsonOnly) {
434+
messageJson.put(IterableConstants.ITERABLE_IN_APP_JSON_ONLY, 1);
435+
}
413436

414437
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_TRIGGER, trigger.toJSONObject());
415438

@@ -435,7 +458,7 @@ JSONObject toJSONObject() {
435458
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_CUSTOM_PAYLOAD, customPayload);
436459

437460
if (saveToInbox != null) {
438-
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX, saveToInbox);
461+
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX, saveToInbox && !jsonOnly);
439462
}
440463
if (inboxMetadata != null) {
441464
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_INBOX_METADATA, inboxMetadata.toJSONObject());
@@ -472,6 +495,9 @@ private void onChanged() {
472495
* @return
473496
*/
474497
static Rect getPaddingFromPayload(JSONObject paddingOptions) {
498+
if (paddingOptions == null) {
499+
return new Rect(0, 0, 0, 0);
500+
}
475501
Rect rect = new Rect();
476502
rect.top = decodePadding(paddingOptions.optJSONObject("top"));
477503
rect.left = decodePadding(paddingOptions.optJSONObject("left"));
@@ -529,4 +555,4 @@ static JSONObject encodePadding(int padding) throws JSONException {
529555
}
530556
return paddingJson;
531557
}
532-
}
558+
}

Diff for: ‎iterableapi/src/test/java/com/iterable/iterableapi/InAppTestUtils.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public static IterableInAppMessage getTestInboxInAppWithId(String messageId) {
3030
new Double(300.5),
3131
true,
3232
null,
33-
null
33+
null,
34+
false
3435
);
3536
}
3637
}

Diff for: ‎iterableapi/src/test/java/com/iterable/iterableapi/IterableApiAuthTests.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,23 @@ public void testAuthTokenPresentInRequest() throws Exception {
397397
public void testAuthFailureReturns401() throws InterruptedException {
398398
doReturn(expiredJWT).when(authHandler).onAuthTokenRequested();
399399
dispatcher.enqueueResponse("/events/inAppConsume", new MockResponse().setResponseCode(401).setBody("{\"code\": \"InvalidJwtPayload\"}"));
400-
IterableApi.getInstance().inAppConsume(new IterableInAppMessage("asd", null, null, null, null, null, 0.0, null, null, (long) 2), null, null);
400+
IterableApi.getInstance().inAppConsume(
401+
new IterableInAppMessage(
402+
"asd", // messageId
403+
null, // content
404+
null, // customPayload
405+
null, // createdAt
406+
null, // expiresAt
407+
null, // trigger
408+
0.0, // priorityLevel
409+
null, // saveToInbox
410+
null, // inboxMetadata
411+
2L, // campaignId
412+
false // jsonOnly - since this is a test message, not a JSON message
413+
),
414+
null, // urlHandler
415+
null // customActionHandler
416+
);
401417
Robolectric.flushForegroundThreadScheduler();
402418
assertEquals(IterableApi.getInstance().getAuthToken(), expiredJWT);
403419
}

0 commit comments

Comments
 (0)