var fs = require('fs'); const { template, checkEmail, } = require("./emailUtils.js") module.exports = function (s, config, lang, getSnapshot) { const { getEventBasedRecordingUponCompletion } = require('../events/utils.js')(s, config, lang); const nodeMailer = require('nodemailer'); try { const sendMessage = async function (sendBody, files, groupKey) { const transporter = s.group[groupKey].emailClient; if (!transporter) { s.userLog( { ke: groupKey, mid: '$USER' }, { type: lang.NotifyErrorText, msg: { msg: lang.AppNotEnabledText, app: lang.Email }, } ); return; } try { const appOptions = s.group[groupKey].emailClientOptions.transport; const sendTo = appOptions.sendTo; const sendData = { from: `"shinobi.video" <${transportOptions.auth.user}>`, to: sendTo, subject: sendBody.subject, html: sendBody.html, }; if (files.length > 0) { // sadly pushover allows only ONE single attachment msg.file = { name: files[0].name, data: files[0].attachment, }; } transporter.sendMail(sendData, function (err, result) { if (err) { throw err; } s.userLog(result); s.debugLog(result); }); } catch (err) { s.userLog( { ke: groupKey, mid: '$USER' }, { type: lang.NotifyErrorText, msg: err } ); } }; const loadAppForUser = function (user) { const userDetails = s.parseJSON(user.details); const optionsHost = userDetails.emailClient_host const optionsUser = userDetails.emailClient_user const optionsSendTo = userDetails.emailClient_sendTo || '' if ( !s.group[user.ke].emailClient && userDetails.emailClient === '1' && optionsHost && optionsUser && optionsSendTo ){ const optionsPass = userDetails.emailClient_pass || '' const optionsSecure = userDetails.emailClient_secure === '1' ? true : false const optionsPort = isNaN(userDetails.emailClient_port) ? (optionsSecure ? 465 : 587) : parseInt(userDetails.emailClient_port) const clientOptions = { host: optionsHost, port: optionsPort, secure: optionsSecure, auth: { user: optionsUser, pass: optionsPass } } s.group[user.ke].emailClientOptions = { transport: clientOptions, sendTo: optionsSendTo, } s.group[user.ke].emailClient = nodeMailer.createTransport(clientOptions) } }; const unloadAppForUser = function (user) { if ( s.group[user.ke].emailClient && s.group[user.ke].emailClient.close ) { s.group[user.ke].emailClient.close(); } delete s.group[user.ke].emailClient; delete s.group[user.ke].emailClientOptions; }; const onTwoFactorAuthCodeNotificationForApp = function (r) { // r = user if (r.details.factor_emailClient === '1') { sendMessage({ subject: r.lang['2-Factor Authentication'], html: template.createFramework({ title: r.lang['2-Factor Authentication'], subtitle: r.lang['Enter this code to proceed'], body: ''+s.factorAuth[r.ke][r.uid].key+'

'+r.lang.FactorAuthText1, }), },[],r.ke); } }; const onEventTriggerForApp = async (d, filter) => { const monitorConfig = s.group[d.ke].rawMonitorConfigurations[d.id]; // d = event object if ( s.group[d.ke].emailClient && (filter.emailClient || monitorConfig.details.notify_emailClient === '1') && !s.group[d.ke].activeMonitors[d.id].detector_emailClient ) { var detector_emailClient_timeout; if ( !monitorConfig.details.detector_emailClient_timeout || monitorConfig.details.detector_emailClient_timeout === '' ) { detector_emailClient_timeout = 1000 * 60 * 10; } else { detector_emailClient_timeout = parseFloat( monitorConfig.details.detector_emailClient_timeout ) * 1000 * 60; } s.group[d.ke].activeMonitors[d.id].detector_emailClient = setTimeout(function () { s.group[d.ke].activeMonitors[d.id].detector_emailClient = null; }, detector_emailClient_timeout); // lock passed const sendMail = function(files){ const infoRows = [] Object.keys(d.details).forEach(function(key){ var value = d.details[key] var text = value if(value instanceof Object){ text = JSON.stringify(value,null,3) } infoRows.push(template.createRow({ title: key, text: text })) }) sendMessage({ subject: lang.Event+' - '+d.screenshotName, html: template.createFramework({ title: lang.EventText1 + ' ' + d.currentTimestamp, subtitle: lang.Event, body: infoRows.join(''), }), },files || [],r.ke) } if(monitorConfig.details.detector_mail_send_video === '1'){ let videoPath = null let videoName = null const eventBasedRecording = await getEventBasedRecordingUponCompletion({ ke: d.ke, mid: d.mid }) if(eventBasedRecording.filePath){ videoPath = eventBasedRecording.filePath videoName = eventBasedRecording.filename }else{ const siftedVideoFileFromRam = await s.mergeDetectorBufferChunks(d) videoPath = siftedVideoFileFromRam.filePath videoName = siftedVideoFileFromRam.filename } if(videoPath){ fs.readFile(mergedFilepath,function(err,buffer){ if(buffer){ sendMail([ { filename: videoName, content: buffer } ]) } }) } } await getSnapshot(d,monitorConfig) sendMail([ { filename: d.screenshotName + '.jpg', content: d.screenshotBuffer } ]) } }; const onEventTriggerBeforeFilterForApp = function (d, filter) { filter.emailClient = false; }; const onDetectorNoTriggerTimeoutForApp = function (e) { //e = monitor object var currentTime = new Date(); if (e.details.detector_notrigger_emailClient === '1') { var html = '*' + lang.NoMotionEmailText2 + ' ' + (e.details.detector_notrigger_timeout || 10) + ' ' + lang.minutes + '.*\n'; html += '**' + lang['Monitor Name'] + '** : ' + e.name + '\n'; html += '**' + lang['Monitor ID'] + '** : ' + e.id + '\n'; html += currentTime; sendMessage({ subject: lang['"No Motion" Detector'], html: template.createFramework({ title: lang['"No Motion" Detector'], subtitle: 'Shinobi Event', body: html, }), },[],e.ke); } }; const onMonitorUnexpectedExitForApp = (monitorConfig) => { if ( monitorConfig.details.notify_emailClient === '1' && monitorConfig.details.notify_onUnexpectedExit === '1' ){ const ffmpegCommand = s.group[monitorConfig.ke].activeMonitors[monitorConfig.mid].ffmpeg const subject = lang['Process Unexpected Exit'] + ' : ' + monitorConfig.name const currentTime = new Date(); sendMessage({ subject: subject, html: template.createFramework({ title: subject, subtitle: lang['Process Crashed for Monitor'], body: ffmpegCommand, footerText: currentTime }), },[],monitorConfig.ke); } }; s.loadGroupAppExtender(loadAppForUser); s.unloadGroupAppExtender(unloadAppForUser); s.onTwoFactorAuthCodeNotification(onTwoFactorAuthCodeNotificationForApp); s.onEventTrigger(onEventTriggerForApp); s.onEventTriggerBeforeFilter(onEventTriggerBeforeFilterForApp); s.onDetectorNoTriggerTimeout(onDetectorNoTriggerTimeoutForApp); s.onMonitorUnexpectedExit(onMonitorUnexpectedExitForApp); s.definitions['Monitor Settings'].blocks[ 'Notifications' ].info[0].info.push({ name: 'detail=notify_emailClient', field: lang.Email, description: '', default: '0', example: '', selector: 'h_det_emailClient', fieldType: 'select', possible: [ { name: lang.No, value: '0', }, { name: lang.Yes, value: '1', }, ], }); s.definitions['Monitor Settings'].blocks['Notifications'].info.push( { evaluation: "$user.details.use_emailClient !== '0'", isFormGroupGroup: true, name: lang.Email, color: 'blue', 'section-class': 'h_det_emailClient_input h_det_emailClient_1', info: [ { name: 'detail=detector_emailClient_timeout', field: `${lang['Allow Next Alert']} (${lang['on Event']})`, default: '10', }, ], } ); s.definitions['Account Settings'].blocks[ '2-Factor Authentication' ].info.push({ name: 'detail=factor_emailClient', field: lang.Email, default: '1', example: '', fieldType: 'select', possible: [ { name: lang.No, value: '0', }, { name: lang.Yes, value: '1', }, ], }); s.definitions['Account Settings'].blocks['Email'] = { evaluation: "$user.details.use_emailClient !== '0'", field: lang.Email, color: 'blue', info: [ { name: 'detail=emailClient', selector: 'u_emailClient', field: lang.Enabled, default: '0', example: '', fieldType: 'select', possible: [ { name: lang.No, value: '0', }, { name: lang.Yes, value: '1', }, ], }, { hidden: true, field: lang.Host, name: 'detail=emailClient_host', example: 'smtp.gmail.com', 'form-group-class': 'u_emailClient_input u_emailClient_1', }, { hidden: true, field: lang.Port, name: 'detail=emailClient_port', example: '587', 'form-group-class': 'u_emailClient_input u_emailClient_1', }, { name: 'detail=emailClient_secure', field: lang.Secure, default: '0', example: '', fieldType: 'select', possible: [ { name: lang.No, value: '0', }, { name: lang.Yes, value: '1', }, ], }, { hidden: true, field: lang.Email, name: 'detail=emailClient_user', example: 'test@gmail.com', 'form-group-class': 'u_emailClient_input u_emailClient_1', }, { hidden: true, field: lang.Password, name: 'detail=emailClient_pass', 'form-group-class': 'u_emailClient_input u_emailClient_1', }, { hidden: true, field: lang['Send to'], name: 'detail=emailClient_sendTo', 'form-group-class': 'u_emailClient_input u_emailClient_1', }, ], }; s.definitions["Event Filters"].blocks["Action for Selected"].info.push({ "name": "actions=emailClient", "field": lang['Email'], "fieldType": "select", "form-group-class": "actions-row", "default": "", "example": "1", "possible": [ { "name": lang['Original Choice'], "value": "", "selected": true }, { "name": lang.Yes, "value": "1", } ] }) } catch (err) { console.log(err); console.log('Could not engage Email notifications.'); } };