const EventEmitter = require('events');
const admin = require("firebase-admin");
let serviceAccount = require("./alarmiator-oauth.json");
const FCMToken = require('../../../models/fctmtokens');
/**
*
* @class Sending new alarms to mobile apps via Firebase Cloud Messaging
* ALARMiator Zusatzalarmierung
*
* @version: 1.0.1
* @author: Stefan Bauer 2020
*/
class alarmiatormobile extends EventEmitter {
/**
*
* @constructor
*/
constructor() {
super();
global.plgManager.logger.info('-------- PLUGIN ALARMIATOR MOBILE -----------');
//this.plgManager = global.plgManager;
this.registerForEvents();
this.serviceProcId = null;
this.loadConfig((success) => {
});
this.alarmiator = null;
this.alarmInfo = null;
this.fcmtokens = new FCMToken(global.plgManager.logger);
}
/**
* Registration of Events at the plugin manager (hook in to events provided by the plugin manager)
*/
registerForEvents() {
global.plgManager.logger.info('PLUGIN | ALARMIATORMOBILE | Registering events')
global.plgManager.on('event_pluginConfig_refreshed', (namespace) => {
if (namespace === 'alarmiatormobile') {
// plugins config has changed --> refresh
this.loadConfig((success) => {
if (success) {
global.plgManager.logger.info('PLUGIN | ALARMIATORMOBILE | successfully reloaded plugin configuration');
} else {
global.plgManager.logger.error('PLUGIN | ALARMIATORMOBILE | could not reload plugin config!');
}
});
}
})
global.plgManager.on('event_new_alarm', (alarmInfo) => {
this.alarmInfo = alarmInfo;
this.setupInstance();
this.sendMessage(alarmInfo);
})
global.plgManager.on('event_new_test_alarm', (baseDataId, pluginNamespace, alarmInfo) => {
if (pluginNamespace === "alarmiatormobile"){
global.plgManager.logger.info('PLUGIN | ALARMIATORMOBILE | EVENT event_new_test_alarm recieved -> processing now');
this.alarmInfo = alarmInfo;
this.setupInstance();
this.sendTestAlarm(baseDataId, alarmInfo);
}
})
}
/**
* Plugin-specific Getters and Setters
*
*/
set alarmiatorActive(alarmiatorActive) {
this._alarmiatorActive = alarmiatorActive;
}
get alarmiatorActive() {
return this._alarmiatorActive;
}
/**
* Plugin-specific implementation
*/
/**
* Creates ALARMiator mobile Instance
*
*/
setupInstance() {
global.plgManager.logger.debug('PLUGIN | ALARMIATORMOBILE | Setup ALARMiator Mobile Instance');
if (admin.apps.length == 0){
admin.initializeApp(
{credential: admin.credential.cert(serviceAccount)}
)
}
}
/**
* Check plugin config, whether sending alarms to ALARMiator is active
*
* @param {operation} alarmInfo
*/
sendMessage(alarmInfo) {
global.plgManager.logger.debug('PLUGIN | ALARMIATORMOBILE | Send Messages');
if (this.getConfigValue('alarmiatorActive') == "true"){
global.plgManager.logger.debug('PLUGIN | ALARMIATORMOBILE | Sending Alarmiator messages');
this.sendAlarmMessages(alarmInfo);
}
}
/**
* Sending ALARMiator messages to all users in ALARMiatorReceivers
* @param {operation} alarmInfo
*/
sendAlarmMessages(alarmInfo){
var fcmKeysString = this.getConfigValue('ALARMiatorReceivers');
var fcmKeys = [];
// check if string is empty
if (fcmKeysString){
fcmKeys = fcmKeysString.split(",").map(x => x.trim()).filter(x => x); // filter removes empty results
}
/* Get FCM token from tokenstore*/
this.fcmtokens.getAllFCMTokensForNamespace("alarmiatormobile", (fcmrows) => {
if (fcmrows != null){
fcmrows.forEach((entry)=> {
fcmKeys.push(entry.fcmToken);
})
}
var message = this.buildPayloadAlarm(alarmInfo, fcmKeys);
this.sendFCMMessage(message, fcmKeys);
});
}
/**
* Building alarm payload
* @param {number} baseDataId
* @param {operation} alarmInfo
*/
sendTestAlarm(baseDataId, alarmInfo){
var fcmKeys = [];
/* Get FCM token for User from tokenstore*/
this.fcmtokens.getAllFCMTokensForBasedataAndNamespace("alarmiatormobile", baseDataId, (fcmrows) => {
console.log(fcmrows);
if (fcmrows != null){
fcmrows.forEach((entry)=> {
fcmKeys.push(entry.fcmToken);
})
}
var message = this.buildPayloadAlarm(alarmInfo, fcmKeys);
this.sendFCMMessage(message, fcmKeys);
});
}
/**
* Building alarm payload
* @param {operation} alarmInfo
* @param {array} fcmKeys
*/
buildPayloadAlarm(alarmInfo, fcmKeys){
var sound = "default";
if (this.getConfigValue('iosSound') != undefined){
sound = this.getConfigValue('iosSound');
}
var organization = global.serverInstanceName;;
/* Customize notification here for Android + iOS */
var notification_title = "EINSATZ " + organization;
var notification_subtitle = alarmInfo.subject.value +" - "+ alarmInfo.keywordName.value;
var notification_body = "Einsatzort: " + alarmInfo.locationCalc.value;
/*************************************************/
var payload = {
/* NEW */
operation: alarmInfo.getReduced(),
/* Android Notification */
notification_payload: {
title: notification_subtitle, // switched with subtitle for android!!
subtitle : notification_title, // switched with title for android!!
body: notification_body,
}
};
// REFERENCE: https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#top_of_page
var message = {
data: {
payload: JSON.stringify(payload),
messageType: "alarm",
feedback: "true",
serverUUID: global.serverUUID,
content_available: "1"
},
android: {
priority: "high",
},
apns: {
payload: {
aps: {
alert : {
title : notification_title,
subtitle : notification_subtitle,
body: notification_body,
},
sound: {
critical: true,
name: sound,
volume: 1.0
},
"mutable-content": 1,
"content-available": 1
}
}
},
tokens: fcmKeys
};
global.plgManager.logger.debug('PLUGIN | ALARMIATORMOBILE | PAYLOAD for DEBUGGING -------START-----------');
global.plgManager.logger.debug(JSON.stringify(message));
global.plgManager.logger.debug('PLUGIN | ALARMIATORMOBILE | PAYLOAD for DEBUGGING -------END-------------');
return message;
}
/**
* Sending message to tokens
* @param {string} message
* @param {array} fcmKeys
*/
sendFCMMessage(message,fcmKeys){
admin.messaging().sendMulticast(message)
.then((response) => {
// Response is a message ID string.
const failedTokens = {};
const successTokens = [];
response.responses.forEach((resp, idx) => {
if (!resp.success) {
failedTokens[fcmKeys[idx]] = resp.error.message;
}
else {
successTokens.push(fcmKeys[idx]);
}
});
global.plgManager.logger.debug("PLUGIN | ALARMIATORMOBILE | List of successfully sent tokens: " + JSON.stringify(successTokens))
global.plgManager.logger.debug('PLUGIN | ALARMIATORMOBILE | List of tokens that caused failures: ' + JSON.stringify(failedTokens));
admin.app().delete();
})
.catch((error) => {
global.plgManager.logger.error('PLUGIN | ALARMIATORMOBILE | Error sending message: ',JSON.stringify(error));
admin.app().delete();
});
}
/**
* Loads configuration for KatSys Service
* TBD: Needs to be pulled from plugin config store
*/
loadConfig(callback) {
global.plgManager.loadConfigFromStore('alarmiatormobile', (configRows) => {
if (configRows !== null) {
this.config = configRows[0];
this.config = JSON.parse(this.config.configstore);
callback(true);
}
global.plgManager.logger.info('PLUGIN | ALARMIATORMOBILE | Configuration reloaded from core database');
})
}
/**
* returns config parameter for given fieldname
* @param {string} fieldname
*/
getConfigValue(fieldname) {
var retVal = null;
this.config.fields.forEach((field) => {
if (field.fieldname === fieldname) {
retVal = field.value;
}
});
return retVal;
}
}
module.exports = alarmiatormobile;