start rebuilding email notifications to be configured from user account (not active yet)
parent
fec699af9c
commit
3f23502214
|
|
@ -734,6 +734,7 @@
|
|||
"NotifyErrorText": "Sending Notification caused an Error",
|
||||
"Check the Channel ID": "Check the Channel ID",
|
||||
"Check the Recipient ID": "Check the Recipient ID",
|
||||
"AppNotEnabledText": "App Not Enabled, Enable it in your Account Settings.",
|
||||
"DiscordNotEnabledText": "Discord Bot Not Enabled, Enable it in your Account Settings.",
|
||||
"Account Settings": "Account Settings",
|
||||
"How to Record": "How to Record",
|
||||
|
|
@ -1254,6 +1255,7 @@
|
|||
"Close All Monitors": "Close All Monitors",
|
||||
"Daily Events": "Daily Events",
|
||||
"Send Notification": "Send Notification",
|
||||
"Send to": "Send to",
|
||||
"setMaxStorageAmountText": "You should set your Max Storage Amount in your Account Settings located on the left. Find the option under the Profile section. Default is 10 GB.",
|
||||
"Save Events": "Save Events",
|
||||
"Original Choice": "Original Choice",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,412 @@
|
|||
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: '<b style="font-size: 20pt;">'+s.factorAuth[r.ke][r.uid].key+'</b><br><br>'+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.');
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue