node.jsimapmultipartmime-mail

MIME email multipart parser


I'm looking for a node.js module that can parse my IMAP request - FETCH 1 BODY[TEXT]. I need multipart parser, because I have messages with few levels in hierarchy.

Example of message:

--94eb2c032ec81bf420053483f579
Content-Type: multipart/alternative; boundary=94eb2c032ec81bf411053483f577

--94eb2c032ec81bf411053483f577
Content-Type: text/plain; charset=UTF-8

test

--94eb2c032ec81bf411053483f577
Content-Type: text/html; charset=UTF-8

<div dir="ltr">test</div>

--94eb2c032ec81bf411053483f577--
--94eb2c032ec81bf420053483f579
Content-Type: image/x-icon; name="favicon.ico"
Content-Disposition: attachment; filename="favicon.ico"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_ip2cdokt0

AAABAAEAEA8AAAEAIA... THIS IS ATTACHMENT ...A8AcAAPw/AAA=
--94eb2c032ec81bf420053483f579--)

Solution

  • With mailparser we can parse source of e-mail messages into a structured object. It's supports multipart levels - so html/text/attachments will stay in the object and we can find them in attributes.

    For example:

    const simpleParser = require('mailparser').simpleParser
    
    
    var f = imap.fetch(results, { bodies: '' })
    
    f.on('message', function (msg, seqno) {
      msg.on('body', async function (stream) {
        const parsed = await simpleParser(stream)
    
        if (parsed) {
          const fromEmail = parsed.from?.value?.[0]?.address
    
          if (fromEmail) {
            if (parsed.subject?.length > 0) {
              console.log('parsed.subject :>> ', parsed.subject)
            }
    
            const lines = parsed.text?.split('\n')
            lines.forEach(function (line, indx) {
              if (line?.length > 0) {
                console.log(`parsed.text[${indx}] :>> `, line)
              }
            })
          } else {
            console.warn('No from email found in', parsed)
          }
        }
      })
    
      msg.once('end', function () {
        console.log(prefix + 'Finished')
      })
    })