{"_id":"5b4dcfe26727e800038b0d18","project":"55dd9f2e0efd5821000d54d9","version":{"_id":"55dd9f4dab0e4d210045aae9","__v":45,"project":"55dd9f2e0efd5821000d54d9","createdAt":"2015-08-26T11:13:17.024Z","releaseDate":"2015-08-26T11:13:17.024Z","categories":["55dd9f4dab0e4d210045aaea","55ddb5fa9067202b00ddff6f","55e0472c6bad670d0081f213","55e04764a44fae0d00214671","55e047a9a44fae0d00214672","55e047b258c5460d0076a9a7","55e95e337fc27b2d00d32cf2","55e979bda7ca823900ad549a","55edb8c18dcb210d0056900b","55f0365c8563861700a33765","55f03677d58f9b1900acf996","55f036938eeefc23001ea5de","55f036a38563861700a33767","55f036c08563861700a33769","55f036d02911b72100482cd7","55f036e92911b72100482cd9","55f036fa8563861700a3376b","55f0370ee507711900e58c69","55f0371df6101b1900c70700","55f0374f2911b72100482cdb","55f0375e2911b72100482cdc","560eb0f659cb8d0d0015cd52","560eb25239fad419002ae1e0","561fb64d4d67490d00804b2a","562b9f775a39cd0d009aff22","562ba0505a39cd0d009aff23","562ba149d56bc30d00f0cb18","562ba595f68a5f0d007b1f3b","562ba78fd56bc30d00f0cb1b","562ba8b95a39cd0d009aff27","562baadf6562140d001501d2","562bab37f68a5f0d007b1f3d","562bc1bf9ebc950d000f7523","562bc99ced4bea0d00c11dfa","562bd29c1b98640d00714520","562bd5875a39cd0d009aff60","562bdfabff2da50d002c0aaf","562be0bd5a39cd0d009aff75","57a0b476d8313e1900454439","5b19051beece890003020163","5b34ded01cb20f000391ad6d","5b3a325acffe770003fd29e5","5b3c737a7f7b890003365501","5b3c929b367036000391b11e","5b7c1e210dc2e20003871521"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.0.0","version":"2"},"category":{"_id":"5b34ded01cb20f000391ad6d","project":"55dd9f2e0efd5821000d54d9","version":"55dd9f4dab0e4d210045aae9","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2018-06-28T13:12:48.898Z","from_sync":false,"order":2,"slug":"push-notifications","title":"Push notifications"},"user":"5a251846c297dc0012e531cd","githubsync":"","__v":0,"parentDoc":null,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2018-07-17T11:15:46.515Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":5,"body":"[block:html]\n{\n  \"html\": \"<div id=\\\"userMap\\\">\\n<div class=\\\"content\\\"><a href=\\\"https://developer.dotmailer.com/v2/docs/creating-a-push-notification-profile\\\"><div class=\\\"box box1\\\">Create a push notification profile in dotmailer</div></a></div>\\n<div class=\\\"arrow\\\">→</div>\\n<div class=\\\"content\\\"><a href=\\\"https://developer.dotmailer.com/v2/docs/creating-a-json-web-token\\\"><div class=\\\"box box2\\\">Create a class or function that generates a JSON Web Token</div></a></div>\\n<div class=\\\"arrow\\\">→</div>\\n<div class=\\\"content\\\"><a href=\\\"https://developer.dotmailer.com/v2/docs/setting-up-push-notifications#section-mobile-sdk-options\\\"><div class=\\\"box box3 active\\\">Use one of our mobile SDKs in your app</div></a></div>\\n<div class=\\\"clearfix\\\"></div></div>\\n\\n<style>\\n  .box {\\n    padding: 10px;\\n    border: 2px solid #000;\\n    width: 120px;\\n    height: 120px;\\n    background-color: #EAEAEA;\\n    hyphens: auto;\\n    float: left;\\n    font-size: 12px;\\n}\\n\\n.box:hover {\\n    background-color: #82bc42;\\n}\\n\\n.box.active {\\n    background-color: #82bc42;\\n}\\n\\n#userMap {\\n    overflow-x: auto;\\n    overflow-y: auto;\\n    padding: 20px;\\n    min-width: 770px;\\n}\\n\\n#userMap a:hover {\\n    text-decoration: none;\\n  }\\n\\ndiv.arrow {\\n    max-width: 50px;\\n    margin-left: 15px;\\n    margin-right: 15px;\\n    font-size: 50px;\\n}\\n\\n\\n#userMap div.arrow, #userMap div.content {\\n    float: left;\\n}\\n\\n.clearfix {\\n    clear: both;\\n}\\n\\n\\n#userMap div.arrow {\\n    position: relative;\\n    top: 45px;\\n}\\n\\n.box1 {\\n    margin-left:0px;\\n}\\n\\ndiv.box.box1 {\\n    margin-left: -20px;\\n}\\n\\n</style>\"\n}\n[/block]\nUnlike our native mobile SDKs, the JavaScript SDK is for cross-platform apps, therefore, after you've added the JavaScript SDK code to your app, you must [use a framework, such as Cordova (with PhoneGap) to get a native device token (registration ID)](#section-using-a-javascript-framework-to-get-a-native-device-token), and send it to dotmailer through the JavaScript SDK.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/904f532-JavaScript-SDK-push.png\",\n        \"JavaScript-SDK-push.png\",\n        1588,\n        1123,\n        \"#88c34d\"\n      ],\n      \"caption\": \"JS framework sending the registration ID between dotmailer and your app\"\n    }\n  ]\n}\n[/block]\nTo set up push notifications for cross-platform apps, complete the following tasks:\n\n1. [Install the JavaScript SDK](#section-installing-the-javascript-sdk)\n2. [Configure the JavaScript SDK](#section-configuring-the-javascript-sdk)\n3. [Initialise the JavaScript SDK](#section-initialising-the-javascript-sdk)\n4. [Add an email address to the web app user's profile](#section-adding-an-email-address-to-the-web-app-user-s-profile)\n\n# Installing the JavaScript SDK\n\nThe JavaScript SDK can be installed from either NPM or Bower, depending on your intended usage.\n\nIf you use classical JavaScript in your project, and you just want to include a script that exposes some global objects on your page, use Bower.\n\nIf you use ES6 modules in your project, for example in the Angular and Ionic 2 frameworks, use NPM. The examples for the NPM package are in TypeScript because the NPM version of the SDK is written in TypeScript.\n\nThis tutorial explains how to use the SDK with JavaScript, but you can find a full sample of the TypeScript code in the ['JavaScript SDK sample code in TypeScript' section](#section-javascript-sdk-sample-code-in-typescript).\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"ES6 Promises are used in this SDK. Depending on which browsers you are targeting, you may need to use a polyfill.\",\n  \"title\": \"ES6 Promises\"\n}\n[/block]\n## NPM\n\n1. Install the JavaScript SDK\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"$ npm install :::at:::comapi/sdk-js-foundation --save\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\n2. Import the `Foundation`, `ComapiConfig`, and `IAuthChallengeOptions ` modules from the SDK file\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import { Foundation } from \\\"@comapi/sdk-js-foundation\\\"\\nimport { ComapiConfig } from \\\"@comapi/sdk-js-foundation\\\"\\nimport { IAuthChallengeOptions } from \\\"@comapi/sdk-js-foundation\\\"\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n## Bower\n\n1. Install the JavaScript SDK\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"$ bower install comapi-sdk-js-foundation\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\n2. Import the script into your project\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<script src=\\\"bower_components/comapi-sdk-js-foundation/dist/comapi-foundation.js\\\"></script>\\n//Minified version\\n<script src=\\\"bower_components/comapi-sdk-js-foundation/dist/comapi-foundation.min.js\\\"></script>\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\n# Configuring the JavaScript SDK\n\nBefore you can configure the JavaScript SDK, you need the following:\n\n* The value of the [API space ID field in dotmailer](doc:creating-a-push-notification-profile#section-finding-your-api-space-id)\n* A function that [creates a JWT](doc:creating-a-json-web-token)\n\n1. Create a `ComapiConfig` object by calling the `Comapi.ComapiConfig()` constructor\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var comapiConfig = new COMAPI.ComapiConfig();\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n2. Pass your API Space ID to the `withApiSpaceId()` method\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var comapiConfig = new COMAPI.ComapiConfig()\\n    .withApiSpace(appConfig.apiSpaceId);\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n3. Pass the function that creates a JWT to the `withAuthChallenge()` method\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var comapiConfig = new COMAPI.ComapiConfig()\\n    .withApiSpace(appConfig.apiSpaceId)\\n    .withAuthChallenge(challengeHandler);\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n# Initialising the JavaScript SDK\n\nAfter you've configured the SDK, pass the `comapiConfig` object to the `initialise()` method.\n\nThis method creates a valid session by calling your JWT function and by using the JWT to create the user's profile ID (`profileId` string).\n\nWhen a session is stopped and started again, a new JWT token is created and used to create a new profile ID.\n\nA session is stopped in any of the following circumstances:\n\n* The user uninstalls the app, and then reinstalls it\n* The user clears all of the app's data\n\nYour app needs a valid session in order to add an email address to the user's profile.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"COMAPI.Foundation.initialise(comapiConfig)\\n    .then(function (sdk) {\\n        console.log(\\\"Foundation interface created\\\", sdk);\\n    })\\n    .catch(function (error) {\\n        $log.error(\\\"paragonService: failed to initialise\\\", error);\\n    });\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n# Adding an email address to the web app user's profile\n\nPush notifications can be sent from dotmailer only to users who have a profile that contains an email address.\n\nIf you want to update a profile, you need to query it first, make the appropriate changes to it, then update it.\n\nWhen you query a profile, that profile contains an `eTag` string, which is used to check that the profile hasn't already been updated before you update it.\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Ask users to enter their email address\",\n  \"body\": \"You should ask users if they'd like to receive push notifications from you and prompt them to enter their email address.\"\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"sdk.profile.getMyProfile()\\n    .then(function (profile) {\\n  \\t\\t\\tprofile.email = \\\"exampleappuser1@gmail.com\\\";\\n        sdk.services.profile.updateMyProfile(profile);\\n    })\\n    .catch(function (error) {\\n        console.error(\\\"getMyProfile() failed\\\", error);\\n    });\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nAt this point, push notifications can't be displayed on the device of your app users, unless you use a third-party framework to get a native device token and handle displaying the push notification.\n\n# JavaScript SDK sample code in TypeScript\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// some app specific imports\\nimport { AppSettings } from \\\"../settings\\\";\\nimport { AuthService } from \\\"./auth\\\";\\n\\n// Comapi class / interface imports\\nimport { Foundation, ComapiConfig, IAuthChallengeOptions } from \\\"@comapi/sdk-js-foundation\\\"\\n\\nexport class ComapiService {\\n\\n    public sdk: Foundation;\\n\\n    private challengeHandler(options: IAuthChallengeOptions, answerAuthenticationChallenge) {\\n        this._authService.getToken(options.nonce)\\n            .then((token) => {\\n                answerAuthenticationChallenge(token);\\n            });\\n    }\\n\\n    constructor(private _authService: AuthService) { }\\n\\n    /**\\n     * Public method to encapsulate up the initialisation of Comapi \\n     */\\n    public initialise(): Promise<Foundation> {\\n\\n        return new Promise((resolve, reject) => {\\n\\n            if (this._authService.isAuthenticated()) {\\n\\n                let comapiConfig = new ComapiConfig()\\n                    .withApiSpace(AppSettings.APP_SPACE_ID)\\n                    // Note the this pointer binding so I can access this._authService in the authChallenge calllback\\n                    .withAuthChallenge(this.challengeHandler.bind(this));\\n\\n                Foundation.initialise(comapiConfig)\\n                    .then((sdk) => {\\n                        this.sdk = sdk;\\n                        console.log(\\\"foundation interface created\\\");\\n                        resolve(sdk);\\n                    })\\n                    .catch((error) => {\\n                        console.error(\\\"initialise failed\\\", error);\\n                        reject(error);\\n                    });\\n            } else {\\n                reject(\\\"Not logged in\\\");\\n            }\\n        });\\n    }\\n}\",\n      \"language\": \"javascript\",\n      \"name\": \"JavaScript SDK sample code in TypeScript\"\n    }\n  ]\n}\n[/block]\n# Using a JavaScript framework to get a native device token\n\nMany frameworks, such as [React Native](https://facebook.github.io/react-native/), [Cordova](https://cordova.apache.org/docs/en/latest/guide/overview/) with the [PhoneGap](https://github.com/phonegap/phonegap-plugin-push) plugin, and [Ionic Capacitor](https://capacitor.ionicframework.com/), can be used to display incoming push notifications from dotmailer.\n\nThis tutorial uses the Cordova framework with the PhoneGap plugin, but any framework that you choose to use must be able to get a [native device token](#section-sending-the-registration-id-to-the-javascript-sdk) (`registrationId`).\n\nIf your app is for use on iOS, you'll need to have your app ID's bundle ID. This ID must match the value of the `id` attribute in the `<widget>` element of your `config.xml` file.\n\nIf your app is for use on Android, you'll need to have your app's package name that you entered in your [push notification profile](doc:creating-a-push-notification-profile#section-entering-your-fcm-credentials-in-dotmailer).\n\n## Getting a registration ID, using the Cordova framework with the Adobe PhoneGap plugin\n\nPush notifications can be sent only if the registration ID (`registrationId`) is successfully passed to the JavaScript SDK.\n\nGetting the `registrationId` is an asynchronous task that is performed after the Cordova `deviceready` event.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import { Push } from 'ionic-native';\\n\\nplatform.ready().then(() => {\\n\\n    let push = Push.init({\\n        //For Android apps\\n        android: { senderID: 'Your_Project_ID' },\\n        //For iOS apps\\n        ios: {\\n        alert: \\\"true\\\",\\n        badge: true,\\n        sound: 'false'\\n        }\\n    });\\n\\n    push.on('registration', (data) => {\\n        console.log(\\\"got a registration ID\\\", data.registrationId);\\n        localStorage.setItem(\\\"registrationId\\\", data.registrationId);\\n    });\\n  \\n    push.on('notification', (data) => {\\n          console.log(\\\"got a push notification\\\", data);\\n      });\\n  \\n \\t\\tpush.on('error', (error) => {\\n     \\t\\t console.error('Error with Push plugin', error);\\n\\t\\t});\\n\\n}\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n## Displaying push notifications while the app is in the foreground\n\nPush notifications are automatically displayed only while the app is in the background. These notifications are sent to the system tray (Android) or the Notification Center (iOS) and launch your app when users tap them.\n\nIf you want to display the push notification message while the app is in the foreground, do one of the following:\n\n### Android\n\nFor Android devices, you can choose to have push notifications displayed automatically when the app is in the foreground, or you can choose to display the push notification message yourself.\n\n#### Displaying push notifications automatically\n\nWhen you choose to have push notifications displayed automatically when the app is in the foreground, the `on('notification')` callback is run only when the user taps the notification. Therefore, you can decide what happens when the user taps the notification\n\nThe push notification is passed as an argument to the `push.on('notification')` callback.\n\n* On the `init()` method of the push plugin, set the `android` object's `forceShow` property to `true` (it's set to `false` by default).\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \" let push = Push.init({\\n        //For Android apps\\n        android: { senderID: 'Your_Project_ID',\\n                 \\t forceShow: true\\n                 }\\n });\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n#### Displaying push notifications yourself\n\nIf you want contol over how push notification messages are displayed, you can implement your own way of displaying the push notification while the app is in the foreground.\n\nFor this option, the `on('notification')` callback is run immediately, and the push notification is passed as an argument to it.\n\n* On the `init()` method of the push plugin, make sure the `android` object's `forceShow` property is set to `false` (it's set to `false` by default).\n\n### For iOS\n\nYou need to implement your own way of displaying the push notification while the app is in the foreground. The push notification is passed as an argument to the `push.on('notification')` callback.\n\n## Sending the registration ID to the JavaScript SDK\n\nAfter you initialise the JavaScript SDK and you have a valid session, you need to send the registration ID to the JavaScript SDK.\n\nThe JavaScript SDK expects the registration ID to be passed to different methods, depending on the operating system. Therefore, use the [cordova device plugin](https://github.com/apache/cordova-plugin-device) to find out which platform the user is on.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import { Environment } from \\\"@comapi/sdk-js-foundation\\\";\\n\\n// Put this somewhere appropriate in your app (at the end of you initialisation/login flow)\\n\\nlet registrationId = localStorage.getItem(\\\"registrationId\\\");\\n// skip if registrationId hasn't been collected\\nif(registrationId){\\n\\n    // There are separate methods to call, depending on the operating system\\n    if (platform.is('ios')) {\\n\\n        // You need to create an APNs certificate in the Apple Developer Portal.\\n        // You must upload this cerificate to your push notification profile in dotmailer\\n        // This certificate can be of type 'development' or 'production', hence the Environment parameter\\n        sdk.device.setAPNSPushDetails(\\\"<Bundle Id>\\\", Environment.development, registrationId)\\n        .then(result => {\\n            console.log(\\\"setAPNSPushDetails() succeeded\\\", result);\\n        })\\n        .catch(error => {\\n            console.error(\\\"setAPNSPushDetails() failed\\\", error);\\n        });\\n\\n    }else if(platform.is('android')){\\n\\n        sdk.device.setFCMPushDetails(\\\"<Package Name>\\\", registrationId)\\n        .then(result => {\\n            console.log(\\\"setFCMPushDetails() succeeded\\\", result);\\n        })\\n        .catch(error => {\\n            console.error(\\\"setFCMPushDetails() failed\\\", error);\\n        });\\n\\n    }\\n}else{\\n    console.error(\\\"no registrationId ;-(\\\");\\n}\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nNow, when a user launches your app, the user's profile data is sent to dotmailer and (if that profile contains an email address that belongs to one of your contacts) that contact can now receive push notifications from dotmailer :tada: .\n[block:callout]\n{\n  \"type\": \"success\",\n  \"body\": \"[Send a push notification to your app](https://support.dotmailer.com/hc/en-gb/articles/360001827870) from the program builder in dotmailer.\",\n  \"title\": \"Next steps\"\n}\n[/block]","excerpt":"A tutorial for adding the JavaScript SDK code to your app to allow your app users to receive push notifications from your dotmailer account.","slug":"javascript-sdk","type":"basic","title":"Using the JavaScript SDK"}

Using the JavaScript SDK

A tutorial for adding the JavaScript SDK code to your app to allow your app users to receive push notifications from your dotmailer account.

[block:html] { "html": "<div id=\"userMap\">\n<div class=\"content\"><a href=\"https://developer.dotmailer.com/v2/docs/creating-a-push-notification-profile\"><div class=\"box box1\">Create a push notification profile in dotmailer</div></a></div>\n<div class=\"arrow\">→</div>\n<div class=\"content\"><a href=\"https://developer.dotmailer.com/v2/docs/creating-a-json-web-token\"><div class=\"box box2\">Create a class or function that generates a JSON Web Token</div></a></div>\n<div class=\"arrow\">→</div>\n<div class=\"content\"><a href=\"https://developer.dotmailer.com/v2/docs/setting-up-push-notifications#section-mobile-sdk-options\"><div class=\"box box3 active\">Use one of our mobile SDKs in your app</div></a></div>\n<div class=\"clearfix\"></div></div>\n\n<style>\n .box {\n padding: 10px;\n border: 2px solid #000;\n width: 120px;\n height: 120px;\n background-color: #EAEAEA;\n hyphens: auto;\n float: left;\n font-size: 12px;\n}\n\n.box:hover {\n background-color: #82bc42;\n}\n\n.box.active {\n background-color: #82bc42;\n}\n\n#userMap {\n overflow-x: auto;\n overflow-y: auto;\n padding: 20px;\n min-width: 770px;\n}\n\n#userMap a:hover {\n text-decoration: none;\n }\n\ndiv.arrow {\n max-width: 50px;\n margin-left: 15px;\n margin-right: 15px;\n font-size: 50px;\n}\n\n\n#userMap div.arrow, #userMap div.content {\n float: left;\n}\n\n.clearfix {\n clear: both;\n}\n\n\n#userMap div.arrow {\n position: relative;\n top: 45px;\n}\n\n.box1 {\n margin-left:0px;\n}\n\ndiv.box.box1 {\n margin-left: -20px;\n}\n\n</style>" } [/block] Unlike our native mobile SDKs, the JavaScript SDK is for cross-platform apps, therefore, after you've added the JavaScript SDK code to your app, you must [use a framework, such as Cordova (with PhoneGap) to get a native device token (registration ID)](#section-using-a-javascript-framework-to-get-a-native-device-token), and send it to dotmailer through the JavaScript SDK. [block:image] { "images": [ { "image": [ "https://files.readme.io/904f532-JavaScript-SDK-push.png", "JavaScript-SDK-push.png", 1588, 1123, "#88c34d" ], "caption": "JS framework sending the registration ID between dotmailer and your app" } ] } [/block] To set up push notifications for cross-platform apps, complete the following tasks: 1. [Install the JavaScript SDK](#section-installing-the-javascript-sdk) 2. [Configure the JavaScript SDK](#section-configuring-the-javascript-sdk) 3. [Initialise the JavaScript SDK](#section-initialising-the-javascript-sdk) 4. [Add an email address to the web app user's profile](#section-adding-an-email-address-to-the-web-app-user-s-profile) # Installing the JavaScript SDK The JavaScript SDK can be installed from either NPM or Bower, depending on your intended usage. If you use classical JavaScript in your project, and you just want to include a script that exposes some global objects on your page, use Bower. If you use ES6 modules in your project, for example in the Angular and Ionic 2 frameworks, use NPM. The examples for the NPM package are in TypeScript because the NPM version of the SDK is written in TypeScript. This tutorial explains how to use the SDK with JavaScript, but you can find a full sample of the TypeScript code in the ['JavaScript SDK sample code in TypeScript' section](#section-javascript-sdk-sample-code-in-typescript). [block:callout] { "type": "info", "body": "ES6 Promises are used in this SDK. Depending on which browsers you are targeting, you may need to use a polyfill.", "title": "ES6 Promises" } [/block] ## NPM 1. Install the JavaScript SDK [block:code] { "codes": [ { "code": "$ npm install @comapi/sdk-js-foundation --save", "language": "shell" } ] } [/block] 2. Import the `Foundation`, `ComapiConfig`, and `IAuthChallengeOptions ` modules from the SDK file [block:code] { "codes": [ { "code": "import { Foundation } from \"@comapi/sdk-js-foundation\"\nimport { ComapiConfig } from \"@comapi/sdk-js-foundation\"\nimport { IAuthChallengeOptions } from \"@comapi/sdk-js-foundation\"", "language": "javascript" } ] } [/block] ## Bower 1. Install the JavaScript SDK [block:code] { "codes": [ { "code": "$ bower install comapi-sdk-js-foundation", "language": "shell" } ] } [/block] 2. Import the script into your project [block:code] { "codes": [ { "code": "<script src=\"bower_components/comapi-sdk-js-foundation/dist/comapi-foundation.js\"></script>\n//Minified version\n<script src=\"bower_components/comapi-sdk-js-foundation/dist/comapi-foundation.min.js\"></script>", "language": "html" } ] } [/block] # Configuring the JavaScript SDK Before you can configure the JavaScript SDK, you need the following: * The value of the [API space ID field in dotmailer](doc:creating-a-push-notification-profile#section-finding-your-api-space-id) * A function that [creates a JWT](doc:creating-a-json-web-token) 1. Create a `ComapiConfig` object by calling the `Comapi.ComapiConfig()` constructor [block:code] { "codes": [ { "code": "var comapiConfig = new COMAPI.ComapiConfig();", "language": "javascript" } ] } [/block] 2. Pass your API Space ID to the `withApiSpaceId()` method [block:code] { "codes": [ { "code": "var comapiConfig = new COMAPI.ComapiConfig()\n .withApiSpace(appConfig.apiSpaceId);", "language": "javascript" } ] } [/block] 3. Pass the function that creates a JWT to the `withAuthChallenge()` method [block:code] { "codes": [ { "code": "var comapiConfig = new COMAPI.ComapiConfig()\n .withApiSpace(appConfig.apiSpaceId)\n .withAuthChallenge(challengeHandler);", "language": "javascript" } ] } [/block] # Initialising the JavaScript SDK After you've configured the SDK, pass the `comapiConfig` object to the `initialise()` method. This method creates a valid session by calling your JWT function and by using the JWT to create the user's profile ID (`profileId` string). When a session is stopped and started again, a new JWT token is created and used to create a new profile ID. A session is stopped in any of the following circumstances: * The user uninstalls the app, and then reinstalls it * The user clears all of the app's data Your app needs a valid session in order to add an email address to the user's profile. [block:code] { "codes": [ { "code": "COMAPI.Foundation.initialise(comapiConfig)\n .then(function (sdk) {\n console.log(\"Foundation interface created\", sdk);\n })\n .catch(function (error) {\n $log.error(\"paragonService: failed to initialise\", error);\n });", "language": "javascript" } ] } [/block] # Adding an email address to the web app user's profile Push notifications can be sent from dotmailer only to users who have a profile that contains an email address. If you want to update a profile, you need to query it first, make the appropriate changes to it, then update it. When you query a profile, that profile contains an `eTag` string, which is used to check that the profile hasn't already been updated before you update it. [block:callout] { "type": "warning", "title": "Ask users to enter their email address", "body": "You should ask users if they'd like to receive push notifications from you and prompt them to enter their email address." } [/block] [block:code] { "codes": [ { "code": "sdk.profile.getMyProfile()\n .then(function (profile) {\n \t\t\tprofile.email = \"exampleappuser1@gmail.com\";\n sdk.services.profile.updateMyProfile(profile);\n })\n .catch(function (error) {\n console.error(\"getMyProfile() failed\", error);\n });", "language": "javascript" } ] } [/block] At this point, push notifications can't be displayed on the device of your app users, unless you use a third-party framework to get a native device token and handle displaying the push notification. # JavaScript SDK sample code in TypeScript [block:code] { "codes": [ { "code": "// some app specific imports\nimport { AppSettings } from \"../settings\";\nimport { AuthService } from \"./auth\";\n\n// Comapi class / interface imports\nimport { Foundation, ComapiConfig, IAuthChallengeOptions } from \"@comapi/sdk-js-foundation\"\n\nexport class ComapiService {\n\n public sdk: Foundation;\n\n private challengeHandler(options: IAuthChallengeOptions, answerAuthenticationChallenge) {\n this._authService.getToken(options.nonce)\n .then((token) => {\n answerAuthenticationChallenge(token);\n });\n }\n\n constructor(private _authService: AuthService) { }\n\n /**\n * Public method to encapsulate up the initialisation of Comapi \n */\n public initialise(): Promise<Foundation> {\n\n return new Promise((resolve, reject) => {\n\n if (this._authService.isAuthenticated()) {\n\n let comapiConfig = new ComapiConfig()\n .withApiSpace(AppSettings.APP_SPACE_ID)\n // Note the this pointer binding so I can access this._authService in the authChallenge calllback\n .withAuthChallenge(this.challengeHandler.bind(this));\n\n Foundation.initialise(comapiConfig)\n .then((sdk) => {\n this.sdk = sdk;\n console.log(\"foundation interface created\");\n resolve(sdk);\n })\n .catch((error) => {\n console.error(\"initialise failed\", error);\n reject(error);\n });\n } else {\n reject(\"Not logged in\");\n }\n });\n }\n}", "language": "javascript", "name": "JavaScript SDK sample code in TypeScript" } ] } [/block] # Using a JavaScript framework to get a native device token Many frameworks, such as [React Native](https://facebook.github.io/react-native/), [Cordova](https://cordova.apache.org/docs/en/latest/guide/overview/) with the [PhoneGap](https://github.com/phonegap/phonegap-plugin-push) plugin, and [Ionic Capacitor](https://capacitor.ionicframework.com/), can be used to display incoming push notifications from dotmailer. This tutorial uses the Cordova framework with the PhoneGap plugin, but any framework that you choose to use must be able to get a [native device token](#section-sending-the-registration-id-to-the-javascript-sdk) (`registrationId`). If your app is for use on iOS, you'll need to have your app ID's bundle ID. This ID must match the value of the `id` attribute in the `<widget>` element of your `config.xml` file. If your app is for use on Android, you'll need to have your app's package name that you entered in your [push notification profile](doc:creating-a-push-notification-profile#section-entering-your-fcm-credentials-in-dotmailer). ## Getting a registration ID, using the Cordova framework with the Adobe PhoneGap plugin Push notifications can be sent only if the registration ID (`registrationId`) is successfully passed to the JavaScript SDK. Getting the `registrationId` is an asynchronous task that is performed after the Cordova `deviceready` event. [block:code] { "codes": [ { "code": "import { Push } from 'ionic-native';\n\nplatform.ready().then(() => {\n\n let push = Push.init({\n //For Android apps\n android: { senderID: 'Your_Project_ID' },\n //For iOS apps\n ios: {\n alert: \"true\",\n badge: true,\n sound: 'false'\n }\n });\n\n push.on('registration', (data) => {\n console.log(\"got a registration ID\", data.registrationId);\n localStorage.setItem(\"registrationId\", data.registrationId);\n });\n \n push.on('notification', (data) => {\n console.log(\"got a push notification\", data);\n });\n \n \t\tpush.on('error', (error) => {\n \t\t console.error('Error with Push plugin', error);\n\t\t});\n\n}", "language": "javascript" } ] } [/block] ## Displaying push notifications while the app is in the foreground Push notifications are automatically displayed only while the app is in the background. These notifications are sent to the system tray (Android) or the Notification Center (iOS) and launch your app when users tap them. If you want to display the push notification message while the app is in the foreground, do one of the following: ### Android For Android devices, you can choose to have push notifications displayed automatically when the app is in the foreground, or you can choose to display the push notification message yourself. #### Displaying push notifications automatically When you choose to have push notifications displayed automatically when the app is in the foreground, the `on('notification')` callback is run only when the user taps the notification. Therefore, you can decide what happens when the user taps the notification The push notification is passed as an argument to the `push.on('notification')` callback. * On the `init()` method of the push plugin, set the `android` object's `forceShow` property to `true` (it's set to `false` by default). [block:code] { "codes": [ { "code": " let push = Push.init({\n //For Android apps\n android: { senderID: 'Your_Project_ID',\n \t forceShow: true\n }\n });", "language": "javascript" } ] } [/block] #### Displaying push notifications yourself If you want contol over how push notification messages are displayed, you can implement your own way of displaying the push notification while the app is in the foreground. For this option, the `on('notification')` callback is run immediately, and the push notification is passed as an argument to it. * On the `init()` method of the push plugin, make sure the `android` object's `forceShow` property is set to `false` (it's set to `false` by default). ### For iOS You need to implement your own way of displaying the push notification while the app is in the foreground. The push notification is passed as an argument to the `push.on('notification')` callback. ## Sending the registration ID to the JavaScript SDK After you initialise the JavaScript SDK and you have a valid session, you need to send the registration ID to the JavaScript SDK. The JavaScript SDK expects the registration ID to be passed to different methods, depending on the operating system. Therefore, use the [cordova device plugin](https://github.com/apache/cordova-plugin-device) to find out which platform the user is on. [block:code] { "codes": [ { "code": "import { Environment } from \"@comapi/sdk-js-foundation\";\n\n// Put this somewhere appropriate in your app (at the end of you initialisation/login flow)\n\nlet registrationId = localStorage.getItem(\"registrationId\");\n// skip if registrationId hasn't been collected\nif(registrationId){\n\n // There are separate methods to call, depending on the operating system\n if (platform.is('ios')) {\n\n // You need to create an APNs certificate in the Apple Developer Portal.\n // You must upload this cerificate to your push notification profile in dotmailer\n // This certificate can be of type 'development' or 'production', hence the Environment parameter\n sdk.device.setAPNSPushDetails(\"<Bundle Id>\", Environment.development, registrationId)\n .then(result => {\n console.log(\"setAPNSPushDetails() succeeded\", result);\n })\n .catch(error => {\n console.error(\"setAPNSPushDetails() failed\", error);\n });\n\n }else if(platform.is('android')){\n\n sdk.device.setFCMPushDetails(\"<Package Name>\", registrationId)\n .then(result => {\n console.log(\"setFCMPushDetails() succeeded\", result);\n })\n .catch(error => {\n console.error(\"setFCMPushDetails() failed\", error);\n });\n\n }\n}else{\n console.error(\"no registrationId ;-(\");\n}", "language": "javascript" } ] } [/block] Now, when a user launches your app, the user's profile data is sent to dotmailer and (if that profile contains an email address that belongs to one of your contacts) that contact can now receive push notifications from dotmailer :tada: . [block:callout] { "type": "success", "body": "[Send a push notification to your app](https://support.dotmailer.com/hc/en-gb/articles/360001827870) from the program builder in dotmailer.", "title": "Next steps" } [/block]