Integration

Kumulos provides an SDK in the form of a Cordova plugin to ease the integration of the Kumulos Analytics, Push Notification, Crash Reporting and Build features into your hybrid app. This guide provides an overview of setting up the SDK for your project and sample usage.

Prerequisites

Get Started with Cordova

cordova plugin add cordova-plugin-kumulos-sdk

Add https://*.kumulos.com to the Content-Security-Policy meta tag in your app, for example in www/index.html:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:; connect-src 'self' https://*.kumulos.com;">

Get Started with Ionic

ionic cordova plugin add cordova-plugin-kumulos-sdk

Next, add the Kumulos type definitions to your tsconfig.json file:

{
  "files": [
    "node_modules/cordova-plugin-kumulos-sdk/index.d.ts"
  ],
}

You may also need to add connect-src 'self' https://*.kumulos.com; to the Content-Security-Policy meta tag in your app in www/index.html if there is one present.

Initialization

The plugin defines a global window.Kumulos object which is available after the deviceready event has fired. See the example for initialization:

document.addEventListener('deviceready', function () {
    if (typeof Kumulos === 'undefined') {
      console.info('Kumulos plugin not found, assuming browser environment & skipping init...');
      return;
    }

    Kumulos.initialize({
        apiKey: 'YOUR_API_KEY',
        secretKey: 'YOUR_SECRET_KEY'
    });
}, false);

Your API Key and Secret Key can be obtained from your App Dashboard in your agency console.

Checking installs of your App

When you run your app on a simulator or install your app on a device, you can check that the SDK has been initialized correctly by selecting the app and clicking the Installs tab to see the ten most recent installs of your app. Click on any install to see more information.

Recent installs

If you experience any difficulties integrating an SDK or initializing the Kumulos client, please don't hesitate to contact support who are standing by to help!

Installation ID

When initialized for the first time, the Kumulos SDK will create a unique identifier for the app installation that initialized the SDK.

This identifier can be used to target push notifications to a specific device through KScript or the Push Notifications API.

In order to retrieve this installation ID, simply access the getter method:

Kumulos.getInstallId().then(function (id) {
    console.log('Install id: ' + id);
});

Once you have the installation ID, you can send it to your app's backend to be used later for push targeting. For more information about push targeting, please see the KScript Documentation or push notification documentation as appropriate.

Analytics

Kumulos provides concise and easy to consume analytics & reporting features. By initializing the SDK, you automatically get session & engagement reporting out the box.

Session Analytics

Kumulos records sessions based on application foreground and background events. When an app enters the background, Kumulos will wait for an idle period (defaulted to 40 seconds). If there are no more foreground events during that idle period, the current session will be closed.

Session analytics

Event Tracking

Kumulos allows you to track custom analytics events that can be used as a trigger to fire automation rules (e.g. to trigger a push notification) or as steps in a funnel to track conversion through key user journeys in your app.

Track conversion

To track a custom analytics event, use Kumulos.trackEvent as follows:

Kumulos.trackEvent('product.purchased', {
    productId: 404
});

Event tracking is available offline as all events are persisted locally before being synced to the server in batches in the background.

Checking events from your App

When you run your app on a simulator or install your app on a device, you can check that the SDK is recording events correctly by selecting the app and clicking the Installs tab to see the ten most recent installs of your app. Click on any install and then click on the Events tab.

Install events

Alternatively, to see counts of all analytics events, including system events such as opened a push notification, recorded by installs of the app in the last 30 days, expand 'Analytics' and click 'Explore' in the left menu. For comparison, the total number of sessions in the same period is shown.

Analytics Explorer

User Association

Kumulos allows associating a user identifier with the current installation ID. This user identifier is useful for performing analytics aggregations & analyses at the user level, for example, funnels completed by users across multiple devices. You can also optionally associate a collection of attributes with the user.

To associate the current app installation with a user, you can use the helper method as shown below:

Kumulos.associateUserWithInstall("unique-user-id");

User association is time-aware, so say two different users log in to the app, their user IDs will be associated with the same install for the time between subsequent calls to the helper method. For example:

Kumulos.associateUserWithInstall('Bob');
// This event will belong to Bob
Kumulos.trackEvent('product.purchased');
Kumulos.associateUserWithInstall('Alice');
// This event will belong to Alice
Kumulos.trackEvent('product.purchased');

Attributes

You can optionally associate a collection of attributes with the user for targeting, personalization or attribution. To associate attributes with the user, pass a collection into the helper method as shown.

Kumulos.associateUserWithInstall("unique-user-id", {
    "name": "Shawn",
    "age": 25
});

If you do not have a user identifier, use the installation id generated by the Kumulos SDK.

Push

To receive and handle native push notifications, it is recommended to use phonegap-plugin-push. For example:

cordova plugin add phonegap-plugin-push --variable FCM_VERSION=15.0.0

N.B. For the Android platform, you will require cordova-android >= 7.1.0 for the latest push plugin versions

Make sure the package name in config.xml matches the FCM project's package name (sometimes it is necessary to removing and re-add the android platform again to update this properly).

The following example shows how to upload push tokens to Kumulos and then track opens using Phonegap-plugin-push.

var senderId = 'XXXXXXXXXXXX';

var push = PushNotification.init({
    android: {
        senderID: senderId,
        sound: true,
        forceShow: true
    },
    ios: {
        alert: 'true',
        badge: 'true',
        sound: 'true'
    }
})

push.on('registration', function(data) {
    Kumulos.pushStoreToken(data.registrationId);
});

push.on('error', function(e) {
        console.error(e);
});

push.on('notification', function(data) {
    var id = data.additionalData.custom.i;

    Kumulos.pushTrackOpen(id);
});

To remove the token from Kumulos server, please see the example below.

push.unregister(function(data) {
    Kumulos.pushRemoveToken();
});

Finally, if you need to check whether the push notification permission has been granted, you can call the static method:

PushNotification.hasPermission(function(data) {
    if (data.isEnabled) {
        console.log('Push Notifications Enabled');
    }
});

Checking Push Registrations

When you run your app on a simulator or install your app on a device, you can check that the install has successfully registered for push notifications by selecting the app and clicking the Installs tab to see the ten most recent installs of your app. Click on any install and then click on Push tab.

Install push details

Push Channels

The SDK provides methods for subscribing the app installation to push notification channels. These methods are accessed from the client's pushChannels manager property. The interface is declared as follows:

interface PushChannel {
    uuid: String;
    name?: String;
    subscribed: Boolean;
    meta?: any;
}

interface ChannelSpec {
    uuid: String;
    subscribe: Boolean;
    meta?: any;
    name?: String;
    showInPortal?: Boolean;
}

interface PushChannelManager {
    subscribe(uuids: String[]): Promise<Response>;
    unsubscribe(uuids: String[]): Promise<Response>;
    setSubscriptions(uuids: String[]): Promise<Response>;
    clearSubscriptions(): Promise<Response>;
    listChannels(): Promise<PushChannel[]>;
    createChannel(channelSpec: ChannelSpec): Promise<PushChannel>;
}

For example, to list push channels:

Kumulos.getPushSubscriptionManager()
    .listChannels()
    .then(channels => console.log(channels))
    .catch(err => console.error(err));

This will return a list of all public channels (as well as any private channels this install is subscribed to) along with a boolean for whether or not this install is subscribed to that channel. For each channel, you will get:

{
    'uuid',
    'name',
    'meta',
    'subscribed'
}

When creating channels, you can control the visiblity and add meta-data.

Location Tracking

You can send Kumulos location updates and use this to trigger events such as push notifications when an install enters a GeoFence.

How you configure location updates depends on the specific use case of your app. You should consider both accuracy and battery life when making this decision.

Once you have set up location updates from the OS, you can send them to Kumulos like so:

Kumulos.sendLocationUpdate({lat: 0, lng: 0});

Plugins which can provide location updates include:

Beacons

You can send Kumulos beacon proximity updates and use these to trigger automations such as sending a push notification when an install is in proximity to a beacon.

The Kumulos SDK provides helper methods to notify our services of proximity to a detected beacon. Helpers for both Eddystone and iBeacon protocols are provided.

You will need to integrate a suitable plugin to detect the beacon proximity events (for example, https://github.com/petermetz/cordova-plugin-ibeacon).

Eddystone Beacon Detection

Kumulos.trackEddystoneBeaconProximity({
    hexNamespace: 'namespace',
    hexInstance: 'instance',
    distanceMetres: 10
});

Beacon monitoring on Android typically requires a device with BLE, and API level 18+. You can read more about detecting beacons in the Android Nearby reference.

iBeacon Detection

Kumulos.trackiBeaconProximity({
    uuid: 'vendor-uuid',
    major: 1,
    minor: 2
});

Build

You can call API methods defined in the Kumulos Build service using the Kumulos.call method.

To talk to Kumulos, you need three things:

  • your method title (in lowerCamelCase)
  • a method parameters map (field names are also in lowerCamelCase)
  • some response handler code

Example code to make an API call is shown below:

var params = {}
params.name = $('#name').val()
params.email = $('#email').val()
params.password = $('#password').val()

Kumulos.call('createCustomer', params).then(function (result) {
    // Handle result
});

Crash

Crash reporting allows you to track unhandled exceptions in your app, and optionally log any caught exceptions for further investigation. Crash reporting is not enabled by default. To enable this feature, simply modify your Kumulos configuration as follows:

Kumulos.initialize({
    apiKey: 'YOUR_API_KEY',
    secretKey: 'YOUR_SECRET_KEY',
    enableCrashReporting: true
});

That's it! Unhandled exceptions that lead to crashes will now be recorded automatically and shown in your App Delivery Console.

For Cordova & Ionic, the crash reporting feature includes both native code crash reporting, and JavaScript error reporting. Native code crash reporting would catch crashes of the Cordova host process, whilst JavaScript error reporting catches unhandled errors in your application source code.

Source Mapping

If you use a bundling or minification step for your JavaScript sources, you can upload source maps to allow us to show source file locations in your error reports rather than the position in the minified bundle.

In order to use source maps you must take the following actions:

  • Configure your build tool to output source maps for your bundle
  • Set the sourceMapTag field in the Kumulos initialization options
  • Upload source maps matching the version of the configured sourceMapTag

For example:

Kumulos.initialize({
    apiKey: 'YOUR_API_KEY',
    secretKey: 'YOUR_SECRET_KEY',
    enableCrashReporting: true,
    // Configure the version for the source maps
    sourceMapTag: '1.0.0-rc1'
});

Now you would upload the source maps for version 1.0.0-rc1 to the Crash Dashboard in your App Delivery Console.

If you are automating your builds, you can upload the source maps from your CI environment. See the following sample script for reference.

#!/bin/sh
# TODO set version to match the configured sourceMapTag in the SDK init options
VERSION=''

# TODO set up the keys from your App Dashboard
API_KEY='YOUR_API_KEY'
SERVER_KEY='YOUR_SERVER_KEY'

# TODO customize the archiving step to include your source maps
zip -r maps.zip sourcemaps

UPLOAD_URL='https://crash.kumulos.com/sourcemaps'

curl --fail --retry 3 --retry-delay 3 --user "$API_KEY:$SERVER_KEY" -X POST -F version="$VERSION" -F file="@maps.zip" "$UPLOAD_URL"
rm maps.zip

Ionic Error Reporting

To integrate JavaScript error reporting with your Ionic project, you need to define a custom error handler in src/app/app.module.ts.

export class KumulosErrorHandler implements ErrorHandler {
  handleError(err: any): void {
    Kumulos.logUncaughtException(err);
  }
}

In the NgModule configuration, you would then set the error provider item as follows:

{provide: ErrorHandler, useClass: KumulosErrorHandler}

Troubleshooting

iOS: Plugin Installation Code 31

CocoaPods dependency installation can fail if the target build environment has out of date local pod spec definitions. To remedy this, simply run pod repo update prior to executing the Cordova plugin setup.

Add the following script to your project root as pods_update.sh and make it executable:

#!/bin/sh
# This script ensures the local CocoaPods spec repo is up to date
# before installing plugins. It is run as a cordova platform hook.
pod repo update

Add the hook to your config.xml:

...
<platform name="ios">
    <hook src="pods_update.sh" type="before_platform_add" />
...

iOS: Build Failure, Linker Error

If your iOS app builds fail due to missing libraries during the link step, it may be necessary to run the CocoaPods dependency installation step during your build script.

Add the following script to your project root as pods_install.sh and make it executable:

#!/bin/sh
# This script ensures CocoaPods are correctly set up in the iOS project
# when installing plugins which depend on pods.
pod install --project-directory=./platforms/ios

Add the hook to your config.xml:

...
<platform name="ios">
    <hook src="pods_install.sh" type="after_platform_add" />
...

Changelog

3.1.2

  • Record exceptions occurring during lazy init of crash reporting service

3.1.1

  • Record foreground events from initializer where native listeners are too early

3.1.0

  • Add JavaScript error reporting support
  • New config option to support source maps in JS error reporting
  • Fix header search paths issue with iOS builds when built from the CLI instead of Xcode

3.0.0

  • Analytics event tracking with batched background sync
  • Session analytics events
  • Beacon proximity event tracking helpers
  • User association helper

Also publish TypeScript source files.

2.1.0

  • Add helper to send geolocation updates
  • Add additional fields to stats payloads
  • Add convenience for getting install ID

2.0.2

  • Add type definitions file for easier integration with TypeScript projects

2.0.1

  • Remove base64-js

2.0.0

  • Removes the es6-promise polyfill from the plugin bundle to reduce bundle size & improve interoperability for environments that include their own polyfilled or native Promise implementations.

1.1.0

  • Add the ability to create push channels and manage subscription to push channels

1.0.2

  • Set correct SDK version in stats module

1.0.1

  • Fix issue with parameter encoding for RPC API calls

1.0.0

  • Initial SDK release

Thanks

We would like to thank to Travis Kriel from Sketch Advertising in South Africa for diligently correcting a mistake in this guide.