AppLink sample code: AppLinkHelper.js


var AppLinkHelper = {
    _log: function(level, message) {
        if (level === 'ERROR') {
            if (this.config.logging === 'ERROR' || this.config.logging === 'DEBUG')
                console.log('%cAppLinkHelper ERROR: ' + message, 'background: #222; color: red');
        }
        else if (level === 'DEBUG') {
            if (this.config.logging === 'DEBUG')
                console.log('%cAppLinkHelper DEBUG: ' + message, 'color: blue');
        }
    },
    config: {
        sessionName: 'AppLinkSession',
        logging: 'DEBUG',              // 'DEBUG'
        timeout: 5000                  // connection retry timeout
    },
    session: {
        onConnect: null,
        onDisconnect: null,
        onTextMessageReceived: null,
        onReachableChanged: null
    },
    _reconnectTimer: null,
    _clearReconnectTimer: function() {
        clearTimeout(this._reconnectTimer);
        this._reconnectTimer = null;
    },
    isConnected: false,
    init : function (sessionName) {
        this._log('DEBUG', 'init');

        var self = this;

        // make sure dapi.js is loaded
        if (!window.dapi) {
            this.log.error('init: window.dapi not found');
            return;
        }

        this.config.sessionName = sessionName;

        this._dapi = window.dapi;

        // ensure appLinkSession is initialized
        if (!this._dapi.appLinkSession) {
            this._log('ERROR', 'init: Could not connect to DCP');
            return;
        }

        // setup appLinkSession callbacks (4)
        this._dapi.appLinkSession.onConnect = function (success) {
            if (!success) {
                self._log('DEBUG','onConnect: failed 😓');
                self.isConnected = false;
                self._clearReconnectTimer();
                self._reconnectTimer = setTimeout(function(){
                    if (self && self._dapi) {
                        self._log('DEBUG', 'onConnect: attempting to reconnect...');
                        self.connect();
                    }
                }, self.config.timeout);
            } else {
                self._log('DEBUG', 'onConnect: success 😀');
                self._clearReconnectTimer();
                self.isConnected = true;
            }

            if (self.session.onConnect)
                self.session.onConnect(success);
        }

        this._dapi.appLinkSession.onDisconnect = function () {
            self._log('DEBUG', 'onDisconnect');
            self.isConnected = false;
            if (self._dapi.configuration.parameter('Phone.App.Status').value == "SUCCESS") {
                self._log('DEBUG', 'onDisconnect: try connect');
                self.connect();
            }

            if (self.session.onDisconnect)
                self.session.onDisconnect();
        }

        this._dapi.appLinkSession.onTextMessageReceived = function (message) {
            self._log('DEBUG', 'onTextMessageReceived');

            if (self.session.onTextMessageReceived)
                self.session.onTextMessageReceived(message);
        }

        this._dapi.appLinkSession.onReachableChanged = function () {
            self._log('DEBUG', 'onReachableChanged');

            if (self.session.onReachableChanged)
                self.session.onReachableChanged();
        }

        // setup event callbacks
        this._dapi.configuration.parameter('Phone.App.Status').valueChanged.connect(function (message) {
            self._log('DEBUG', 'Phone.App.Status changed to ' + self._dapi.configuration.parameter('Phone.App.Status').value);
            // attempt connection when Phone.App.Status changes from * to 'SUCCESS'
            if (self._dapi.configuration.parameter('Phone.App.Status').value == "SUCCESS")
                self.connect();
        });

        // attempt connection
        this.connect();
    },
    // connect AppLink to DCP
    connect : function () {
        this._clearReconnectTimer();
        if(this.isConnected) {
            this._log('DEBUG', 'connect: Already connected to ' + this.config.sessionName);
            return;
        }
        this._log('DEBUG', 'connect: connecting to ' + this.config.sessionName);
        this._dapi.appLinkSession.connect(this.config.sessionName);
    },
    // send message to DCP via AppLink
    sendTextMessage : function (msg) {
        if (!this._dapi || !this._dapi.appLinkSession) {
            this._log('ERROR', 'sendTextMessage: dapi not loaded');
            return false;
        }
        if (!this.isConnected && !this._dapi.appLinkSession.reachable ) {
            this._log('ERROR', 'sendTextMessage: AppLink not reachable');
            return false;
        }
        try {
            // this must be a string message
            this._dapi.appLinkSession.sendTextMessage(msg);
            this._log('DEBUG', 'sendTextMessage: message: ' + msg);
            return true;
        } catch (e) {
            this._log('ERROR', 'sendTextMessage: ' + e);
            return false;
        }
    },
    // AppLinkHelper teardown/reset
    cleanup : function () {
        if (!this._dapi || !this._dapi.appLinkSession)
            return;

        this._log('DEBUG', 'cleanup: disconnecting from ' + this.config.sessionName);

        this._dapi.appLinkSession.disconnect(this.config.sessionName);

        this.session.onConnect = null;
        this._dapi.appLinkSession.onConnect = null;
        this.session.onDisconnect = null;
        this._dapi.appLinkSession.onDisconnect = null;
        this.session.onTextMessageReceived = null;
        this._dapi.appLinkSession.onTextMessageReceived = null;
        this.session.onReachableChanged = null;
        this._dapi.appLinkSession.onReachableChanged = null;

        this.config.sessionName = 'AppLinkSession';

        this._log('DEBUG', 'cleanup: done.');
    }
}