Create and display offers with Decision Management
Learn how to show offers from Journey Optimizer Decision Management in your mobile apps with Experience Platform Mobile SDK.
Journey Optimizer Decision Management helps you to deliver the best offer and experience to your customers across all touchpoints at the right time. Once designed, target your audience with personalized offers.
Decision management makes personalization easy with a central library of marketing offers and a decision engine that applies rules and constraints to rich, real-time profiles created by ÃÛ¶¹ÊÓƵ Experience Platform. As a result, it enables you to send your customers the right offer at the right time. See About Decision Management for more information.
Prerequisites
- Successfully built and run app with SDKs installed and configured.
- Set up the app for ÃÛ¶¹ÊÓƵ Experience Platform.
- Access to Journey Optimizer - Decision Management with the proper permissions to manage offers and decisions as described here.
Learning objectives
In this lesson, you will
- Update your Edge configuration for Decision Management.
- Update your tag property with the Journey Optimizer - Decisioning extension.
- Update your schema to capture proposition events.
- Validate setup in Assurance.
- Create an offer decision, based on offers in Journey Optimizer - Decision Management.
- Update your app to register the Optimizer extension.
- Implement offers from Decision Management in your app.
Setup
Update datastream configuration
To ensure data sent from your mobile app to Platform Edge Network is forwarded to Journey Optimizer - Decision Management, update your datastream.
-
In the Data Collection UI, select Datastreams, and select your datastream, for example Luma Mobile App.
-
Select for Experience Platform and select Edit from the context menu.
-
In the Datastreams > > ÃÛ¶¹ÊÓƵ Experience Platform screen, ensure Offer Decisioning, Edge Segmentation, and ÃÛ¶¹ÊÓƵ Journey Optimizer are selected. If you will do the Target lesson, select Personalization Destinations, too. See ÃÛ¶¹ÊÓƵ Experience Platform settings for more information.
-
To save your datastream configuration, select Save .
Install Journey Optimizer - Decisioning tags extension
-
Navigate to Tags and find your mobile tag property and open the property.
-
Select Extensions.
-
Select Catalog.
-
Search for the ÃÛ¶¹ÊÓƵ Journey Optimizer - Decisioning extension.
-
Install the extension. The extension does not require additional configuration.
Update your schema
- Navigate to Data Collection interface and select Schemas from the left rail.
- Select Browse from the top bar.
- Select your schema to open it.
- In the schema editor, select Add next to Field groups.
- In the Add fields groups dialog,
search for
proposition
, select Experience Event - Proposition Interactions and select Add field groups. This field group collects the experience event data relevant to offers: what offer is presented, as part of which collection, decision, and other parameters (see later in this lesson). But also what is happening with the offer? Is it displayed, interacted with, dismissed, and so forth.
- Select Save to save the changes to your schema.
Validate setup in Assurance
To validate your setup in Assurance:
- Go to the Assurance UI.
- Select Configure in left rail and select next to Validate Setup underneath ADOBE JOURNEY OPTIMIZER DECISIONING.
- Select Save.
- Select Validate Setup in the left rail. Both datastream setup and the SDK setup in your application are validated.
Create placement
Before you can actually create offers, you have to define how and where these offers can be placed in the mobile app. In Decision Management, you define placements for this purpose and you will define a placement for the mobile channel that supports a JSON payload:
-
In the Journey Optimizer UI, select Components from DECISION MANAGEMENT in the left rail.
-
Select Placements from the top bar.
-
If no placement with name Mobile JSON, Mobile as Channel type and JSON as Content type is listed, you must create a placement. Otherwise, continue to Create offers.
To create the Mobile JSON placement:
-
Select Create placement.
- in the Details section, enter
Mobile JSON
as the Name, select Mobile from Channel type and JSON from Content type. - Select Save to save the placement.
- in the Details section, enter
Create offers
-
In the Journey Optimizer UI, select Offers from DECISION MANAGEMENT in the left rail.
-
In the Offers screen, select Browse to see the list of offers.
-
Select Create offer.
-
In the New offer dialog, select Personalized offer and click Next.
-
In the Details step of Create new personalized offer:
- Enter a Name for the offer, for example
Luma - Juno Jacket
, and enter a Start date and time and an End date and time. Outside of these dates, the offer won’t be selected by the Decisioning engine. - Select Next.
- Enter a Name for the offer, for example
-
In the Add representations step of Create new personalized offer:
-
Select Mobile from Channel list, and select Mobile JSON from the Placement list.
-
Select Custom for Content.
-
Select Add content. In the Add personalization dialog:
-
In case a Mode selector is available, ensure it is set to JSON.
-
Enter the following JSON:
code language-json { "title": "Juno Jacket", "text": "On colder-than-comfortable mornings, you'll love warming up in the Juno All-Ways Performance Jacket, designed to compete with wind and chill. Built-in Cocona™ technology aids evaporation, while a special zip placket and stand-up collar keep your neck protected.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/women/tops/jackets/wj06-purple_main.jpg" }
-
Select Save.
-
-
Select Next.
-
-
In the Add constraints step of the Create new personalized offer:
- Set Priority to
10
. - Toggle Include capping off.
- Select Next.
- Set Priority to
-
In the Review step of Create new personalized offer:
- Review the offer, then select Finish.
- In the Save offer dialog, select Save and approve.
-
Repeat steps 3 - 8 to create four more offers with different names and content. All other configuration values, for example Start date and time or Priority, are similar to the first offer you created. You can quickly create duplicate and edit offers.
-
In Journey Optimizer UI, select Offers from the left rail, then select Offers from the top bar.
-
Select the row of the offer that you created.
-
In the right pane, select More actions and from the context menu select Duplicate.
Use the table below to define the four other offers.
table 0-row-2 1-row-2 2-row-2 3-row-2 4-row-2 layout-fixed Offer name Offer content in JSON Luma - Affirm Water Bottle { "title": "Affirm Water Bottle", "text": "You'll stay hydrated with ease with the Affirm Water Bottle by your side or in hand. Measurements on the outside help you keep track of how much you're drinking, while the screw-top lid prevents spills. A metal carabiner clip allows you to attach it to the outside of a backpack or bag for easy access.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/gear/fitness-equipment/ug06-lb-0.jpg" }
Luma - Desiree Fitness Tee { "title": "Desiree Fitness Tee", "text": "When you're too far to turn back, thank yourself for choosing the Desiree Fitness Tee. Its ultra-lightweight, ultra-breathable fabric wicks sweat away from your body and helps keeps you cool for the distance.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/women/tops/tees/ws05-yellow_main.jpg" }
Luma - Adrienne Trek Jacket { "title": "Adrienne Trek Jacket", "text": "You're ready for a cross-country jog or a coffee on the patio in the Adrienne Trek Jacket. Its style is unique with stand collar and drawstrings, and it fits like a jacket should.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/women/tops/jackets/wj08-gray_main.jpg" }
Luma - Aero Daily Fitness Tee { "title": "Aero Daily Fitness Tee", "text": "Need an everyday action tee that helps keep you dry? The Aero Daily Fitness Tee is made of 100% polyester wicking knit that funnels moisture away from your skin. Don't be fooled by its classic style; this tee hides premium performance technology beneath its unassuming look.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/men/tops/tees/ms01-black_main.jpg" }
-
-
As a final step you must create a fallback offer, which is an offer sent to customers if they are not eligible for other offers.
-
Select Create offer.
-
In the New offer dialog, select Personalized offer and select Next.
-
In the Details step of Create new fallback offer, enter a Name for the offer, for example
Luma - Fallback Offer
, and select Next. -
In the Add representations step of Create new fallback offer:
-
Select Mobile from Channel list, and select Mobile JSON from Placement list.
-
Select Custom for Content.
-
Select Add content.
-
In the Add personalization dialog, enter the following JSON and select Save:
code language-json { "title": "Luma", "text": "Your store for sports wear and equipment.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/logos/Luma_Logo.png" }
-
Select Next.
-
-
-
In the Review step of Create new fallback offer:
- Review the offer, then select Finish.
- In the Save offer dialog, select Save and approve.
You should now have the following list of offers:
Create a collection
To present an offer to your mobile app user, you must define an offer collection, consisting of one or more of the offers you created.
-
In the Journey Optimizer UI, select Offers from the left rail.
-
Select Collections from the top bar.
-
Select Create collection.
-
In the New collection dialog, enter a Name for your collection, for example
Luma - Mobile App Collection
, select Create static collection, and click Next. -
In Luma - Mobile App Collection, select the offers you want to include in the collection. For this tutorial, pick the five offers you created. You can easily filter the list using the search field, for example by typing Luma.
-
Select Save.
Create a decision
The final step is to define a decision, which is the combination of one or more decision scopes and your fallback offer.
A decision scope is a combination of a specific placement (for example HTML in an email, or JSON in a mobile app) and one or more evaluation criteria.
An evaluation criterium is the combination of
- an offer collection,
- eligibility rules: for example, is the offer only available for a specific audience,
- a ranking method: when multiple offers are available to pick from, which method do you use to rank them (for example by offer priority, using a formula, or an AI model).
See Key steps to create and manage offers if you want to better understand how placements, rules, rankings, offers, representations, collections, decisions, and so on, interact and relate to each other. This lesson is solely focused on using the output of a decision rather than on the flexibility in defining decisions within Journey Optimizer - Decision Management.
-
In the Journey Optimizer UI, select Offers from the left rail.
-
Select Decisions from the top bar.
-
Select Create decision.
-
In the Details step of Create a new offer decision:
- Enter a Name for the decision, for example
Luma - Mobile App Decision
, enter Start date and time and End date and time. - Select Next.
- Enter a Name for the decision, for example
-
In the Add decision scopes step of Create a new offer decision:
-
Select Mobile JSON from Placement list.
-
In the Evaluation Criteria tile, select Add.
- In the Add Offer Collection dialog, select your offer collection. For example, Luma - Mobile App Collection.
- Select Add.
-
Ensure that None is selected for Eligibility, and Offer priority is selected as the Ranking method.
-
Select Next.
.
-
-
In the Add fallback offer step of Create a new offer decision:
- Select your fallback offer, for example the Luma - Fallback offer.
- Select Next.
-
In the Summary step of Create a new offer decision:
- Select Finish.
- In the Save offer decision dialog, select Save and activate.
- In the Decisions tab, you see your decision with status Live.
Your offer decision, consisting of a set of offers, is now ready for use. To use the decision in your app, you have to refer in your code to the decision scope.
-
In the Journey Optimizer UI, select Offers.
-
Select Decisions from the top bar.
-
Select your decision, for example Luma - Mobile App Decision.
-
In the Decision scopes tile, select Copy.
-
From the contextual menu, select Decision scope.
-
Use any text editor to paste the decision scope for later use. The decision scope has the following JSON format.
code language-json { "xdm:activityId":"xcore:offer-activity:xxxxxxxxxxxxxxx", "xdm:placementId":"xcore:offer-placement:xxxxxxxxxxxxxxx" }
Implement offers in your app
As discussed in previous lessons, installing a mobile tag extension only provides the configuration. Next you must install and register the Optimize SDK. If these steps aren’t clear, review the Install SDKs section.
-
In Xcode, ensure that is added to the list of packages in Package Dependencies. See Swift Package Manager.
-
Navigate to Luma > Luma > AppDelegate in the Xcode Project navigator.
-
Ensure
AEPOptimize
is part of your list of imports.code language-swift import AEPOptimize
-
Ensure
Optimize.self
is part of the array of extensions that you are registering.code language-swift let extensions = [ AEPIdentity.Identity.self, Lifecycle.self, Signal.self, Edge.self, AEPEdgeIdentity.Identity.self, Consent.self, UserProfile.self, Places.self, Messaging.self, Optimize.self, Assurance.self ]
-
Navigate to Luma > Luma > Model > Data > decisions in the Xcode Project navigator. Update the
activityId
andplacementId
values with the decision scope details you copied from the Journey Optimizer interface. -
Navigate to Luma > Luma > Utils > MobileSDK in the Xcode Project navigator. Find the
func updatePropositionOD(ecid: String, activityId: String, placementId: String, itemCount: Int) async
function. Add the following code:code language-swift // set up the XDM dictionary, define decision scope and call update proposition API Task { let ecid = ["ECID" : ["id" : ecid, "primary" : true] as [String : Any]] let identityMap = ["identityMap" : ecid] let xdmData = ["xdm" : identityMap] let decisionScope = DecisionScope(activityId: activityId, placementId: placementId, itemCount: UInt(itemCount)) Optimize.clearCachedPropositions() Optimize.updatePropositions(for: [decisionScope], withXdm: xdmData) }
This function:
-
sets up an XDM dictionary
xdmData
, containing the ECID to identify the profile for which you have to present the offers. -
defines
decisionScope
, an object that is based on the decision you have defined in the Journey Optimizer - Decision Management interface and is defined using the copied decision scope from Create a decision. The Luma app uses a configuration file (decisions.json
) that retrieves the scope parameters, based on the following JSON format:code language-swift "scopes": [ { "name": "name of the scope", "activityId": "xcore:offer-activity:xxxxxxxxxxxxxxx", "placementId": "xcore:offer-placement:xxxxxxxxxxxxxxx", "itemCount": 2 } ]
However, you can use any kind of implementation to ensure the Optimize APIs get the proper parameters (
activityId
,placementId
and,itemCount
), to construct a valid object for your implementation.
For your information: the other key-values in thedecisions.json
file are for future use and not relevant and used currently in this lesson and as as part of the tutorial. -
calls two APIs: and . These functions clear any cached propositions and update the propositions for this profile.
-
-
Navigate to Luma > Luma > Views > Personalization > EdgeOffersView in the Xcode Project navigator. Find the
func onPropositionsUpdateOD(activityId: String, placementId: String, itemCount: Int) async
function and inspect the code of this function. The most important part of this function is the API call, which- retrieves the propositions for the current profile based on the decision scope (which you have defined in Journey Optimizer - Decision Management),
- retrieves the offer from the proposition,
- unwraps the content of the offer so it can be displayed properly in the app, and
- triggers the
displayed()
action on the offer which sends an event back to the Edge Network informing the offer is displayed.
-
Still in EdgeOffersView, add the following code to the
.onFirstAppear
modifier. This code ensures that the callback for updating the offers is registered only once.code language-swift // Invoke callback for offer updates Task { await self.onPropositionsUpdateOD(activityId: decision.activityId, placementId: decision.placementId, itemCount: decision.itemCount) }
-
Still in EdgeOffersView, add the following code to the
.task
modifier. This code updates the offers when the view is refreshed.code language-swift // Clear and update offers await self.updatePropositionsOD(ecid: currentEcid, activityId: decision.activityId, placementId: decision.placementId, itemCount: decision.itemCount)
Validate using the app
-
Rebuild and run the app in the simulator or on a physical device from Xcode, using .
-
Go to the Personalisation tab.
-
Select Edge Personalisation.
-
Scroll to the top, and you see two random offers displayed from the collection that you have defined in the DECISION LUMA - MOBILE APP DECISION tile.
{width="300"}
The offers are random, as you have given all offers the same priority and the ranking for the decision is based on priority.
Validate implementation in Assurance
To validate the offers implementation in Assurance:
-
Review the setup instructions section to connect your simulator or device to Assurance.
-
Select Configure in left rail and select next to Review & Simulate underneath ADOBE JOURNEY OPTIMIZER DECISIONING.
-
Select Save.
-
Select Review & Simulate in the left rail. Both datastream setup is validated and the SDK setup in your application.
-
Select Requests at the top bar. You see your Offers requests.
-
You can explore Simulate and Event List tabs for further functionality, checking your setup of Journey Optimizer Decision Management.
Next steps
You should now have all the tools to start adding more functionality to your Journey Optimizer - Decision Management implementation. For example:
- apply different parameters to your offers (for example, priority, capping)
- collect profile attributes in the app (see Profile) and use these profile attributes to build audiences. Then use these audiences as part of the eligibility rules in your decision.
- combine more than one decision scope.
Next: Perform A/B tests