const Imap = require("imap");
var MailParser = require("mailparser").MailParser;
let imap = null
const createImapConnection = (username, password) => {
return new Imap({
user: username,
password: password,
host: "outlook.office365.com",
port: 993,
tls: true,
});
};
const connectImap = () => {
return new Promise((resolve, reject) => {
imap.once("ready", () => {
resolve(imap);
});
imap.once("error", (err) => {
reject(err);
});
imap.connect();
});
};
const openInbox = () => {
return new Promise((resolve, reject) => {
imap.openBox("INBOX", true, (err) => {
if (err) {
reject(err);
} else {
resolve(imap);
}
});
});
};
const waitForNewMail = (cb) => {
imap.once("mail", () => {
cb();
});
};
const newEmailHandler = () => {
return new Promise((resolve) => {
imap.search(["UNSEEN"], (_, results) => {
const f = imap.fetch(results.at(-1), {
bodies: "",
});
f.on("message", (msg) => {
msg.on("body", (stream) => {
var parser = new MailParser();
stream.pipe(parser);
parser.on("data", (data) => {
resolve(data)
});
});
});
});
});
};
let emits = []
exports.getEmail = async ({ username, password }) => {
return {
on: (emitName, emit) => {
const id = Date.now() + Math.random()
emits.push({ emitName, emit, id })
},
off: (id) => {
emits = emits.filter(emit => emit.id !== id)
imap.removeAllListeners()
},
connect: async () => {
try {
imap = createImapConnection(username, password);
await connectImap();
await openInbox();
} catch (error) {
imap.removeAllListeners()
throw error
}
waitForNewMail(async () => {
const data = await newEmailHandler(imap);
emits.forEach(emit => {
if (emit.emitName === 'ready') {
emit.emit(data, emit.id)
}
})
imap.closeBox(() => {
imap.end();
});
});
},
disconnect: () => {
imap.closeBox(() => {
imap.end();
imap.removeAllListeners()
});
}
}
};