Skip to content

xenonview-com/view-java-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

38 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

xenon-view-sdk

The Xenon View Java SDK is the Java SDK to interact with XenonView.

Table of contents:


What's New

  • v0.1.9 - Added: Downsell, Ad, Content Archive, Subscription Pause and included price/term for all subscriptions
  • v0.1.8 - On socket timeout, close all cached connections and start new see #185024471.
  • v0.1.7 - Add options for term/price for all subscription related calls.
  • v0.1.6 - Add initial subscriptions options for term/price.
  • v0.1.5 - Fix typo
  • v0.1.4 - Rename tag to variant
  • v0.1.3 - Correct name for untag
  • v0.1.2 - Allow tags to take String []
  • v0.1.1 - Android Fixups
  • v0.1.0 - SDK redesign

Introduction

Everyone should have access to world-class customer telemetry.

You should be able to identify the most pressing problems affecting your business quickly. You should be able to determine if messaging or pricing, or technical challenges are causing friction for your customers. You should be able to answer questions like:

  1. Is my paywall wording or the price of my subscriptions causing my customers to subscribe less?
  2. Is my website performance or my application performance driving retention?
  3. Is purchasing a specific product or the product portfolio driving referrals?

With the correct approach to instrumentation coupled with AI-enhanced analytics, you can quickly answer these questions and much more.


back to top

Get Started With The Following Steps:

The Xenon View SDK can be used in your application to provide a new level of customer telemetry. You'll need to embed the instrumentation into your website/application via this SDK.

Instrumentation will vary based on your use case; are you offering a service/subscription (SaaS) or selling products (Ecom)?

In a nutshell, the steps to get started are as follows:

  1. Identify Business Outcomes and Customer Journey Milestones leading to those Outcomes.
  2. Instrument the Outcomes/Milestones.
  3. Analyze the results.

Step 1 - Business Outcomes

Regardless of your business model, your first step will be identifying your desired business outcomes.

Example - Service/Subscription/SaaS:

  1. Lead Capture
  2. Account Signup
  3. Initial Subscription
  4. Renewed Subscription
  5. Upsold Subscription
  6. Referral

Example - Ecom:

  1. Place the product in the cart
  2. Checkout
  3. Upsold
  4. Purchase

πŸ“ Note: Each outcome has an associated success and failure.


Step 2 - Customer Journey Milestones

For each Business Outcome, identify potential customer journey milestones leading up to that business outcome.

Example - Service/Subscription/SaaS for Lead Capture:

  1. View informational content
  2. Asks question in the forum
  3. Views FAQs
  4. Views HowTo
  5. Requests info product

Example - Ecom for Place product in cart :

  1. Search for product information
  2. Learns about product
  3. Read reviews

Step 3 - Enumerate Technical Stack

Next, you will want to figure out which SDK to use. We have some of the most popular languages covered.

Start by listing the technologies involved and what languages your company uses. For example:

  1. Front end - UI (Javascript - react)
  2. Back end - API server (Java)
  3. Mobile app - iPhone (Swift)
  4. Mobile app - Android (Android Java)

Next, figure out how your outcomes spread across those technologies. Below are pointers to our currently supported languages:

Finally, continue the steps below for each technology and outcome.

Step 4 - Installation

After you have done the prework of Step 1 and Step 2, you are ready to install Xenon View. Once installed, you'll need to initialize the SDK and get started instrumenting.



Step 5 - Instrument Business Outcomes

We have provided several SDK calls to shortcut your instrumentation and map to the outcomes identified in Step 1.
These calls will roll up into the associated Categories during analysis. These rollups allow you to view each Category in totality. As you view the categories, you can quickly identify issues (for example, if there are more Failures than Successes for a Category).

Service/Subscription/SaaS Related Outcome Calls (click on a call to see usage)

Category Success Decline
Lead Capture leadCaptured() leadCaptureDeclined()
Account Signup accountSignup() accountSignupDeclined()
Application Installation applicationInstalled() applicationNotInstalled()
Initial Subscription initialSubscription() subscriptionDeclined()
Subscription Renewed subscriptionRenewed() subscriptionCanceled() / subscriptionPaused()
Subscription Upsell subscriptionUpsold() subscriptionUpsellDeclined() / subscriptionDownsell()
Ad Clicked adClicked() adIgnored()
Referral referral() referralDeclined()

Ecom Related Outcome Calls (click on a call to see usage)

Category Success Decline
Lead Capture leadCaptured() leadCaptureDeclined()
Account Signup accountSignup() accountSignupDeclined()
Add To Cart productAddedToCart() productNotAddedToCart()
Product Upsell upsold() upsellDismissed()
Checkout checkedOut() checkoutCanceled() / productRemoved()
Purchase purchased() purchaseCanceled()
Promise Fulfillment promiseFulfilled() promiseUnfulfilled()
Product Disposition productKept() productReturned()
Referral referral() referralDeclined()

Step 6 - Instrument Customer Journey Milestones

Next, you will want to instrument your website/application/backend/service for the identified Customer Journey Milestones Step 2. We have provided several SDK calls to shortcut your instrumentation here as well.

During analysis, each Milestone is chained together with the proceeding and following Milestones. That chain terminates with an Outcome (described in Step 4). AI/ML is employed to determine Outcome correlation and predictability for the chains and individual Milestones. During the analysis step, you can view the correlation and predictability as well as the Milestone chains (called Customer Journeys in this guide).

Milestones break down into two types (click on a call to see usage):

Features Content
featureAttempted() contentViewed()
featureFailed() contentCreated() / contentEdited()
featureCompleted() contentDeleted() / contentArchived()
contentRequested()/contentSearched()

Step 7 - Commit Points

Once instrumented, you'll want to select appropriate commit points. Committing will initiate the analysis on your behalf by Xenon View.



Step 8 (Optional) - Group Customer Journeys

All the customer journeys (milestones and outcomes) are anonymous by default. For example, if a Customer interacts with your brand in the following way:

  1. Starts on your marketing website.
  2. Downloads and uses an app.
  3. Uses a feature requiring an API call.

Each of those journeys will be unconnected and not grouped.

To associate those journeys with each other, you can deanonymize the Customer. Deanonymizing will allow for a deeper analysis of a particular user.

Deanonymizing is optional. Basic matching of the customer journey with outcomes is valuable by itself. Deanonymizing will add increased insight as it connects Customer Journeys across devices.


Step 9 - Analysis

Once you have released your instrumented code, you can head to XenonView to view the analytics.


Step 10 - Perform Experiments

There are multiple ways you can experiment using XenonView. We"ll focus here on three of the most common: time, platform, and variant based cohorts.

Time-based cohorts

Each Outcome and Milestone is timestamped. You can use this during the analysis phase to compare timeframes. A typical example is making a feature change. Knowing when the feature went to production, you can filter in the XenonView UI based on the timeframe before and the timeframe after to observe the results.

Variant-based cohorts

You can identify a journey collection as an experiment before collecting data. This will allow you to run A/B testing-type experiments (of course not limited to two). As an example, let"s say you have two alternate content/feature variants and you have a way to direct half of the users to Variant A and the other half to Variant B. You can name each variant before the section of code that performs that journey. After collecting the data, you can filter in the XenonView UI based on each variant to observe the results.

Platform-based cohorts

You can Platform any journey collection before collecting data. This will allow you to experiment against different platforms:

  • Operating System Name
  • Operating System version
  • Device model (Pixel, iPhone 14, Docker Container, Linux VM, Dell Server, etc.)
  • A software version of your application.

As an example, let's say you have an iPhone and Android mobile application and you want to see if an outcome is more successful on one device verse the other. You can platform before the section of code that performs that flow. After collecting the data, you can filter in the XenonView UI based on each platform to observe the results.




back to top

Detailed Usage

The following section gives detailed usage instructions and descriptions. It provides code examples for each of the calls.


Installation


You can install the Xenon View SDK from maven central:

Via maven:

<dependency>
  <groupId>io.github.xenonview-com</groupId>
  <artifactId>xenon-view-sdk</artifactId>
  <version>0.1.7</version>
</dependency>

Via gradle (groovy):

implementation "io.github.xenonview-com:xenon-view-sdk:0.1.8"

Via gradle (kolin):

implementation("io.github.xenonview-com:xenon-view-sdk:0.1.8")

Via jar download (maven central):

Download required Jars and import as libraries into your project:
Download Jar
Download Dependencies Jar


back to top

Instantiation

The View SDK is a Java module you'll need to include in your application. After inclusion, you'll need to init the singleton object:

import xenon.view.sdk.Xenon;

// start by initializing Xenon View
final Xenon xenon = new Xenon("<API KEY>");

-OR-

import xenon.view.sdk.Xenon;

// to initialize Xenon View after construction
final Xenon xenon = new Xenon();
xenon.init("<API KEY>");

Of course, you'll have to make the following modifications to the above code:

  • Replace <API KEY> with your api key

back to top

Service/Subscription/SaaS Related Business Outcomes


Lead Capture

Use this call to track Lead Capture (emails, phone numbers, etc.) You can add a specifier string to the call to differentiate as follows:


leadCaptured()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String emailSpecified = "Email";
final String phoneSpecified = "Phone Number";

// Successful Lead Capture of an email
xenon.leadCaptured(emailSpecified);
//...
// Successful Lead Capture of a phone number
xenon.leadCaptured(phoneSpecified);

leadCaptureDeclined()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String emailSpecified = "Email";
final String phoneSpecified = "Phone Number"; 

// Unsuccessful Lead Capture of an email
xenon.leadCaptureDeclined(emailSpecified);
// ...
// Unsuccessful Lead Capture of a phone number
xenon.leadCaptureDeclined(phoneSpecified);

Account Signup

Use this call to track when customers signup for an account. You can add a specifier string to the call to differentiate as follows:


accountSignup()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String viaFacebook = "Facebook";
final String viaGoogle = "Facebook";
final String viaEmail = "Email";

// Successful Account Signup with Facebook
xenon.accountSignup(viaFacebook);
// ...
// Successful Account Signup with Google
xenon.accountSignup(viaGoogle);
// ...
// Successful Account Signup with an Email
xenon.accountSignup(viaEmail);

accountSignupDeclined()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String viaFacebook = "Facebook";
final String viaGoogle = "Facebook";
final String viaEmail = "Email";

// Unsuccessful Account Signup with Facebook
xenon.accountSignupDeclined(viaFacebook);
// ...
// Unsuccessful Account Signup with Google
xenon.accountSignupDeclined(viaGoogle);
// ...
// Unsuccessful Account Signup with an Email
xenon.accountSignupDeclined(viaEmail);

Application Installation

Use this call to track when customers install your application.


applicationInstalled()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

// Successful Application Installation
xenon.applicationInstalled();

applicationNotInstalled()

πŸ“ Note: You want consistency between success and failure.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

// Unsuccessful or not completed Application Installation
xenon.applicationNotInstalled();

Initial Subscription

Use this call to track when customers initially subscribe. You can add a specifier string to the call to differentiate as follows:


initialSubscription()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String tierSilver = "Silver 30d";
final String tierGold = "Gold";
final String tierPlatium = "Platium";
final String annualSilver = "Silver Annual";
final String method = "Stripe"; // optional
final String term = "30d"; // optional
final String price = "$25"; //optional

// Successful subscription of the lowest tier with Stripe
xenon.initialSubscription(tierSilver, method);
// ...
// Successful subscription of the middle tier
xenon.initialSubscription(tierGold);
// ...
// Successful subscription of the middle tier with term and price
xenon.initialSubscription(tierGold, term, price, method);
// ...
// Successful subscription to the top tier
xenon.initialSubscription(tierPlatium);
// ...
// Successful subscription of an annual period
xenon.initialSubscription(annualSilver);

subscriptionDeclined()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String tierSilver = "Silver 30d";
final String tierGold = "Gold";
final String tierPlatium = "Platium";
final String annualSilver = "Silver Annual";
final String method = "Stripe"; // optional
final String term = "30d"; // optional
final String price = "$25"; //optional

// Unsuccessful subscription of the lowest tier
xenon.subscriptionDeclined(tierSilver);
// ...
// Unsuccessful subscription of the middle tier
xenon.subscriptionDeclined(tierGold);
// ...
// Unsuccessful subscription of the middle tier with term and price
xenon.subscriptionDeclined(tierGold, term, price, method);
// ...
// Unsuccessful subscription to the top tier
xenon.subscriptionDeclined(tierPlatium);
// ...
// Unsuccessful subscription of an annual period
xenon.subscriptionDeclined(annualSilver, method);

Subscription Renewal

Use this call to track when customers renew. You can add a specifier string to the call to differentiate as follows:


subscriptionRenewed()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String tierSilver = "Silver 30d";
final String tierGold = "Gold";
final String tierPlatium = "Platium";
final String annualSilver = "Silver Annual";
final String method = "Stripe"; //optional
final String term = "30d"; //optional
final String price = "$25"; //optional

