salix/back/methods/imap-time-control/checkInbox.js

179 lines
6.1 KiB
JavaScript

const Imap = require('imap');
module.exports = Self => {
Self.remoteMethod('checkInbox', {
description: 'Check an email inbox and process it',
accessType: 'READ',
returns:
{
arg: 'body',
type: 'file',
root: true
},
http: {
path: `/checkInbox`,
verb: 'GET'
}
});
Self.checkInbox = async() => {
let imapConfig = await Self.app.models.WorkerTimeControlParams.findOne();
let imap = new Imap({
user: imapConfig.mailUser,
password: imapConfig.mailPass,
host: imapConfig.mailHost,
port: 993,
tls: true
});
let isEmailOk;
let uid;
let emailBody;
function openInbox(cb) {
imap.openBox('INBOX', true, cb);
}
imap.once('ready', function() {
openInbox(function(err, box) {
if (err) throw err;
let f = imap.seq.fetch('1:*', {
bodies: ['HEADER.FIELDS (FROM SUBJECT)', '1'],
struct: true
});
f.on('message', function(msg, seqno) {
isEmailOk = false;
msg.on('body', function(stream, info) {
let buffer = '';
let bufferCopy = '';
stream.on('data', function(chunk) {
buffer = chunk.toString('utf8');
if (info.which === '1' && bufferCopy.length == 0)
bufferCopy = buffer.replace(/\s/g, ' ');
});
stream.on('end', function() {
if (bufferCopy.length > 0) {
emailBody = bufferCopy.toUpperCase().trim();
const bodyPositionOK = emailBody.match(/\bOK\b/i);
if (bodyPositionOK != null && (bodyPositionOK.index == 0 || bodyPositionOK.index == 122))
isEmailOk = true;
else
isEmailOk = false;
}
});
msg.once('attributes', function(attrs) {
uid = attrs.uid;
});
msg.once('end', function() {
if (info.which === 'HEADER.FIELDS (FROM SUBJECT)') {
if (isEmailOk) {
imap.move(uid, 'exito', function(err) {
});
emailConfirm(buffer);
} else {
imap.move(uid, 'error', function(err) {
});
emailReply(buffer, emailBody);
}
}
});
});
});
f.once('end', function() {
imap.end();
});
});
});
imap.connect();
return 'Leer emails de gestion horaria';
};
async function emailConfirm(buffer) {
const now = new Date();
const from = JSON.stringify(Imap.parseHeader(buffer).from);
const subject = JSON.stringify(Imap.parseHeader(buffer).subject);
const timeControlDate = await getEmailDate(subject);
const week = timeControlDate[0];
const year = timeControlDate[1];
const user = await getUser(from);
let workerMail;
if (user.id != null) {
workerMail = await Self.app.models.WorkerTimeControlMail.findOne({
where: {
week: week,
year: year,
workerFk: user.id
}
});
}
if (workerMail != null) {
await workerMail.updateAttributes({
updated: now,
state: 'CONFIRMED'
});
}
}
async function emailReply(buffer, emailBody) {
const now = new Date();
const from = JSON.stringify(Imap.parseHeader(buffer).from);
const subject = JSON.stringify(Imap.parseHeader(buffer).subject);
const timeControlDate = await getEmailDate(subject);
const week = timeControlDate[0];
const year = timeControlDate[1];
const user = await getUser(from);
let workerMail;
if (user.id != null) {
workerMail = await Self.app.models.WorkerTimeControlMail.findOne({
where: {
week: week,
year: year,
workerFk: user.id
}
});
if (workerMail != null) {
await workerMail.updateAttributes({
updated: now,
state: 'REVISE',
emailResponse: emailBody
});
} else
await sendMail(user, subject, emailBody);
}
}
async function getUser(workerEmail) {
const userEmail = workerEmail.match(/(?<=<)(.*?)(?=>)/);
let [user] = await Self.rawSql(`SELECT u.id,u.name FROM account.user u
LEFT JOIN account.mailForward m on m.account = u.id
WHERE forwardTo =? OR
CONCAT(u.name,'@verdnatura.es') = ?`,
[userEmail[0], userEmail[0]]);
return user;
}
async function getEmailDate(subject) {
const date = subject.match(/\d+/g);
return date;
}
async function sendMail(user, subject, emailBody) {
const sendTo = 'rrhh@verdnatura.es';
const emailSubject = subject + ' ' + user.name;
await Self.app.models.Mail.create({
sender: sendTo,
subject: emailSubject,
body: emailBody
});
}
};