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

IAM Tag Substitution #1283

Merged
merged 14 commits into from
Mar 17, 2021
Merged

IAM Tag Substitution #1283

merged 14 commits into from
Mar 17, 2021

Conversation

emawby
Copy link
Contributor

@emawby emawby commented Feb 23, 2021

This PR adds support for IAM liquid templating tag substitution
The liquid rendering is handled by a javascript library added to the IAM by the dashboard. The SDKs just need to inject the tags for the player into the IAM html.

  • Injects tags into the IAM via the iamInfo.tags object in the IAM. I had to add it into the HTML before it was loaded into the webview to get it to render properly. This takes place in OSInAppMessageController after the HTML is loaded and tags are retrieved.
  • Tags are retrieved in parallel with the IAM HTML if a new property has_liquid is true in the IAM json. Tags will only be retrieved from the server once per app run (no change in behavior from existing getTags logic)
  • currently is targeting local host for testing. This will be removed before merging

This change is Reviewable

Parsed from "has_liquid" this property indicates if an IAM contains liquid templating. It is currently used to ask for tags for tag substitution when loading HTML content for an IAM
@@ -45,8 +45,8 @@ public void onCreate() {
notificationReceivedEvent.complete(null);
});

OneSignal.unsubscribeWhenNotificationsAreDisabled(true);
OneSignal.pauseInAppMessages(true);
OneSignal.unsubscribeWhenNotificationsAreDisabled(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

demo application changes should be done separately, but in this case, it seems like they are not needed for this change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverting the local testing commit but leaving in the history so I can add it back easier. I will remove this before merging. For the bug bash I will make this target staging instead

@@ -25,7 +25,7 @@ public static boolean exists(Context context, String key) {
}

public static String getOneSignalAppId(Context context) {
return getSharedPreference(context).getString(OS_APP_ID_SHARED_PREF, "77e32082-ea27-42e3-a898-c72e141824ef");
return getSharedPreference(context).getString(OS_APP_ID_SHARED_PREF, "1bcc4195-2039-4b18-83d7-2ab5b98daf76");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idem

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverting the local testing commit but leaving in the history so I can add it back easier. I will remove this before merging. For the bug bash I will make this target staging instead

@@ -750,6 +762,24 @@ private void displayMessage(@NonNull final OSInAppMessage message) {
}

inAppMessageShowing = true;
waitForTags = false;
if (message.getHasLiquid()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not wait for get tags to call display message and avoid the parallel flag check?

What about checking on the evaluateInAppMessages method if the IAM hasLiquid? If so, check if it already has tags set. If not, download tags and put them to that IAM, then call evaluateInAppMessages again

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We definitely could do that and it would be cleaner code but this is theoretically more performant since we are kicking off the rest requests in parallel we don't need to wait for 2 round trips.

I am open to not doing them in parallel if the performance improvement is less important than the simplicity and reliability of the sequential calls.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that this will be less performant, but I'm worried about future extensibility and maintainability with other functionalities. Maybe @jkasten2 can give his opinion on this one

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -52,7 +52,7 @@ void onFailure(int statusCode, String response, Throwable throwable) {}

private static final String OS_API_VERSION = "1";
private static final String OS_ACCEPT_HEADER = "application/vnd.onesignal.v" + OS_API_VERSION + "+json";
private static final String BASE_URL = "https://api.onesignal.com/";
private static final String BASE_URL = "http://192.168.1.86:3000/api/v1/";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverting the local testing commit but leaving in the history so I can add it back easier. I will remove this before merging. For the bug bash I will make this target staging instead

@emawby emawby requested a review from Jeasmine March 2, 2021 23:22
Copy link
Contributor

@Jeasmine Jeasmine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I want to know about @jkasten2 point of view of the logic performance vs. maintainability

Copy link
Member

@jkasten2 jkasten2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 8 files at r1, 3 of 4 files at r2, 1 of 1 files at r3, 1 of 1 files at r4, 1 of 1 files at r5.
Reviewable status: all files reviewed, 10 unresolved discussions (waiting on @emawby and @Jeasmine)


OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java, line 766 at r1 (raw file):

Previously, Jeasmine (JNahui) wrote…

Agree that this will be less performant, but I'm worried about future extensibility and maintainability with other functionalities. Maybe @jkasten2 can give his opinion on this one

I am concerned about performance if we don't make these calls in parallel. It depends on the IAM but if someone calls OneSignal.setTrigger in their app from a button press and wants an IAM to show up in response we want to make sure that happens as fast as possible.

To make this code cleaner we could use an async / await strategy for this instead. This is a Kotlin feature and would require us to switch some of this logic to Kotlin. Which we could do now but would recommend doing so in a follow up PR. Seems like a interesting trail to blaze for this code base, if someone is interested in digging.
https://kotlinlang.org/docs/composing-suspending-functions.html#concurrent-using-async
@Jeasmine @emawby Thoughts?


OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java, line 831 at r5 (raw file):

    }

    String taggedHTMLString(@NonNull String untaggedString) {

Add @NonNull to return type too.


OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java, line 833 at r5 (raw file):

    String taggedHTMLString(@NonNull String untaggedString) {
        String tagsDict = userTagsString;
        String tagScript =  LIQUID_TAG_SCRIPT;

nit, extra space after =.

Copy link
Contributor

@Jeasmine Jeasmine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: all files reviewed, 10 unresolved discussions (waiting on @emawby, @Jeasmine, and @jkasten2)


OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java, line 766 at r1 (raw file):

Previously, jkasten2 (Josh Kasten) wrote…

Left a follow up comment here: https://reviewable.io/reviews/onesignal/onesignal-android-sdk/1283/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java#-MV-jin1cLek6URzCeI5-r1-766

Fair point. in this case, we do want performance better than maintainability. Introducing suspending functions will mean introducing coroutines. I do like the idea of introducing coroutines and was part of the reactor, but that will mean changing a lot of stuff if we want to do it correctly, first making a new package for IAM and transform it to kotlin, after that define a layer for coroutine and scope managing, then use coroutines. But will love to do that 🔥

Copy link
Contributor Author

@emawby emawby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: all files reviewed, 9 unresolved discussions (waiting on @Jeasmine and @jkasten2)


OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java, line 766 at r1 (raw file):

Previously, Jeasmine (JNahui) wrote…

Fair point. in this case, we do want performance better than maintainability. Introducing suspending functions will mean introducing coroutines. I do like the idea of introducing coroutines and was part of the reactor, but that will mean changing a lot of stuff if we want to do it correctly, first making a new package for IAM and transform it to kotlin, after that define a layer for coroutine and scope managing, then use coroutines. But will love to do that 🔥

Ya I am definitely interested in improving this area. Keeping it maintainable and performant is ideal so I am onboard with using something like async/await in the future


OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java, line 831 at r5 (raw file):

Previously, jkasten2 (Josh Kasten) wrote…

Add @NonNull to return type too.

Done.

Copy link
Member

@jkasten2 jkasten2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r6.
Reviewable status: all files reviewed, 9 unresolved discussions (waiting on @Jeasmine and @jkasten2)


OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java, line 766 at r1 (raw file):

Previously, emawby (Elliot Mawby) wrote…

Ya I am definitely interested in improving this area. Keeping it maintainable and performant is ideal so I am onboard with using something like async/await in the future

Not a requirement for this PR but wanted to bring it up. I am in favor of refactoring in another PR to keep this PR simple.

Copy link
Member

@jkasten2 jkasten2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r7.
Reviewable status: all files reviewed, 8 unresolved discussions (waiting on @Jeasmine)

We will always get tags for the preview since we don't have a real InAppMessage object to check for hasLiquid.
@Jeasmine
Copy link
Contributor

I retrigger the Travis with no intention, but I saw there were 2 new test failing, its that correct?

@Jeasmine
Copy link
Contributor

Looks like shouldShowInAppPreviewWhenOpeningPreviewNotification and osIAMPreview_showsPreview are always failing

@emawby emawby merged commit 97df02d into master Mar 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants