I've been trying to display emails properly, but failing to do so. I've just send email to myself and it looks like this when i open it in hotmail But when i open it in my app using node-imap, from 'Sent box' it looks like this (notice those '=' signs, and some other weird shit..):
and this is same message output in console (for some reason i get '=' on end of every row, and '3D' after each '='):
Now... SAME message, same method, just opened from inbox: http://prntscr.com/jbqtyw
just a plain text.. in console too: http://prntscr.com/jbquba
I know its messy question and hard to understand, but couldnt make it easier.. And here is the code of get() which is fetching emails:
get(id, params) {
this.emailUsername = params.user.businessEmail;
this.emailPassword = params.user.businessEmailPassword;
this.host = params.user.serverIMAP;
this.port = params.user.portIMAP;
this.tls = params.user.serverSMTP;
this.smtpPort = params.user.portSMTP;
let currBox = params.query.box;
let userEmail = this.emailUsername;
return new Promise((resolve, reject) => {
var imap = new Imap({
user: this.emailUsername,
password: this.emailPassword,
host: this.host,
port: this.port,
tls: this.tls,
tlsOptions: {
rejectUnauthorized: false
}
});
var response = {};
function toUpper(thing) { return thing && thing.toUpperCase ? thing.toUpperCase() : thing; }
function findAttachmentParts(struct, attachments) {
attachments = attachments || []
struct.forEach((i) => {
if (Array.isArray(i)) findAttachmentParts(i, attachments)
else if (i.disposition && ['INLINE', 'ATTACHMENT'].indexOf(toUpper(i.disposition.type)) > -1) {
attachments.push(i)
}
})
return attachments
}
function checkEmail(email) {
return email.split('@')[1].split('.')[0];
}
function findTextPart(struct) {
for (var i = 0, len = struct.length, r; i < len; ++i) {
if (Array.isArray(struct[i])) {
if (r = findTextPart(struct[i]))
return r;
} else if (struct[i].type === 'text'
&& struct[i].subtype === 'html') {
return [struct[i].partID, struct[i].type + '/' + struct[i].subtype];
} else if(struct[i].type === 'text'&& struct[i].subtype === 'plain') {
return [struct[i].partID, struct[i].type + '/' + struct[i].subtype];
}
}
}
function getMsgByUID(uid, cb, partID) {
var f = imap.seq.fetch(uid,
(partID
? {
bodies: [
'HEADER.FIELDS (TO FROM SUBJECT DATE CC BCC)',
partID[0]
]
}
: { struct: true })),
hadErr = false;
if (partID)
var msg = { header: undefined, body: '', attrs: undefined };
f.on('error', function (err) {
hadErr = true;
cb(err);
});
if (!partID) {
f.on('message', function (m) {
m.on('attributes', function (attrs) {
partID = findTextPart(attrs.struct);
const attachments = findAttachmentParts(attrs.struct);
attachments.forEach((attachment) => {
const filename = attachment.params.name // need decode disposition.params['filename*'] !!!
const encoding = toUpper(attachment.encoding)
const f = imap.fetch(attrs.uid, { bodies: [attachment.partID] })
})
});
});
f.on('end', function () {
if (hadErr)
return;
if (partID)
getMsgByUID(uid, cb, partID);
else
cb(new Error('No text part found'));
});
} else {
f.on('message', function (m) {
m.on('body', function (stream, info) {
var b = '';
stream.on('data', function (d) {
b += d;
});
stream.on('end', function () {
if (/^header/i.test(info.which))
msg.header = Imap.parseHeader(b);
else
msg.body = b;
console.log(b);
});
});
m.on('attributes', function (attrs) {
msg.attrs = attrs;
msg.contentType = partID[1];
});
});
f.on('end', function () {
if (hadErr)
return;
cb(undefined, msg);
});
}
}
imap.once('ready', function () {
imap.openBox(currBox, true, function (err, box) {
if (err) throw err;
getMsgByUID(id, function (err, msg) {
if (err) throw err;
response = msg;
imap.end();
});
});
});
imap.once('error', function (err) {
reject(err);
});
imap.once('end', function () {
resolve(response);
});
imap.connect();
})
}
and on the frontend, just displaying it as inner HTML:
<div class="content" [innerHtml]="bypassSecurity(email.body)">
</div>
So to sum it up.. same method/call getting different output from stream (once plain text, once html text.. also in both cases some weird shit added to messages, like '=' or '3D' on seems like random places)? is this the right way to read emails?
This is Quoted Printable encoding.
It looks like you need to possibly undo the Content Transfer Encoding for the sections, which can commonly be Base64 or Quoted Printable.