Skip to content

Commit 97df02d

Browse files
authored
Merge pull request #1283 from OneSignal/feature/iam_tab_sub
IAM Tag Substitution
2 parents 31a4d1d + be363ae commit 97df02d

File tree

6 files changed

+124
-15
lines changed

6 files changed

+124
-15
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessage.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class OSInAppMessage {
2424
private static final String IAM_REDISPLAY_STATS = "redisplay";
2525
private static final String DISPLAY_DURATION = "displayDuration";
2626
private static final String END_TIME = "end_time";
27+
private static final String HAS_LIQUID = "has_liquid";
2728

2829
/**
2930
* The unique identifier for this in-app message
@@ -64,6 +65,7 @@ class OSInAppMessage {
6465
private boolean actionTaken;
6566
private Date endTime;
6667
boolean isPreview;
68+
private boolean hasLiquid;
6769

6870
OSInAppMessage(boolean isPreview) {
6971
this.isPreview = isPreview;
@@ -83,6 +85,8 @@ class OSInAppMessage {
8385
this.triggers = parseTriggerJson(json.getJSONArray(IAM_TRIGGERS));
8486
this.clickedClickIds = new HashSet<>();
8587
this.endTime = parseEndTimeJson(json);
88+
if (json.has(HAS_LIQUID))
89+
this.hasLiquid = json.getBoolean(HAS_LIQUID);
8690

8791
if (json.has(IAM_REDISPLAY_STATS))
8892
this.redisplayStats = new OSInAppMessageRedisplayStats(json.getJSONObject(IAM_REDISPLAY_STATS));
@@ -186,6 +190,8 @@ JSONObject toJSONObject() {
186190
json.put(END_TIME, endTimeString);
187191
}
188192

193+
json.put(HAS_LIQUID, hasLiquid);
194+
189195
} catch (JSONException exception) {
190196
exception.printStackTrace();
191197
}
@@ -227,6 +233,14 @@ public void setDisplayedInSession(boolean displayedInSession) {
227233
this.displayedInSession = displayedInSession;
228234
}
229235

236+
boolean getHasLiquid() {
237+
return hasLiquid;
238+
}
239+
240+
void setHasLiquid(boolean hasLiquid) {
241+
this.hasLiquid = hasLiquid;
242+
}
243+
230244
@NonNull
231245
Set<String> getClickedClickIds() {
232246
return clickedClickIds;
@@ -266,6 +280,7 @@ public String toString() {
266280
", actionTaken=" + actionTaken +
267281
", isPreview=" + isPreview +
268282
", endTime=" + endTime +
283+
", hasLiquid=" + hasLiquid +
269284
'}';
270285
}
271286

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class OSInAppMessageController implements OSDynamicTriggerControllerObserver, OS
2828
private static final Object LOCK = new Object();
2929
private static final String OS_SAVE_IN_APP_MESSAGE = "OS_SAVE_IN_APP_MESSAGE";
3030
public static final String IN_APP_MESSAGES_JSON_KEY = "in_app_messages";
31+
private static final String LIQUID_TAG_SCRIPT = "\n\n" +
32+
"<script>\n" +
33+
" setPlayerTags(%s);\n" +
34+
"</script>";
3135
private static ArrayList<String> PREFERRED_VARIANT_ORDER = new ArrayList<String>() {{
3236
add("android");
3337
add("app");
@@ -69,6 +73,14 @@ class OSInAppMessageController implements OSDynamicTriggerControllerObserver, OS
6973
private boolean inAppMessagingEnabled = true;
7074
private boolean inAppMessageShowing = false;
7175

76+
@Nullable
77+
private String userTagsString = null;
78+
79+
@Nullable
80+
private String pendingHTMLContent = null;
81+
82+
private boolean waitForTags = false;
83+
7284
@Nullable
7385
Date lastTimeInAppDismissed = null;
7486
private int htmlNetworkRequestAttemptCount = 0;
@@ -743,6 +755,29 @@ public void run() {
743755
return "in_app_messages/" + message.messageId + "/variants/" + variantId + "/html?app_id=" + OneSignal.appId;
744756
}
745757

758+
private void getTagsForLiquidTemplating(@NonNull final OSInAppMessage message, final boolean isPreview) {
759+
waitForTags = false;
760+
if (isPreview || message.getHasLiquid()) {
761+
waitForTags = true;
762+
OneSignal.getTags(new OneSignal.OSGetTagsHandler() {
763+
@Override
764+
public void tagsAvailable(JSONObject tags) {
765+
waitForTags = false;
766+
if (tags != null) {
767+
userTagsString = tags.toString();
768+
}
769+
if (pendingHTMLContent != null) {
770+
if (!isPreview) {
771+
OneSignal.getSessionManager().onInAppMessageReceived(message.messageId);
772+
}
773+
WebViewManager.showHTMLString(message, taggedHTMLString(pendingHTMLContent));
774+
pendingHTMLContent = null;
775+
}
776+
}
777+
});
778+
}
779+
}
780+
746781
private void displayMessage(@NonNull final OSInAppMessage message) {
747782
if (!inAppMessagingEnabled) {
748783
logger.verbose("In app messaging is currently paused, in app messages will not be shown!");
@@ -751,6 +786,8 @@ private void displayMessage(@NonNull final OSInAppMessage message) {
751786

752787
inAppMessageShowing = true;
753788

789+
getTagsForLiquidTemplating(message, false);
790+
754791
String htmlPath = htmlPathForMessage(message);
755792
OneSignalRestClient.get(htmlPath, new ResponseHandler() {
756793
@Override
@@ -785,19 +822,32 @@ void onSuccess(String response) {
785822

786823
double displayDuration = jsonResponse.optDouble("display_duration");
787824
message.setDisplayDuration(displayDuration);
788-
825+
if (waitForTags) {
826+
pendingHTMLContent = htmlStr;
827+
return;
828+
}
789829
OneSignal.getSessionManager().onInAppMessageReceived(message.messageId);
790-
WebViewManager.showHTMLString(message, htmlStr);
830+
WebViewManager.showHTMLString(message, taggedHTMLString(htmlStr));
791831
} catch (JSONException e) {
792832
e.printStackTrace();
793833
}
794834
}
795835
}, null);
796836
}
797837

838+
@NonNull
839+
String taggedHTMLString(@NonNull String untaggedString) {
840+
String tagsDict = userTagsString;
841+
String tagScript = LIQUID_TAG_SCRIPT;
842+
return untaggedString + String.format(tagScript, tagsDict);
843+
}
844+
798845
void displayPreviewMessage(@NonNull String previewUUID) {
799846
inAppMessageShowing = true;
800847

848+
final OSInAppMessage message = new OSInAppMessage(true);
849+
getTagsForLiquidTemplating(message, true);
850+
801851
String htmlPath = "in_app_messages/device_preview?preview_id=" + previewUUID + "&app_id=" + OneSignal.appId;
802852
OneSignalRestClient.get(htmlPath, new ResponseHandler() {
803853
@Override
@@ -813,12 +863,13 @@ void onSuccess(String response) {
813863
JSONObject jsonResponse = new JSONObject(response);
814864
String htmlStr = jsonResponse.getString("html");
815865

816-
OSInAppMessage message = new OSInAppMessage(true);
817-
818866
double displayDuration = jsonResponse.optDouble("display_duration");
819867
message.setDisplayDuration(displayDuration);
820-
821-
WebViewManager.showHTMLString(message, htmlStr);
868+
if (waitForTags) {
869+
pendingHTMLContent = htmlStr;
870+
return;
871+
}
872+
WebViewManager.showHTMLString(message, taggedHTMLString(htmlStr));
822873
} catch (JSONException e) {
823874
e.printStackTrace();
824875
}

OneSignalSDK/unittest/src/test/java/com/onesignal/InAppMessagingHelpers.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class InAppMessagingHelpers {
1818
public static final String ONESIGNAL_APP_ID = "b4f7f966-d8cc-11e4-bed1-df8f05be55ba";
1919
public static final String IAM_CLICK_ID = "12345678-1234-1234-1234-123456789012";
2020
public static final String IAM_PAGE_ID = "12345678-1234-ABCD-1234-123456789012";
21+
public static final String IAM_HAS_LIQUID = "has_liquid";
2122

2223
public static boolean evaluateMessage(OSInAppMessage message) {
2324
return OneSignal.getInAppMessageController().triggerController.evaluateMessageTriggers(message);
@@ -95,6 +96,17 @@ private static JSONObject basicIAMJSONObject(final JSONArray triggerJson) throws
9596
return json;
9697
}
9798

99+
public static OSTestInAppMessage buildTestMessageWithLiquid(final JSONArray triggerJson) throws JSONException {
100+
JSONObject json = basicIAMJSONObject(triggerJson);
101+
json.put(IAM_HAS_LIQUID, true);
102+
return new OSTestInAppMessage(json);
103+
}
104+
105+
public static OSTestInAppMessage buildTestMessageWithSingleTriggerAndLiquid(final OSTriggerKind kind, final String key, final String operator, final Object value) throws JSONException {
106+
JSONArray triggersJson = basicTrigger(kind, key, operator, value);
107+
return buildTestMessageWithLiquid(triggersJson);
108+
}
109+
98110
private static OSTestInAppMessage buildTestMessageWithMultipleDisplays(final JSONArray triggerJson, final int limit, final long delay) throws JSONException {
99111
JSONObject json = basicIAMJSONObject(triggerJson);
100112
json.put("redisplay", new JSONObject() {{

OneSignalSDK/unittest/src/test/java/com/test/onesignal/GenerateNotificationRunner.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,8 +1201,8 @@ public void shouldShowInAppPreviewWhenInFocus() throws Exception {
12011201

12021202
new FCMBroadcastReceiver().onReceive(blankActivity, intent);
12031203
threadAndTaskWait();
1204-
1205-
assertEquals("PGh0bWw+PC9odG1sPg==", ShadowOSWebView.lastData);
1204+
threadAndTaskWait();
1205+
assertEquals("PGh0bWw+PC9odG1sPgoKPHNjcmlwdD4KICAgIHNldFBsYXllclRhZ3MobnVsbCk7Cjwvc2NyaXB0Pg==", ShadowOSWebView.lastData);
12061206
}
12071207

12081208
@Test
@@ -1223,8 +1223,9 @@ public void shouldShowInAppPreviewWhenOpeningPreviewNotification() throws Except
12231223

12241224
Intent notificationOpenIntent = createOpenIntent(2, inAppPreviewMockPayloadBundle());
12251225
NotificationOpenedProcessor_processFromContext(blankActivity, notificationOpenIntent);
1226-
1227-
assertEquals("PGh0bWw+PC9odG1sPg==", ShadowOSWebView.lastData);
1226+
threadAndTaskWait();
1227+
threadAndTaskWait();
1228+
assertEquals("PGh0bWw+PC9odG1sPgoKPHNjcmlwdD4KICAgIHNldFBsYXllclRhZ3MobnVsbCk7Cjwvc2NyaXB0Pg==", ShadowOSWebView.lastData);
12281229
}
12291230

12301231
@Test

OneSignalSDK/unittest/src/test/java/com/test/onesignal/InAppMessageIntegrationTests.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
import java.util.HashSet;
5858
import java.util.List;
5959
import java.util.Set;
60-
import java.util.concurrent.Callable;
6160
import java.util.concurrent.TimeUnit;
6261

6362
import static com.onesignal.OneSignalPackagePrivateHelper.OSTestTrigger.OSTriggerKind;
@@ -1283,7 +1282,6 @@ public void testInAppMessageDisplayMultipleTimes() throws Exception {
12831282
// Add trigger to make IAM display
12841283
OneSignal.addTrigger("test_1", 2);
12851284
assertEquals(1, OneSignalPackagePrivateHelper.getInAppMessageDisplayQueue().size());
1286-
12871285
// Check impression request
12881286
int requestSize = ShadowOneSignalRestClient.requests.size();
12891287
ShadowOneSignalRestClient.Request iamImpressionRequest = ShadowOneSignalRestClient.requests.get(requestSize - 1);
@@ -1304,7 +1302,6 @@ public void testInAppMessageDisplayMultipleTimes() throws Exception {
13041302
// Set same trigger, should display again
13051303
OneSignal.addTrigger("test_1", 2);
13061304
assertEquals(1, OneSignalPackagePrivateHelper.getInAppMessageDisplayQueue().size());
1307-
13081305
// Check impression request is sent again
13091306
int requestSizeAfterRedisplay = ShadowOneSignalRestClient.requests.size();
13101307
ShadowOneSignalRestClient.Request iamImpressionRequestAfterRedisplay = ShadowOneSignalRestClient.requests.get(requestSizeAfterRedisplay - 1);
@@ -1830,6 +1827,40 @@ public void testInAppMessageIdTracked() throws Exception {
18301827
assertEquals(1, lastReceivedIds.length());
18311828
}
18321829

1830+
@Test
1831+
public void testLiquidIAMDisplayWaitsForGetTags() throws Exception {
1832+
final OSTestInAppMessage message = InAppMessagingHelpers.buildTestMessageWithSingleTriggerAndLiquid(
1833+
OSTriggerKind.CUSTOM, "test_1", OSTestTrigger.OSTriggerOperator.EQUAL_TO.toString(), 2);
1834+
1835+
setMockRegistrationResponseWithMessages(new ArrayList<OSTestInAppMessage>() {{
1836+
add(message);
1837+
}});
1838+
1839+
// Init OneSignal IAM with redisplay
1840+
OneSignalInit();
1841+
threadAndTaskWait();
1842+
1843+
// Add trigger to make IAM display
1844+
OneSignal.addTrigger("test_1", 2);
1845+
assertEquals(1, OneSignalPackagePrivateHelper.getInAppMessageDisplayQueue().size());
1846+
// Wait for both getTags and get IAM HTML to be called
1847+
Awaitility.await()
1848+
.atMost(new Duration(150, TimeUnit.MILLISECONDS))
1849+
.pollInterval(new Duration(10, TimeUnit.MILLISECONDS))
1850+
.until(() -> ShadowOneSignalRestClient.requests.size() == 4);
1851+
int requestSize = ShadowOneSignalRestClient.requests.size();
1852+
ShadowOneSignalRestClient.Request getTagsRequest = ShadowOneSignalRestClient.requests.get(requestSize - 1);
1853+
assertEquals("players/" + "df8f05be55ba-b2f7f966-d8cc-11e4-bed1" + "?app_id=" + "b2f7f966-d8cc-11e4-bed1-df8f05be55ba", getTagsRequest.url);
1854+
// Runnable for get tags is run
1855+
threadAndTaskWait();
1856+
// Runnable for webView is run from background thread to main thread
1857+
threadAndTaskWait();
1858+
// Check impression request
1859+
requestSize = ShadowOneSignalRestClient.requests.size();
1860+
ShadowOneSignalRestClient.Request iamImpressionRequest = ShadowOneSignalRestClient.requests.get(requestSize - 1);
1861+
assertEquals("in_app_messages/" + message.messageId + "/impression", iamImpressionRequest.url);
1862+
}
1863+
18331864
private void setMockRegistrationResponseWithMessages(ArrayList<OSTestInAppMessage> messages) throws JSONException {
18341865
final JSONArray jsonMessages = new JSONArray();
18351866

OneSignalSDK/unittest/src/test/java/com/test/onesignal/NotificationOpenedActivityHMSIntegrationTestsRunner.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ public void osIAMPreview_showsPreview() throws Exception {
193193
);
194194

195195
helper_startHMSOpenActivity(intent);
196-
197-
assertEquals("PGh0bWw+PC9odG1sPg==", ShadowOSWebView.lastData);
196+
assertEquals("PGh0bWw+PC9odG1sPgoKPHNjcmlwdD4KICAgIHNldFBsYXllclRhZ3MobnVsbCk7Cjwvc2NyaXB0Pg==", ShadowOSWebView.lastData);
198197
}
199198
}

0 commit comments

Comments
 (0)