Introduction
Recently, we received a client request where the requirement was to serve optimize decisioning with zero latency. Currently decisioning works using the edge network, where the requests are sent via the mobile SDK to the Adobe network which in turn reverts back with personalisation. These do come with some latencies albiet small. One such solution was developed by our web team which is CDN based decisioning.
What is CDN based decisioning?
To oversimplify the solution, CDN based approach brings the decisioning closer to client so that latency can be reduced. This deployment would be done on a CDN server inside clients architecture. The client is provided an SDK developed by our web team, which makes the integration much smoother. The SDK is responsible for periodically syncing the configurations and rules from Adobe network. These are required for computing the personalizations. The client can then make requests to this server and compute the required personalizations.

How can we utilize this for mobile?
Optimize SDK currently use the edge network via Edge SDK to fetch personalized propositions and also track the impressions or interactions with the said propositions. This is very similar to how Alloy (Web) solution works.

In the CDN based approach the application would request personalizations from CDN server which keeps the configurations and rules in sync with the Adobe network and serves personalizations utilizing the same. We can change the data flow of the application to fetch personalizations from CDN server and keep on sending the tracking events to Edge network so that least changes would be needed.

The implementation
Sample Server and can be found in this repo : https://github.com/adobe/target-cdn-experimentation-nodejs-sdk
Sample Mobile Application code can be found here : https://github.com/adobe/aepsdk-optimize-android/tree/dev_odd_cdn_sample
To integrate the CDN based decisioning in the mobile application below mentioned instructions can be followed:
- Dependencies:
- The implementation would depend on the mobile sdks for core functionalities so following dependencies need to be added to the application:
Dependencies
implementation(platform("com.adobe.marketing.mobile:sdk-bom:3.8.0")) implementation("com.adobe.marketing.mobile:edgeidentity") implementation("com.adobe.marketing.mobile:core") implementation("com.adobe.marketing.mobile:optimize") |
- Initialize the SDKs in the main application:
Initialization
MobileCore.initialize(this, LAUNCH_ENVIRONMENT_FILE_ID) |
- Here is a brief about use of each dependency in this case:
- Core is required for enabling communication between different sdk's and share common functionalities it is crucial for other sdks to work.
- Optimize provides some basic classes that do data transformation and data validation for us. This also enables us to leverage any future additions to Optimize features and use them as is.
- EdgeIdentity is used to maintain identity of users and application for consistent behaviour. This is how users are divided in different experiences.
- To make the identity map for use in request following code snippent can be used :
Getting ECID
var ecid = "" Identity.getExperienceCloudId {id -> ecid = id}} private fun getIdentityMap(ecid: String) : Map<String, List<Any>> { val map = mutableMapOf<String, List<Any>>() map["ECID"] = listOf(mapOf("id" to ecid)) return map } |
- Request format:
- Building DecisionScopes, Data and XDM Data would be common for both CDN based approach and Edge based approach.
- For reference check "ODDRequestBuilder" and it's usage in sample application
Request format
{ "type": "decisioning.propositionFetch", "personalization": { "decisionScopes": [ "scope1", "scope2" ], "sendDisplayEvent": false }, "data" : { "variableKey": "variableValue" }, "xdm": { "identityMap": { "ECID": [ { "id": "<ID>" } ] } "xdmKey": "xdmValue" } } |
- ResponseParsing:
- The response would contain one or more payloads which are mapped to different decision scopes. To parse this response we could use the Optimize SDKs exposed methods "OptimizeProposition.fromEventData(Map<String, Object>)". and build a map of Scope to Propositions.
- For refer check "ODDEventProcessor" in sample application.
Response Parsing
val map = mutableMapOf<DecisionScope, OptimizeProposition>() response?.handle?.forEach { event -> event.payload?.forEach { payload -> val proposition = OptimizeProposition.fromEventData(payload) val scope = DecisionScope(proposition.scope) map[scope] = proposition } } |
- Display and Click Tracking:
- For tracking the view and click of propositions OptimizeProposition provides methods that can be called directly. This requires Edge and Core as dependency.
Display and Click
OptimizeProposition.displayed() OptimizeProposition.tapped() |
Conclusion and future
With CDN based approach we were able to solve the clients requirements with existing solutions. It is a great example of making the most out of what tools we have at our disposal. We also came up with other solutions while discussing this problem which would take some time to build and are in pipeline. I am sure as we build better solutions this would become obsolete but it is a great example of how understanding a system inside out can help in rearranging the pieces in a fasion that suites our needs.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.