npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@nodemailer/mailparser2

v1.0.3

Published

Parse emails

Downloads

5,163

Readme

MailParser2

Advanced email parser for Node.js. Everything is handled as a stream which should make it able to parse even very large messages (100MB+) with relatively low overhead. This project is somewhat similar to Mailparser even though it's a complete rewrite.

Mailparser2 is part of Nodemailer PRO bundle. You can use it on its own under restrictive CC-BY-NC-SA-4.0 license. For more permissive commercial license see the Nodemailer PRO offering.

The module exposes two separate modes, a lower level MailParser2 class and simpleParser function. The latter is simpler to use (hence the name) but is less resource efficient as it buffers attachment contents in memory.

Install

npm install @nodemailer/mailparser2

simpleParser

simpleParser is the easiest way to parse emails. You only need to provide a message source to get a parsed email structure in return. As an additional bonus all embedded images in HTML (eg. the images that point to attachments using cid: URIs) are replaced with base64 encoded data URIs, so the message can be displayed without any additional processing. Be aware though that this module does not do any security cleansing (eg. removing javascript and so on), this is left to your own application.

const simpleParser = require('@nodemailer/mailparser2').simpleParser;
simpleParser(source, (err, mail)=>{})

or as a Promise:

simpleParser(source).then(mail=>{}).catch(err=>{})

Where

  • source is either a stream, a Buffer or a string that needs to be parsed
  • err is the possible error object
  • mail is a structured email object

mail object

Parsed mail object has the following properties

  • headers – a Map object with lowercase header keys
  • subject is the subject line (also available from the header mail.headers.get('subject'))
  • from is an address object for the From: header
  • to is an address object for the To: header
  • cc is an address object for the Cc: header
  • bcc is an address object for the Bcc: header (usually not present)
  • date is a Date object for the Date: header
  • messageId is the Message-ID value string
  • inReplyTo is the In-Reply-To value string
  • reply-to is an address object for the Cc: header
  • references is an array of referenced Message-ID values
  • html is the HTML body of the message. If the message included embedded images as cid: urls then these are all replaced with base64 formatted data: URIs
  • text is the plaintext body of the message
  • textAsHtml is the plaintext body of the message formatted as HTML
  • attachments is an array of attachments

address object

Address objects have the following structure:

  • value an array with address details
    • name is the name part of the email/group
    • address is the email address
    • group is an array of grouped addresses
  • text is a formatted address string for plaintext context
  • html is a formatted address string for HTML context

Example

{
    value: [
        {
            address: '[email protected]',
            name: 'Andris Reinman'
        },
        {
            address: '[email protected]',
            name: ''
        }
    ],
    html: '<span class="mp_address_name">Andris Reinman</span> &lt;<a href="mailto:[email protected]" class="mp_address_email">[email protected]</a>&gt;, <a href="mailto:[email protected]" class="mp_address_email">[email protected]</a>',
    text: 'Andris Reinman <[email protected]>, [email protected]'
}

headers Map

headers is a Map with lowercase header keys. So if you want to check for the Subject: header then you can do it like this:

if (mail.headers.has('subject')) {
    console.log(mail.headers.get('subject'));
}

The format of a header depends on the specific key. For most header keys the value is either a string (a single header) or an array of strings (multiple headers with the same key were found).

Special header keys are the following:

  1. All address headers are converted into address objects
  • from
  • to
  • cc
  • bcc
  • sender
  • reply-to
  • delivered-to
  • return-path
  1. All different priority headers are converted into priority with the following values:
  • 'high'
  • 'normal'
  • 'low'
  1. references is a string if only a single reference-id exists or an array if multiple ids exist
  2. date value is a Date object
  3. The following headers are parsed into structured objects, where value property includes the main value as string and params property holds an object of additional arguments as key-value pairs
  • content-type
  • content-disposition
  • dkim-signature

Some headers are also automaticaly mime-word decoded

  • all address headers (name parts and punycode encoded domains are converted to unicode)
  • subject is converted to unicode

attachment object

Attachment objects have the following structure:

  • filename (if available) file name of the attachment
  • contentType MIME type of the message
  • contentDisposition content disposition type for the attachment, most probably "attachment"
  • checksum a MD5 hash of the message content
  • size message size in bytes
  • headers a Map value that holds MIME headers for the attachment node
  • content a Buffer that contains the attachment contents
  • contentId the header value from 'Content-ID' (if present)
  • cid contentId without < and >
  • related if true then this attachment should not be offered for download (at least not in the main attachments list)

MailParser2

MailParser2 is a lower-level email parsing class. It is a transform stream that takes email source as bytestream for the input and emits data objects for attachments and text contents.

const MailParser2 = require('@nodemailer/mailparser2').MailParser2;
let parser = new MailParser2()

Event 'headers'

The parser emits 'headers' once message headers have been processed. The headers object is a Map. Different header keys have different kind of values, for example address headers have the address object/array as the value while subject value is string.

Header keys in the Map are lowercase.

parser.on('headers', headers = {
    console.log(headers.get('subject'));
});

Event 'data'

Event 'data' or 'readable' emits message content objects. The type of the object can be determine by the type property. Currently there are two kind of data objects

  • 'attachment' indicates that this object is an attachment
  • 'text' indicates that this object includes the html and text parts of the message. This object is emitted once and it includes both values

attachment object

Attachment object is the same as in simpleParser except that content is not a buffer but a stream. Additionally there's a method release() that must be called once you have processed the attachment. The property related is set after message processing is ended, so at the data event this value is not yet available.

parser.on('data', data => {
    if(data.type === 'attachment'){
        console.log(data.filename);
        data.content.pipe(process.stdout);
        data.on('end', ()=>data.release());
    }
});

If you do not call release() then the message processing is paused.

text object

Text object has the following keys:

  • text includes the plaintext version of the message. Is set if the message has at least one 'text/plain' node
  • html includes the HTML version of the message. Is set if the message has at least one 'text/html' node
  • textAsHtml includes the plaintext version of the message in HTML format. Is set if the message has at least one 'text/plain' node.
parser.on('data', data => {
    if(data.type === 'text'){
        console.log(data.html);
    }
});

Issues

Charset decoding is handled using iconv-lit that is missing some charsets, especially some Japanese ones. If required then it would be possible to switch to native iconv bindings with node-iconv to handle these missing charsets but for now this option is not used for easier packaging.

License

Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) (details). Commercial licenses available upon request.

© 2017 Kreata OÜ