# Creating Native Applications v4
When it is necessary to integrate product quizzes and recommendations with native applications, developers generally apply one of two methods. The hybrid application route relies on the same robust web UX framework provided by Cartographer. Developers create a mobile-first theme for the quiz, which then gets displayed inside web view component provided by the native platform. A set of application API might need to be provided to the web view implementation to aspects such as displaying product details or checkout.
The web view method could be limiting in some cases, for example, when a true native implelemntation is required or when integrating with other dynamic experiences like chat bots. Cartographer provides Conversations API that allows developers to take advantange of all recommender platform features, including routing, page configuration, questions attribute mapping, while focusing soley on implementing the UI.
# Enabling Conversations API
There is nothing that needs to be done to start using the Conversations API as it is always enabled for all projects. Simply collect your project Draft or Production API key and direct calls to the runtime/conversations
API endpoint.
TIP
In the examples below we will use JavaScript and fetch
API to illustrate Conversations concepts. These can be easily translated to other programming languages and platforms.
# Reference Implementations
A React Native reference implementation can be found in the public Git repository (opens new window). This sample app is fully functional and illustrates all API featuers. It could even be used as a starting point if React Native is your chosen platform for native app development.
# Localizing the UI
All page, question, choice descriptions, or product fields automatically pick translated copy according to locale
parameter.
# Starting a Conversation
Conversations is a stateful API. The current state is represented by a JSON object that is returned by the API. The state then can be modified by the implementation and posted back to the API to process the user input, retrieve the UI state or generate recommendations.
To start the conversation, two parameters are required:
- A project API key, either draft or production mode;
- Requested locale ISO identifier, either in short form (language only), or language and country combination.
State object should be posted as JSON body (Content-Type: application/json) tohttps://api.cartographer.drivecommerce.com/api/v4/runtime/conversations endpoint
(or another latest version).
All initial parameters can be configured as following:
PARAMETER | PURPOSE |
---|---|
project | Project API key |
locale | Locale identifier |
limit | Maximum number of returned recommendations, 3 by default |
TIP
Do not alter user
or session
identifiers.
# Environment
Similar to the Web reference implementation (see documentation (opens new window)), Conversations API also supports a method of pre-selecting some question answers ahead of time.
# Conversations API Differences
Since Conversations API works slightly differently from the Web implementation, there are also minor items to keep in mind when using environment variables:
- Prefilled question is removed from the questionnaire experience. If the question was the only question on a page, that page is also hidden.
- If a prefilled question is the only question on the page, and the page is set to auto-advance, the routing will be applied automatically.
- A prefilled question does not count as an answer on pages with "all optional" questions
- Prefilled questions still affect recommendations according to their mapping.
- Prefilled questions trigger page routing according to page rules.
- Fully prefilled pages are removed from calculates around the current step; total steps; farthest steps; and respective page paths.
- Any question can be prefilled using the environment.
# API Usage
In order to set an environment, use environment
element when sending each conversation request:
{
"project": "HTNIg)njFTVmk)5T7jc_",
"environment": [
{
"question": "Kpv3qcJqRVtaKRSlDJTJ",
"answers": [
"dJGdTlpxOBHgylRxamaX"
]
}
],
...
}
Environment element should be an array of objects; each object should include a question ID or a slug, and a list of respective choices.
# Slugs or Short Codes
Each API object has two identifers: an automatically generated system ID, and a slug. Slugs can be assigned manually in the Cartograher quiz configuration UI and could be helpful to customize the UX presentation.
# Interpreting Pages Structure
After the initial call, and with every following interaction, the state object returned from the API will contain a list of pages that describe the quiz structure. The can be multiple pages in the list — however only the last page is considered current. Preciding pages are included for the reference, for example if the native UI needs to display a history of previous questions or provide a nice animation when going from one page to another.
A sample API response, typically after the initial interaction
{
"user": "...",
"session": "...",
"project": "HTNIg)njFTVmk)5T7jc_",
"limit": 3,
"locale": "en",
"pages": [
{
"page": "7nOqatDc0GTtRO5Vqv8T",
"complete": false,
"resultsPage": false,
"canAdvance": false,
"canReturn": false,
"slug": null,
"description": "Let's brew some coffee",
"questions": [
{
"question": "Kpv3qcJqRVtaKRSlDJTJ",
"description": "Do you want to brew your own coffee today?",
"type": "MultipleChoice",
"showAs": "Buttons",
"choices": [
{
"choice": "dJGdTlpxOBHgylRxamaX",
"slug": null,
"description": "Yes",
"value": null,
"selected": false
},
{
"choice": "5qMhyjepuw9MwvxGDdTo",
"slug": null,
"description": "No",
"value": null,
"selected": false
}
]
}
]
}
],
"recommendations": null
}
Each page object contains a few properties that describe the current page state:
PROPERTY | PURPOSE |
---|---|
page | An automatically generated unique page identifier |
slug | A secondary page identifier as configured in the quiz |
description | Translated page title |
body | Translated page body |
footer | Translated page footer |
image | A body image |
canReturn | If set to true, a user may be able to return to the previous page |
canAdvance | If set to true, a user may advance to the next page (see Advancing the Quiz section) |
complete | If set to true, the page is considered complete and the user will be moved to the next page. |
resultsPage | If set to true, the page does not contain any questions and intented to display recommendations instead. |
questions | Questions list. |
# Questions
A non-results page will also contain a list of questions. Each page may have one or more questions, and a user may be required to answer all or at least one question to advance to the next step.
A question object contains following properties:
PROPERTY | PURPOSE |
---|---|
question | An automatically generated unique question identifier |
slug | A secondary question identifier as configured in the quiz |
description | Translated question title |
body | Translated question body |
footer | Translated question footer |
image | A question image |
type | Question type (see below) |
showAs | Question preferred UX (see below) |
choices | Choices list |
Each question will have one or more possible answers. The question's showAs
parameter defines the preferred UX associated with the question as configured in the Cartographer backend, however this parameter can be overridden by the implementation.
SHOW AS TYPE | DESCRIPTION |
---|---|
Buttons | Show the question as a set of radion buttons, only as single answer can be selected at a time |
MultiSelect | Show the question as a set of checkbox buttons, with multiple choices that could be selected at the same time |
Slider | Show the question as a slider |
Dropdown | Show the question as a dropdown |
# Choices
Each choice object represents a potential answer to the question that can be selected by a user:
PROPERTY | PURPOSE |
---|---|
choice | An automatically generated unique choice identifier |
slug | A secondary choice identifier as configured in the quiz |
description | Translated choice description |
body | Translated choice body |
image | An image associated with the choice |
selected | A flag indicating whether the choice is selected |
# Responding To User Actions
When a user selects question choice, the implementation needs to make selected
choice properties according to the selection. It is up to the implementation to enforce the single-select vs multi-select functionality according to the showAs
question property. However, if a multiple choices are selected for a single select question type, only the first choice will be used by Cartographer backend and rest of choice selections will be ignored.
After the selection, the implementation should modify the state JSON object, post it back to the API endpoint, and recieve the new state object in return.
# Marking a Choice as Selected
// For example, in a single select scenario, unselect other choices first.
someQuestion.choices.forEach((choice) => {
choice.selected = false;
});
// Select the new choice
someChoice.selected = true;
# Update the State
fetch('https://api.cartographer.drivecommerce.com/api/v4/runtime/conversations', {
method: 'POST',
cache: 'no-store',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(stateObject),
}).then((response) => response.json()).then((newState) => {
// Save the new state.
stateObject = newState;
});
# Advancing to the Next Step
Once the user input is processed, the state object will update the current page canAdvance
and complete
properties. Depending on the page type, the two things may happen.
# Auto-Advancing Pages
If the page is configured to autoadvance on completion, the current page complete
property will be automatically set to true
, Conversations API will determine the next page according to page routing rules, and will append the next page to the pages
list. The implementation should detect that the current page had changed, generate the new page UX, and display any appropriate page transition animations.
# Manually Advancing Pages
If the page needs manual advancement, the API will set the canAdvance
property to true
, but will leave complete
property as false
. The implementation should display a Next button and process button clicks. Upon the click, the impementation should set the complete property to true, update the conversation state, and process page transations as in the autoadvancing case. See example code snippet below:
page.complete = true;
# Update the State
// As in the example above...
TIP
A single quiz may have a mix of autoadvancing and manually advancing pages. For example, pages with single choice selections may advance automatically, but pages with multi-select questions could require a Next button click.
# Returning to the Previous Page
If the page canReturn
property is set to true
, the implementation should provide a way to return to the previous question, for example, display a Back button. When a user choses to return to the previous page, the implementation should simply delete the last page from the pages
stack.
# Returning Back
// Simply remove the current (last) page from the stack.
stateObject.pages.pop();
// For example, undo selections on the now last page.
stateObject.pages[stateObject.pages.length - 1].questions.forEach((question) => {
question.choices.forEach((choice) => {
choice.selected = false;
});
});
// Also clear the page complete property to prevent the page autoadvancing again.
stateObject.pages[stateObject.pages.length - 1].complete = false;
# Update the State
// As in the example above...
TIP
The implementation should decide whether to leave previous choices selected or clear them.
# Displaying Recommendations
Ultimately, the goal of the quiz is provide product recommendations to the user. Depending on the quiz configuration, recommendations can be generated:
- After each choice selection. For example, if the quiz UX prefers to display product recommendation as soon as possible and update the recommendations list as the user continues to navigate through quiz questions.
- At the end of the quiz.
In either case, when it is time to display recommendations, Conversations API will populate recommendations
property on the state object.
PROPERTY | PURPOSE |
---|---|
recommendations | Recommendations list. |
recommendationsCount | A number of generated recommendations. |
Recommendations object will contain a number of propeties that describe each product: the product data, information about why a product was chosen for recommendations, and any included custom attibutes.
TIP
Generate some recommendations and explore the API state object to explore recommendations data structure.
# Recommendations JSON
{
"recommendations": {
"recommendations": [
{
"product": {
"externalId": "FrenchPress",
"name": "French Press",
"description": "Offers direct infusion for full-bodied coffee",
"defaultImageUrl": "//cdn.drrv.co/drive/frenchpress@2x.png",
"orderable": true,
"priceCurrency": "USD",
"price": 1.00,
"parentProduct": null
},
"match": 100.0,
"plan": {
"match": 100.0,
"questions": [
{
"factorId": "6sdMYt2cP5u9XzWzeO6o",
"questionId": "Kpv3qcJqRVtaKRSlDJTJ",
"match": 100.0,
"asked": 1.0,
"rating": 1.0
}
],
"verboseData": null
},
"attributes": {},
"segment": {
"name": "Primary",
"slug": null
}
},
...
],
"recommendationsCount": 3,
"recommendationsTruncated": true
}
}