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: 'POST' } }); 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; const totalMessages = box.messages.total; if (totalMessages == 0) imap.end(); 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 = Date.vnNew(); 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 = Date.vnNew(); 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', reason: 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({ receiver: sendTo, subject: emailSubject, body: emailBody }); } };