Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MOB-10364 Support for In App JSON Only Messages #857

Merged
merged 32 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3005be2
[MOB-10364] some work on in app json only messages
sumeruchat Jan 3, 2025
ac8aa7c
[MOB-10364] fix the test
sumeruchat Jan 3, 2025
839b36f
[MOB-10364] Rewrite of logic and tests
sumeruchat Jan 6, 2025
9736f6f
[MOB-10364] Add editorconfig
sumeruchat Jan 7, 2025
05f0fbe
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
b021a9c
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
feea677
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
2337a3a
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
2f55511
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
6e0d349
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
9a64ac8
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
6044ecb
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
595d2b6
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
5b7f5a0
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
76768d9
Merge branch 'master' into feature/MOB-10364-in-app-json-only
sumeruchat Jan 7, 2025
554c0ef
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
08f1b6e
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
29fa0e5
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
3339e5e
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
4786be3
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
54869df
[MOB-10364] Update according to new discussiom
sumeruchat Jan 7, 2025
52a9610
[MOB-10364] Update according to new discussiom
sumeruchat Jan 8, 2025
50b4e22
[MOB-10364] Update according to new discussiom
sumeruchat Jan 8, 2025
1571913
[MOB-10364] Update according to new discussiom
sumeruchat Jan 8, 2025
3279f0b
[MOB-10364] Update according to new discussiom
sumeruchat Jan 9, 2025
c116571
Merge branch 'master' into feature/MOB-10364-in-app-json-only
evantk91 Jan 9, 2025
3783433
updates json only flag parsing
Jan 10, 2025
d7dd42c
[MOB-10364] Update according to new discussiom
sumeruchat Jan 10, 2025
94169c1
[MOB-10364] Update according to new discussiom
sumeruchat Jan 10, 2025
4f2301a
[MOB-10364] Update according to new discussiom
sumeruchat Jan 10, 2025
fc9253f
[MOB-10364] Update according to new discussiom
sumeruchat Jan 10, 2025
06e6c86
[MOB-10364] Update according to new discussiom
sumeruchat Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
root = true

[*]
indent_style = space
indent_size = 4
tab_width = 4
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,11 @@ private void onForeground() {
fetchRemoteConfiguration();
}

if (_applicationContext == null || sharedInstance.getMainActivityContext() == null) {
IterableLogger.w(TAG, "onForeground: _applicationContext is null");
return;
}

boolean systemNotificationEnabled = NotificationManagerCompat.from(_applicationContext).areNotificationsEnabled();
SharedPreferences sharedPref = sharedInstance.getMainActivityContext().getSharedPreferences(IterableConstants.SHARED_PREFS_FILE, Context.MODE_PRIVATE);

Expand Down Expand Up @@ -1435,4 +1440,4 @@ public void trackEmbeddedSession(@NonNull IterableEmbeddedSession session) {
apiClient.trackEmbeddedSession(session);
}
//endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ public final class IterableConstants {
public static final String ITERABLE_IN_APP_BUTTONS = "buttons";
public static final String ITERABLE_IN_APP_COLOR = "color";
public static final String ITERABLE_IN_APP_CONTENT = "content";
public static final String ITERABLE_IN_APP_JSON_ONLY = "jsonOnly";
public static final String ITERABLE_IN_APP_COUNT = "count";
public static final String ITERABLE_IN_APP_MAIN_IMAGE = "mainImage";
public static final String ITERABLE_IN_APP_MESSAGE = "inAppMessages";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ boolean isShowingInApp() {
}

boolean showMessage(@NonNull IterableInAppMessage message, IterableInAppLocation location, @NonNull final IterableHelper.IterableUrlCallback clickCallback) {
// Early return for JSON-only messages
if (message.isJsonOnly()) {
return false;
}

Activity currentActivity = activityMonitor.getCurrentActivity();
// Prevent double display
if (currentActivity != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,6 @@ private void processMessages() {
IterableLogger.printInfo();

List<IterableInAppMessage> messages = getMessages();

List<IterableInAppMessage> messagesByPriorityLevel = getMessagesSortedByPriorityLevel(messages);

for (IterableInAppMessage message : messagesByPriorityLevel) {
Expand All @@ -414,6 +413,14 @@ private void processMessages() {
InAppResponse response = handler.onNewInApp(message);
IterableLogger.d(TAG, "Response: " + response);
message.setProcessed(true);

if (message.isJsonOnly()) {
setRead(message, true, null, null);
message.setConsumed(true);
api.inAppConsume(message, null, null, null, null);
return;
}

if (response == InAppResponse.SHOW) {
boolean consume = !message.isInboxMessage();
showMessage(message, consume, null);
Expand Down Expand Up @@ -519,4 +526,4 @@ public void run() {
}
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class IterableInAppMessage {
private boolean loadedHtmlFromJson = false;
private boolean markedForDeletion = false;
private @Nullable IterableInAppStorage inAppStorageInterface;
private final boolean jsonOnly;

IterableInAppMessage(@NonNull String messageId,
@NonNull Content content,
Expand All @@ -41,7 +42,8 @@ public class IterableInAppMessage {
@NonNull Double priorityLevel,
@Nullable Boolean saveToInbox,
@Nullable InboxMetadata inboxMetadata,
@Nullable Long campaignId) {
@Nullable Long campaignId,
boolean jsonOnly) {

this.messageId = messageId;
this.content = content;
Expand All @@ -50,9 +52,10 @@ public class IterableInAppMessage {
this.expiresAt = expiresAt;
this.trigger = trigger;
this.priorityLevel = priorityLevel;
this.saveToInbox = saveToInbox;
this.saveToInbox = saveToInbox != null ? (saveToInbox && !jsonOnly) : null;
this.inboxMetadata = inboxMetadata;
this.campaignId = campaignId;
this.jsonOnly = jsonOnly;
}

static class Trigger {
Expand Down Expand Up @@ -246,7 +249,7 @@ public Date getExpiresAt() {

@NonNull
public Content getContent() {
if (content.html == null) {
if (content.html == null && !jsonOnly) {
content.html = inAppStorageInterface.getHTML(messageId);
}
return content;
Expand Down Expand Up @@ -322,70 +325,87 @@ public void markForDeletion(boolean delete) {
this.markedForDeletion = delete;
}

public boolean isJsonOnly() {
return jsonOnly;
}

static IterableInAppMessage fromJSONObject(@NonNull JSONObject messageJson, @Nullable IterableInAppStorage storageInterface) {

if (messageJson == null) {
return null;
}

JSONObject contentJson = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_CONTENT);
if (contentJson == null) {
return null;
}

String messageId = messageJson.optString(IterableConstants.KEY_MESSAGE_ID);
final Long campaignId = IterableUtil.retrieveValidCampaignIdOrNull(messageJson, IterableConstants.KEY_CAMPAIGN_ID);
boolean jsonOnly = messageJson.optBoolean(IterableConstants.ITERABLE_IN_APP_JSON_ONLY, false);

JSONObject customPayload = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_CUSTOM_PAYLOAD);
if (customPayload == null && jsonOnly) {
customPayload = new JSONObject();
}

Content content;
if (jsonOnly) {
content = new Content("", new Rect(), 0.0, false, new InAppDisplaySettings(false, new InAppBgColor(null, 0.0f)));
} else {
JSONObject contentJson = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_CONTENT);
if (contentJson == null) {
return null;
}
if (customPayload == null) {
customPayload = contentJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_LEGACY_PAYLOAD);
}

String html = contentJson.optString(IterableConstants.ITERABLE_IN_APP_HTML, null);
JSONObject inAppDisplaySettingsJson = contentJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_DISPLAY_SETTINGS);
Rect padding = getPaddingFromPayload(inAppDisplaySettingsJson);
double backgroundAlpha = contentJson.optDouble(IterableConstants.ITERABLE_IN_APP_BACKGROUND_ALPHA, 0);
boolean shouldAnimate = inAppDisplaySettingsJson.optBoolean(IterableConstants.ITERABLE_IN_APP_SHOULD_ANIMATE, false);
JSONObject bgColorJson = inAppDisplaySettingsJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_BGCOLOR);

String bgColorInHex = null;
double bgAlpha = 0.0f;
if (bgColorJson != null) {
bgColorInHex = bgColorJson.optString(IterableConstants.ITERABLE_IN_APP_BGCOLOR_HEX);
bgAlpha = bgColorJson.optDouble(IterableConstants.ITERABLE_IN_APP_BGCOLOR_ALPHA);
}

InAppDisplaySettings inAppDisplaySettings = new InAppDisplaySettings(shouldAnimate, new InAppBgColor(bgColorInHex, bgAlpha));
content = new Content(html, padding, backgroundAlpha, shouldAnimate, inAppDisplaySettings);
}

long createdAtLong = messageJson.optLong(IterableConstants.ITERABLE_IN_APP_CREATED_AT);
Date createdAt = createdAtLong != 0 ? new Date(createdAtLong) : null;
long expiresAtLong = messageJson.optLong(IterableConstants.ITERABLE_IN_APP_EXPIRES_AT);
Date expiresAt = expiresAtLong != 0 ? new Date(expiresAtLong) : null;

String html = contentJson.optString(IterableConstants.ITERABLE_IN_APP_HTML, null);
JSONObject inAppDisplaySettingsJson = contentJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_DISPLAY_SETTINGS);
Rect padding = getPaddingFromPayload(inAppDisplaySettingsJson);
double backgroundAlpha = contentJson.optDouble(IterableConstants.ITERABLE_IN_APP_BACKGROUND_ALPHA, 0);
boolean shouldAnimate = inAppDisplaySettingsJson.optBoolean(IterableConstants.ITERABLE_IN_APP_SHOULD_ANIMATE, false);
JSONObject bgColorJson = inAppDisplaySettingsJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_BGCOLOR);

String bgColorInHex = null;
double bgAlpha = 0.0f;
if (bgColorJson != null) {
bgColorInHex = bgColorJson.optString(IterableConstants.ITERABLE_IN_APP_BGCOLOR_HEX);
bgAlpha = bgColorJson.optDouble(IterableConstants.ITERABLE_IN_APP_BGCOLOR_ALPHA);
}

InAppDisplaySettings inAppDisplaySettings = new InAppDisplaySettings(shouldAnimate, new InAppBgColor(bgColorInHex, bgAlpha));
JSONObject triggerJson = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_TRIGGER);
Trigger trigger = Trigger.fromJSONObject(triggerJson);
JSONObject customPayload = messageJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_CUSTOM_PAYLOAD);
if (customPayload == null) {
customPayload = contentJson.optJSONObject(IterableConstants.ITERABLE_IN_APP_LEGACY_PAYLOAD);
}
if (customPayload == null) {
customPayload = new JSONObject();
}

double priorityLevel = messageJson.optDouble(IterableConstants.ITERABLE_IN_APP_PRIORITY_LEVEL, IterableConstants.ITERABLE_IN_APP_PRIORITY_LEVEL_UNASSIGNED);
double priorityLevel = messageJson.optDouble(IterableConstants.ITERABLE_IN_APP_PRIORITY_LEVEL,
IterableConstants.ITERABLE_IN_APP_PRIORITY_LEVEL_UNASSIGNED);

Boolean saveToInbox = messageJson.has(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX) ?
messageJson.optBoolean(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX) : null;

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


IterableInAppMessage message = new IterableInAppMessage(
messageId,
new Content(html, padding, backgroundAlpha, shouldAnimate, inAppDisplaySettings),
content,
customPayload,
createdAt,
expiresAt,
trigger,
priorityLevel,
saveToInbox,
inboxMetadata,
campaignId);
campaignId,
jsonOnly);

message.inAppStorageInterface = storageInterface;
if (html != null) {
if (!jsonOnly && content.html != null && !content.html.isEmpty()) {
message.setLoadedHtmlFromJson(true);
}
message.processed = messageJson.optBoolean(IterableConstants.ITERABLE_IN_APP_PROCESSED, false);
Expand All @@ -410,6 +430,9 @@ JSONObject toJSONObject() {
if (expiresAt != null) {
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_EXPIRES_AT, expiresAt.getTime());
}
if (jsonOnly) {
messageJson.put(IterableConstants.ITERABLE_IN_APP_JSON_ONLY, 1);
}

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

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

if (saveToInbox != null) {
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX, saveToInbox);
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_SAVE_TO_INBOX, saveToInbox && !jsonOnly);
}
if (inboxMetadata != null) {
messageJson.putOpt(IterableConstants.ITERABLE_IN_APP_INBOX_METADATA, inboxMetadata.toJSONObject());
Expand Down Expand Up @@ -472,6 +495,9 @@ private void onChanged() {
* @return
*/
static Rect getPaddingFromPayload(JSONObject paddingOptions) {
if (paddingOptions == null) {
return new Rect(0, 0, 0, 0);
}
Rect rect = new Rect();
rect.top = decodePadding(paddingOptions.optJSONObject("top"));
rect.left = decodePadding(paddingOptions.optJSONObject("left"));
Expand Down Expand Up @@ -529,4 +555,4 @@ static JSONObject encodePadding(int padding) throws JSONException {
}
return paddingJson;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public static IterableInAppMessage getTestInboxInAppWithId(String messageId) {
new Double(300.5),
true,
null,
null
null,
false
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,23 @@ public void testAuthTokenPresentInRequest() throws Exception {
public void testAuthFailureReturns401() throws InterruptedException {
doReturn(expiredJWT).when(authHandler).onAuthTokenRequested();
dispatcher.enqueueResponse("/events/inAppConsume", new MockResponse().setResponseCode(401).setBody("{\"code\": \"InvalidJwtPayload\"}"));
IterableApi.getInstance().inAppConsume(new IterableInAppMessage("asd", null, null, null, null, null, 0.0, null, null, (long) 2), null, null);
IterableApi.getInstance().inAppConsume(
new IterableInAppMessage(
"asd", // messageId
null, // content
null, // customPayload
null, // createdAt
null, // expiresAt
null, // trigger
0.0, // priorityLevel
null, // saveToInbox
null, // inboxMetadata
2L, // campaignId
false // jsonOnly - since this is a test message, not a JSON message
),
null, // urlHandler
null // customActionHandler
);
Robolectric.flushForegroundThreadScheduler();
assertEquals(IterableApi.getInstance().getAuthToken(), expiredJWT);
}
Expand Down
Loading
Loading