// Successful renewal of the lowest tier with Stripe
xenon.subscriptionRenewed(tierSilver, method);
// ...
// Successful renewal of the middle tier
xenon.subscriptionRenewed(tierGold);
// ...
// Successful renewal of the middle tier with term and price
xenon.subscriptionRenewed(tierGold, term, price, method);
// ...
// Successful renewal of the top tier
xenon.subscriptionRenewed(tierPlatium);
// ...
// Successful renewal of an annual period
xenon.subscriptionRenewed(annualSilver);

subscriptionCanceled()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String tierSilver = "Silver 30d";
final String tierGold = "Gold";
final String tierPlatium = "Platium";
final String annualSilver = "Silver Annual";
final String method = "Stripe"; //optional
final String term = "30d"; //optional
final String price = "$25"; //optional

// Canceled subscription of the lowest tier
xenon.subscriptionCanceled(tierSilver);
// ...
// Canceled subscription of the middle tier
xenon.subscriptionCanceled(tierGold);
// ...
// Canceled subscription of the middle tier with term and price
xenon.subscriptionCanceled(tierGold, term, price, method);
// ...
// Canceled subscription of the top tier
xenon.subscriptionCanceled(tierPlatium);
// ...
// Canceled subscription of an annual period with Stripe
xenon.subscriptionCanceled(annualSilver, method);

subscriptionPaused()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String tierSilver = "Silver 30d";
final String tierGold = "Gold";
final String tierPlatium = "Platium";
final String annualSilver = "Silver Annual";
final String method = "Stripe"; //optional
final String term = "30d"; //optional
final String price = "$25"; //optional

// Paused subscription of the lowest tier
xenon.subscriptionPaused(tierSilver);
// ...
// Paused subscription of the middle tier
xenon.subscriptionPaused(tierGold);
// ...
// Paused subscription of the middle tier with term and price
xenon.subscriptionPaused(tierGold, term, price, method);
// ...
// Paused subscription of the top tier
xenon.subscriptionPaused(tierPlatium);
// ...
// Paused subscription of an annual period with Stripe
xenon.subscriptionPaused(annualSilver, method);

Subscription Upsold

Use this call to track when a Customer upgrades their subscription.
You can add a specifier string to the call to differentiate as follows:


subscriptionUpsold()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String tierGold = "Gold 30d";
final String tierPlatium = "Platium";
final String price = "$1.99";
final String annualGold = "Gold Annual";
final String term = "30d"; //optional
final String method = "Stripe"; // optional

// Assume already subscribed to Silver

// Successful upsell of the middle tier with Stripe
xenon.subscriptionUpsold(tierGold, method);
// ...
// Successful subscription upsell of the middle tier with term and price
xenon.subscriptionUpsold(tierGold, term, price, method);
// ...
// Successful upsell of the top tier
xenon.subscriptionUpsold(tierPlatium);
// ...
// Successful upsell of middle tier - annual period
xenon.subscriptionUpsold(annualGold);

subscriptionUpsellDeclined()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String tierGold = "Gold 30d";
final String tierPlatium = "Platium";
final String annualGold = "Gold Annual";
final String method = "Stripe"; //optional
final String term = "30d"; //optional
final String price = "$1.99"; //optional

// Assume already subscribed to Silver

// Rejected upsell of the middle tier
xenon.subscriptionUpsellDeclined(tierGold);
// ...
// Rejected upsell of the top tier
xenon.subscriptionUpsellDeclined(tierPlatium);
// ...
// Rejected subscription upsell of the middle tier with term and price
xenon.subscriptionUpsellDeclined(tierGold, term, price, method);
// ...
// Rejected upsell of middle tier - annual period with Stripe
xenon.subscriptionUpsellDeclined(annualGold, method);

subscriptionDownsell()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String tierGold = "Gold 30d";
final String tierPlatium = "Platium";
final String annualGold = "Gold Annual";
final String method = "Stripe"; //optional
final String term = "30d"; //optional
final String price = "$1.99"; //optional

// Assume already subscribed to Platium

// Downsell to Gold
xenon.subscriptionDownsell(tierGold);
// ...
// Downsell to Gold annual with method
xenon.subscriptionDownsell(annualGold, method);

// Downsell to Gold - annual period with Stripe for $15
xenon.subscriptionDownsell(tierGold, term, price, method);

Ad Clicked

Use this call to track when customers click on an Advertisement. You can add a specifier string to the call to differentiate as follows:


adClicked()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String provider = "AdMob";
final String id = "ID-1234"; // optional
final String price = "$0.25"; // optional

// Click an Ad from AdMob
xenon.adClicked(provider);
// ...
// Click an Ad from AdMob identfied by ID-1234
xenon.adClicked(provider, id);
// ...
// Click an Ad from AdMob identfied by ID-1234 with price
xenon.adClicked(provider, id, price);

adIgnored()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String provider = "AdMob";
final String id = "ID-1234"; // optional
final String price = "$0.25"; // optional

// No action on an Ad from AdMob
xenon.adIgnored(provider);
// ...
// No action on an Ad from AdMob identfied by ID-1234
xenon.adIgnored(provider, id);
// ...
// No action on an Ad from AdMob identfied by ID-1234 with price
xenon.adIgnored(provider, id, price);

Referral

Use this call to track when customers refer someone to your offering. You can add a specifier string to the call to differentiate as follows:


referral()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String kind = "Share";
final String detail = "Review"; // optional

// Successful referral by sharing a review
xenon.referral(kind, detail);
// -OR-
xenon.referral(kind);

referralDeclined()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String kind = "Share";
final String detail = "Review"; // optional

//Customer declined referral 
xenon.referralDeclined(kind, detail);
// -OR-
xenon.referralDeclined(kind);

back to top

Ecommerce Related Outcomes


Lead Capture

Use this call to track Lead Capture (emails, phone numbers, etc.) You can add a specifier string to the call to differentiate as follows:


leadCaptured()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String emailSpecified = "Email";
final String phoneSpecified = "Phone Number";

// Successful Lead Capture of an email
xenon.leadCaptured(emailSpecified);
// ...
// Successful Lead Capture of a phone number
xenon.leadCaptured(phoneSpecified);

leadCaptureDeclined()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String emailSpecified = "Email";
final String phoneSpecified = "Phone Number"; 

// Unsuccessful Lead Capture of an email
xenon.leadCaptureDeclined(emailSpecified);
// ...
// Unsuccessful Lead Capture of a phone number
xenon.leadCaptureDeclined(phoneSpecified);

Account Signup

Use this call to track when customers signup for an account. You can add a specifier string to the call to differentiate as follows:


accountSignup()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String viaFacebook = "Facebook";
final String viaGoogle = "Facebook";
final String viaEmail = "Email";

// Successful Account Signup with Facebook
xenon.accountSignup(viaFacebook);
// ...
// Successful Account Signup with Google
xenon.accountSignup(viaGoogle);
// ...
// Successful Account Signup with an Email
xenon.accountSignup(viaEmail);

accountSignupDeclined()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String viaFacebook = "Facebook";
final String viaGoogle = "Facebook";
final String viaEmail = "Email";

// Unsuccessful Account Signup with Facebook
xenon.accountSignupDeclined(viaFacebook);
// ...
// Unsuccessful Account Signup with Google
xenon.accountSignupDeclined(viaGoogle);
// ...
// Unsuccessful Account Signup with an Email
xenon.accountSignupDeclined(viaEmail);

Add Product To Cart

Use this call to track when customers add a product to the cart. You can add a specifier string to the call to differentiate as follows:


productAddedToCart()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String laptop = "Dell XPS";
final String keyboard = "Apple Magic Keyboard";

// Successful adds a laptop to the cart
xenon.productAddedToCart(laptop);
// ...
// Successful adds a keyboard to the cart
xenon.productAddedToCart(keyboard);

productNotAddedToCart()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String laptop = "Dell XPS";
final String keyboard = "Apple Magic Keyboard";

// Doesn"t add a laptop to the cart
xenon.productNotAddedToCart(laptop);
// ...
// Doesn"t add a keyboard to the cart
xenon.productNotAddedToCart(keyboard);

Upsold Additional Products

Use this call to track when you upsell additional product(s) to customers. You can add a specifier string to the call to differentiate as follows:


upsold()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String laptop = "Dell XPS";
final String keyboard = "Apple Magic Keyboard";
final String keyboardValue = "$139"; //optional

// upsold a laptop
xenon.upsold(laptop);
// ...
// upsold a keyboard with price
xenon.upsold(keyboard, keyboardValue);

