mscdex / node-imap

An IMAP client module for node.js.
MIT License
2.15k stars 380 forks source link

How to fetch whole email thread (replies of replies) using messageId ? #796

Open mohaimin95 opened 4 years ago

mohaimin95 commented 4 years ago

I am trying to get the whole email thread from the inbox using message-id. I have tried using search criteria var searchCriteria = [['HEADER','IN-REPLY-TO',messageId]];, But I am getting replies only for the main thread. I want to get whole replies (replies of replies) from the inbox. I have tried var searchCriteria = [['OR', ['HEADER', 'IN-REPLY-TO', messageId], ['HEADER', 'REFERENCES', messageId]]];, but none of them helps. Please help me with the need. I have included the whole method below for your reference. Thanks in advance

const getInbox = (imapConfig, messageId) => {
return new Promise((resolve, reject) => {
    let config = {
        imap: {
            user: imapConfig.smtp_settings.auth.username,
            password: aesHelper.decrypt(imapConfig.smtp_settings.auth.password),
            host: imapConfig.smtp_settings.imap_host,
            port: imapConfig.smtp_settings.imap_port,
            tls: true,
            tlsOptions:{rejectUnauthorized:false},
            authTimeout: 3000
        }
    }
    Imap.connect(config).then(function (connection) {
        return connection.openBox('INBOX').then(function () {
            var searchCriteria = [['OR', ['HEADER', 'IN-REPLY-TO', messageId], ['HEADER', 'REFERENCES', messageId]]];
            var fetchOptions = {
                bodies: ['HEADER', 'TEXT', ''],
            };
            return connection.search(searchCriteria, fetchOptions).then(async function (messages) {
                let promises = messages.map(item => {
                    return new Promise((resolve, reject) => {
                        var all = _.find(item.parts, { "which": "" })
                        var id = item.attributes.uid;
                        var idHeader = "Imap-Id: " + id + "\r\n";
                        simpleParser(idHeader + all.body, (err, mail) => {
                            resolve(mail);
                        });
                    });
                });
                Promise.all(promises).then(data => {
                    connection.end();
                    let d = data.map(obj => {
                        return {
                            from: obj.from.value.map(obj => obj.address).join(','),
                            to: obj.to.value.map(obj => obj.address).join(','),
                            subject: obj.subject,
                            // body:obj.textAsHtml,
                            body: obj.html,
                            attachments: obj.attachments,
                            message_id: obj.messageId,
                            in_reply_to: obj.inReplyTo,
                            date: obj.date

                        };
                    });
                    resolve(d);
                })
            });
        });
    }).catch(err => {
        reject(err);
    });
});
}
govindaraja91 commented 4 years ago

@mohaimin95 i'm also facing the same issue here. did you find the solution?

MadhabaPatra commented 1 year ago

Hey @mohaimin95 , I found a approach , Get the thread id by message id. and now you can get all the messages by thread id. for ex : if you are using Gmail Folder name [Gmail]/All Mail Search criteria [["HEADER", "MESSAGE-ID", message_id]]

let thread_id = ""
var f = imap.fetch(results, {
    bodies: ""
});
f.on("message", async function(msg, seqno) {
    msg.on("attributes", function(attrs) {
        // Get the thread id from here
        thread_id = attrs["x-gm-thrid"]
    });
});

f.once("end", function() {
    imap.end();
});

Now you got thread id , you can now implement search by thread id Search criteria [["X-GM-THRID", thread_id]]