@hyperbytes/wappler-imap-manager
Version:
IMAP eMail Management for Wappler
129 lines (105 loc) • 5.66 kB
JavaScript
const Imap = require('imap');
const fs = require('fs');
const { simpleParser } = require('mailparser');
const path = require('path');
const { toSystemPath } = require("../../../lib/core/path");
const mime = require('mime-types');
const mimeDb = require('mime-db');
exports.imapgetattachments = async function (options, name) {
const IMAP_USER = process.env.IMAP_USER;
const IMAP_PASSWORD = process.env.IMAP_PASSWORD;
const IMAP_HOST = process.env.IMAP_HOST;
const IMAP_PORT = process.env.IMAP_PORT;
const uid = this.parseRequired(options.uid, '*', 'No UID Specified');
const uidvalidity = this.parseRequired(options.uidvalidity, '*', "No message UIDValidity specified");
const mailbox = this.parseRequired(options.mailbox, '*', "No mailbox specified");
let sentPath = this.parseRequired(options.path, '*', 'No path Specified');
const returnPath = sentPath.split('/').slice(2).join('/');
//savePath = toSystemPath(sentPath);
savePath = sentPath;
// Ensure the directory exists or create it
if (!fs.existsSync(savePath)) {
fs.mkdirSync(savePath, { recursive: true });
}
return new Promise((resolve) => {
const imap = new Imap({
user: IMAP_USER,
password: IMAP_PASSWORD,
host: IMAP_HOST,
port: IMAP_PORT,
tls: true
});
imap.once('ready', () => {
imap.openBox(mailbox, false, (err, box) => {
if (err) {
imap.end();
return resolve({ savedFiles: [], message: "Mailbox Auth Failure", url: '', path: '', status: 401 });
}
// Validate UIDVALIDITY before proceeding
if (Number(box.uidvalidity) !== Number(uidvalidity)) {
imap.end();
return resolve({ savedFiles: [], message: "UID Validity mismatch", url: '', path: '', status: 401 });
}
const fetch = imap.fetch(uid, { bodies: '', struct: true });
fetch.on('message', (msg) => {
let buffer = '';
msg.on('body', (stream) => {
stream.on('data', (chunk) => buffer += chunk.toString('utf8'));
stream.on('end', async () => {
try {
const parsed = await simpleParser(buffer);
if (!parsed.attachments || parsed.attachments.length === 0) {
imap.end();
return resolve({ savedFiles: [], message: "No Attachments Found", url: returnPath, path: sentPath, status: 200 });
}
const savedFiles = [];
parsed.attachments.forEach(att => {
const filePath = path.join(savePath, att.filename);
fs.writeFileSync(filePath, att.content);
savedFiles.push(att.filename);
console.log(`Saved attachment: ${filePath}`);
});
const savedFilesExt = [];
parsed.attachments.forEach(att => {
const filePath = path.join(savePath, att.filename);
// Replace backslashes with forward slashes
let correctedPath = filePath.replace(/\\/g, "/");
// Remove the "public" prefix
correctedPathURL = correctedPath.replace(/^\/?public\//, "/");
fs.writeFileSync(filePath, att.content);
let mimetype = mime.lookup(att.filename)
const fs2 = require('fs');
//const filePath = 'example.txt';
const stats = fs2.statSync(filePath);
console.log(`File size: ${stats.size} bytes`);
savedFilesExt.push({
name: att.filename,
path: correctedPath,
url: correctedPathURL,
type: mimetype,
size: stats.size
});
console.log(`Saved attachment Extended: ${filePath}`);
});
// Output JSON
console.log(JSON.stringify(savedFilesExt, null, 2));
imap.end();
resolve({ status: 200, url: returnPath, path: sentPath, uploads: savedFilesExt });
} catch (parseError) {
imap.end();
resolve({ savedFiles: [], message: "Parse Failure", url: '', path: '', status: 400 });
}
});
});
});
fetch.once('end', () => {
imap.end();
});
});
});
imap.once('error', () => {
resolve({ savedFiles: [], message: "Error Opening Mailbox", url: "", path: "", status: 401 });
});
imap.connect();
});
};