upsellDismissed()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String laptop = "Dell XPS";
final String keyboard = "Apple Magic Keyboard";
final String keyboardValue = "$139"; //optional

// Doesn't add a laptop during upsell
xenon.upsellDismissed(laptop);
// ...
// Doesn't add a keyboard during upsell
xenon.upsellDismissed(keyboard, keyboardValue);

Customer Checks Out

Use this call to track when your Customer is checking out.


checkedOut()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

// Successful Checkout
xenon.checkedOut();

checkoutCanceled()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

//Customer cancels check out.
xenon.checkoutCanceled();

productRemoved()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String laptop = "Dell XPS";
final String keyboard = "Apple Magic Keyboard";

// Removes a laptop during checkout
xenon.productRemoved(laptop);
// ...
// Removes a keyboard during checkout
xenon.productRemoved(keyboard);

Customer Completes Purchase

Use this call to track when your Customer completes a purchase.


purchased()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String method = "Stripe";
final String price = "$2011"; // optional

// Successful Purchase for $2011
xenon.purchased(method, price);

purchaseCanceled()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String method = "Stripe"; // optional
final String price = "$2011"; // optional

//Customer cancels the purchase.
xenon.purchaseCanceled();
// -OR-
xenon.purchaseCanceled(method);
// -OR-
xenon.purchaseCanceled(method, price);

Purchase Shipping

Use this call to track when your Customer receives a purchase.


promiseFulfilled()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

// Successfully Delivered Purchase
xenon.promiseFulfilled();

promiseUnfulfilled(()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

// Problem Occurs During Shipping And No Delivery
xenon.promiseUnfulfilled();

Customer Keeps or Returns Product

Use this call to track if your Customer keeps the product. You can add a specifier string to the call to differentiate as follows:


productKept()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String laptop = "Dell XPS";
final String keyboard = "Apple Magic Keyboard";

//Customer keeps a laptop
xenon.productKept(laptop);
// ...
//Customer keeps a keyboard
xenon.productKept(keyboard);

productReturned()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String laptop = "Dell XPS";
final String keyboard = "Apple Magic Keyboard";

//Customer returns a laptop
xenon.productReturned(laptop);
// ...
//Customer returns a keyboard
xenon.productReturned(keyboard);

Referrals

Use this call to track when customers refer someone to your offering. You can add a specifier string to the call to differentiate as follows:


referral()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String kind = "Share Product";
final String detail = "Dell XPS";

// Successful referral by sharing a laptop
xenon.referral(kind, detail);

referralDeclined()

πŸ“ Note: You want to be consistent between success and failure and match the specifiers

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String kind = "Share Product";
final String detail = "Dell XPS";

//Customer declined referral 
xenon.referralDeclined(kind, detail);

back to top

Customer Journey Milestones

As a customer interacts with your brand (via Advertisements, Marketing Website, Product/Service, etc.), they journey through a hierarchy of interactions. At the top level are business outcomes. In between Outcomes, they may achieve other milestones, such as interacting with content and features. Proper instrumentation of these milestones can establish correlation and predictability of business outcomes.

As of right now, Customer Journey Milestones break down into two categories:

  1. Feature Usage
  2. Content Interaction

Feature Usage

Features are your product/application/service's traits or attributes that deliver value to your customers. They differentiate your offering in the market. Typically, they are made up of and implemented by functions.


featureAttempted()

Use this function to indicate the start of feature usage.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String name = "Scale Recipe";
final String detail = "x2"; // optional

//Customer initiated using a feature 
xenon.featureAttempted(name, detail);
// -OR-
xenon.featureAttempted(name);

featureCompleted()

Use this function to indicate the successful completion of the feature.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String name = "Scale Recipe";
final String detail = "x2"; // optional

// ...
// Customer used a feature 
xenon.featureCompleted(name, detail);

// -OR-

// Customer initiated using a feature 
xenon.featureAttempted(name, detail);
// ...
// feature code/function calls
// ...
// feature completes successfully 
xenon.featureCompleted(name, detail);
// -OR-
xenon.featureCompleted(name);

featureFailed()

Use this function to indicate the unsuccessful completion of a feature being used (often in the exception handler).

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();


final String name = "Scale Recipe";
final String detail = "x2"; // optional


//Customer initiated using a feature 
xenon.featureAttempted(name, detail);
try {
  // feature code that could fail
}
catch(err) {
  //feature completes unsuccessfully 
  xenon.featureFailed(name, detail);
  // -OR-
  xenon.featureFailed(name);
}

back to top

Content Interaction

Content is created assets/resources for your site/service/product. It can be static or dynamic. You will want to mark content that contributes to your Customer's experience or buying decision. Typical examples:

  • Blog
  • Blog posts
  • Video assets
  • Comments
  • Reviews
  • HowTo Guides
  • Charts/Graphs
  • Product/Service Descriptions
  • Surveys
  • Informational product

contentViewed()

Use this function to indicate a view of specific content.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String contentType = "Blog Post";
final String identifier = "how-to-install-xenon-view"; // optional

// Customer view a blog post 
xenon.contentViewed(contentType, identifier);
// -OR-
xenon.contentViewed(contentType);

contentEdited()

Use this function to indicate the editing of specific content.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String contentType = "Review";
final String identifier = "Dell XPS"; //optional
final String detail = "Rewrote"; //optional

//Customer edited their review about a laptop
xenon.contentEdited(contentType, identifier, detail);
// -OR-
xenon.contentEdited(contentType, identifier);
// -OR-
xenon.contentEdited(contentType);

contentCreated()

Use this function to indicate the creation of specific content.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String contentType = "Blog Comment";
final String identifier = "how-to-install-xenon-view"; // optional

//Customer wrote a comment on a blog post
xenon.contentCreated(contentType, identifier);
// -OR- 
xenon.contentCreated(contentType);

contentDeleted()

Use this function to indicate the deletion of specific content.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String contentType = "Blog Comment";
final String identifier = "how-to-install-xenon-view"; // optional

//Customer deleted their comment on a blog post 
xenon.contentDeleted(contentType, identifier);
// -OR- 
xenon.contentDeleted(contentType);

contentArchived()

Use this function to indicate archiving specific content.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String contentType = "Blog Comment";
final String identifier = "how-to-install-xenon-view"; // optional

//Customer archived their comment on a blog post 
xenon.contentArchived(contentType, identifier);
// -OR- 
xenon.contentArchived(contentType);

contentRequested()

Use this function to indicate the request for specific content.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String contentType = "Info Product";
final String identifier = "how-to-efficiently-use-google-ads"; // optional

//Customer requested some content
xenon.contentRequested(contentType, identifier);
// -OR- 
xenon.contentRequested(contentType);

contentSearched()

Use this function to indicate when a user searches.

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String contentType = "Info Product";

// Customer searched for some content
xenon.contentSearched(contentType);

back to top

Commit Points

Business Outcomes and Customer Journey Milestones are tracked locally in memory until you commit them to the Xenon View system. After you have created (by either calling a milestone or outcome) a customer journey, you can commit it to Xenon View for analysis as follows:


commit()

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

// you can commit a journey to Xenon View
xenon.commit();
// -OR-
final Json json = xenon.commit().get();

This call commits a customer journey to Xenon View for analysis.


back to top

Heartbeats

Business Outcomes and Customer Journey Milestones are tracked locally in memory until you commit them to the Xenon View system. You can use the heartbeat call if you want to commit in batch. Additionally, the heartbeat call will update a last-seen metric for customer journeys that have yet to arrive at Business Outcome. The last-seen metric is useful when analyzing stalled Customer Journeys.

Usage is as follows:


heartbeat()

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

// you can heartbeat to Xenon View
xenon.heartbeat();
// -OR-
final Json json = xenon.heartbeat().get();

This call commits any uncommitted journeys to Xenon View for analysis and updates the last accessed time.


back to top

Platforming

After you have initialized Xenon View, you can optionally specify platform details such as:

  • Operating System Name
  • Operating System version
  • Device model (Pixel, Docker Container, Linux VM, Dell Server, etc.)
  • A software version of your application.

platform()

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String softwareVersion = "5.1.5";
final String deviceModel = "Pixel 4 XL";
final String operatingSystemVersion = "12.0";
final String operatingSystemName = "Android";

// you can add platform details to outcomes
xenon.platform(softwareVersion, deviceModel, operatingSystemName, operatingSystemVersion);

This adds platform details for each outcome (Saas/Ecom). Typically, this would be set once at initialization:

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

xenon.init("<API KEY>");

final String softwareVersion = "5.1.5";
final String deviceModel = "Pixel 4 XL";
final String operatingSystemVersion = "12.0";
final String operatingSystemName = "Android";
xenon.platform(softwareVersion, deviceModel, operatingSystemName, operatingSystemVersion);

back to top

Experiments

After you have initialized Xenon View, you can optionally name variants of customer journeys. Named variants facilitate running experiments such as A/B or split testing.

πŸ“ Note: You are not limited to just 2 (A or B); there can be many. Additionally, you can have multiple variant names.


variant()

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

final String variantName = "subscription-variant-A";
final String[] variantNames = {variantName};

// you can name variants for to outcomes
xenon.variant(variantNames);

This adds variant names to each outcome while the variant in play (Saas/Ecom). Typically, you would name a variant once you know the active experiment for this Customer:

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

xenon.init("<API KEY>");
let experimentName = getExperiment();
xenon.variant([experimentName]);

resetVariants()

import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

// you can clear all variant names with the resetVariants method
xenon.resetVariants();

back to top

Customer Journey Grouping

Xenon View supports both anonymous and grouped (known) journeys.

All the customer journeys (milestones and outcomes) are anonymous by default. For example, if a Customer interacts with your brand in the following way:

  1. Starts on your marketing website.
  2. Downloads and uses an app.
  3. Uses a feature requiring an API call.

Each of those journeys will be unconnected and not grouped.

To associate those journeys with each other, you can use deanonymize(). Deanonymizing will allow for a deeper analysis of a particular user.

Deanonymizing is optional. Basic matching of the customer journey with outcomes is valuable by itself. Deanonymizing will add increased insight as it connects Customer Journeys across devices.

Usage is as follows:


deanonymize()

import xenon.view.sdk.Xenon;
import org.json.JSONObject;

final Xenon xenon = new Xenon();


// you can deanonymize before or after you have committed journey (in this case after):
JSONObject person = new JSONObject(){{
    put("name","Java Test");
    put("email","javatest@example.com");
}};
xenon.deanonymize(person);
// -OR-
final Json json = xenon.deanonymize().get();

// you can also deanonymize with a user ID:
JSONObject person = new JSONObject(){{
    put("UUID","<some unique ID>");
}};
xenon.deanonymize(person);

This call deanonymizes every journey committed to a particular user.

πŸ“ Note: With journeys that span multiple platforms (e.g., Website->Android->API backend), you can group the Customer Journeys by deanonymizing each.


back to top

Other Operations

There are various other operations that you might find helpful:



Error handling

In the event of an API error when committing, the method returns a promise.

πŸ“ Note: The default handling of this situation will restore the journey (appending newly added pageViews, events, etc.) for future committing. If you want to do something special, you can do so like this:

import xenon.view.sdk.Xenon;
import xenon.xenon.sdk.api.fetch.Json;

final Xenon xenon = new Xenon();

// you can handle errors if necessary
new Xenon().commit().exceptionally((err)->{
    // handle error
    return Json("{}");
});

Custom Milestones

You can add custom milestones if you need more than the current Customer Journey Milestones.


milestone()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();

// you can add a custom milestone to the customer journey
let category = "Function";
let operation = "Called";
let name = "Query Database";
let detail = "User Lookup";
xenon.milestone(category, operation, name, detail);

This call adds a custom milestone to the customer journey.


Journey IDs

Each Customer Journey has an ID akin to a session. After committing an Outcome, the ID remains the same to link all the Journeys. If you have a previous Customer Journey in progress and would like to append to that, you can get/set the ID.

πŸ“ Note: For Java, the Journey ID is a persistent session variable. Therefore, subsequent Outcomes will reuse the Journey ID if the Customer had a previous browser session.

After you have initialized the Xenon singleton, you can:

  1. Use the default UUID
  2. Set the Customer Journey (Session) ID
  3. Regenerate a new UUID
  4. Retrieve the Customer Journey (Session) ID

id()
import xenon.view.sdk.Xenon;

final Xenon xenon = new Xenon();
// by default has Journey ID
expect(xenon.id()).not.toBeNull();
expect(xenon.id()).not.toEqual("");

// you can also set the id
let testId = "<some random uuid>";
xenon.id(testId);
expect(xenon.id()).toEqual(testId);

// Lastly, you can generate a new Journey ID (useful for serialized async operations that are for different customers)
xenon.newId();
expect(xenon.id()).not.toBeNull();
expect(xenon.id()).not.toEqual("");

back to top

License

Apache Version 2.0

See LICENSE

back to top