/*
* Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
import {
AWS,
AMA,
Pinpoint,
ClientDevice,
ConsoleLogger as Logger,
Constants
} from '../Common';
import Auth from '../Auth';
const logger = new Logger('AnalyticsClass');
const ama_logger = new Logger('AMA');
ama_logger.log = ama_logger.verbose;
/**
* Provide mobile analytics client functions
*/
class AnalyticsClass {
/**
* Initialize an Analytics class with configuration
* @param config - Configuration of the Analytics
*/
constructor(config) {
this.configure(config);
logger.debug('Analytics Config', this._config);
const client_info = ClientDevice.clientInfo();
if (client_info.platform) { this._config.platform = client_info.platform; }
this._buffer = [];
}
/**
* @param {Object} config - The configuration object
* @return {Object} - Current configuration
*/
configure(config) {
logger.debug('configure Analytics');
let conf = config? config.Analytics || config : {};
if (conf['aws_mobile_analytics_app_id']) {
conf = {
appId: conf['aws_mobile_analytics_app_id'],
platform: 'other',
region: conf['aws_project_region']
}
}
this._config = Object.assign({}, this._config, conf);
this._initClients();
return this._config;
}
/**
* Record session start
*/
startSession() {
if (this.amaClient) {
this.amaClient.startSession();
}
}
/**
* Record session stop
*/
stopSession() {
if (this.amaClient) {
this.amaClient.stopSession();
}
}
/**
* Restart Analytics client with credentials provided
* @param {Object} credentials - Cognito Credentials
*/
restart(credentials) {
try {
this.stopSession();
this._config.credentials = credentials;
this._initClients();
} catch(e) {
logger.error(e);
}
}
/**
* Record one analytic event and send it to Pinpoint
* @param {String} name - The name of the event
* @param {Object} [attributs] - Attributes of the event
* @param {Object} [metrics] - Event metrics
*/
record(name, attributes, metrics) {
logger.debug('record event ' + name);
if (!this.amaClient) {
logger.debug('amaClient not ready, put in buffer');
this._buffer.push({
name: name,
attribtues: attributes,
metrics: metrics
});
return;
}
this.amaClient.recordEvent(name, attributes, metrics);
}
/**
* Record one analytic event
* @param {Object} event - Event object
* @param {Object} [attributes] - Attributes of the event
* @param {Object} [metrics] - Event metrics
*/
recordMonetization(event, attributes, metrics) {
this.amaClient.recordMonetizationEvent(event, attributes, metrics);
}
/**
* @private
*/
_ensureCredentials() {
const conf = this._config;
if (conf.credentials) { return Promise.resolve(true); }
return Auth.currentCredentials()
.then(credentials => {
const cred = Auth.essentialCredentials(credentials);
logger.debug('set credentials for analytics', cred);
conf.credentials = cred;
if (!conf.clientId && conf.credentials) {
conf.clientId = conf.credentials.identityId;
}
return true;
})
.catch(err => {
logger.error(err)
return false;
});
}
/**
* @private
*/
_checkConfig() {
return !!this._config.appId;
}
/**
* @private
*/
async _initClients() {
if (!this._checkConfig()) { return false; }
const credentialsOK = await this._ensureCredentials();
if (!credentialsOK) { return false; }
this._initAMA();
this._initPinpoint();
this.startSession();
return true;
}
/**
* @private
*/
_initAMA() {
logger.debug('init AMA');
const { appId, platform, clientId, region, credentials } = this._config;
this.amaClient = new AMA.Manager({
appId: appId,
platform: platform,
clientId: clientId,
logger: ama_logger,
clientOptions: {
region: region,
credentials: credentials
}
});
if (this._buffer.length > 0) {
logger.debug('something in buffer, flush it');
const buffer = this._buffer;
this._buffer = [];
buffer.forEach(event => {
this.amaClient.recordEvent(event.name, event.attributes, event.metrics);
});
}
}
/**
* @private
*/
_initPinpoint() {
logger.debug('init Pinpoint');
const { region, appId, clientId, credentials } = this._config;
this.pinpointClient = new Pinpoint({
region: region,
credentials: credentials
});
const request = this._endpointRequest();
const update_params = {
ApplicationId: appId,
EndpointId: clientId,
EndpointRequest: request
};
logger.debug(update_params);
this.pinpointClient.updateEndpoint(update_params, function(err, data) {
if (err) {
logger.debug('Pinpoint ERROR', err);
} else {
logger.debug('Pinpoint SUCCESS', data);
}
});
}
/**
* @private
*/
_endpointRequest() {
const client_info = ClientDevice.clientInfo();
const credentials = this._config.credentials;
const user_id = credentials.authenticated? credentials.identityId : null;
logger.debug('demographic user id: ' + user_id);
return {
Demographic: {
AppVersion: this._config.appVersion || client_info.appVersion,
Make: client_info.make,
Model: client_info.model,
ModelVersion: client_info.version,
Platform: client_info.platform
},
User: { UserId: user_id }
};
}
}
export default AnalyticsClass;