Notorious Penguin Magicians
    Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    buildmailpublic

    This package has been deprecated

    Author message:

    This project is unmaintained

    buildmail

    Low level rfc2822 message composer that streams output. Define your own mime tree, no magic included.

    Ported from MailBuild of the emailjs.org project. This port uses similar API but is for Node only and streams the output.

    Build Status NPM version

    Usage

    Install with npm

    npm install buildmail
    

    Require in your scripts

    var BuildMail = require('buildmail');

    API

    Create a new BuildMail object with

    var builder = new BuildMail(contentType [, options]);

    Where

    • contentType - define the content type for created node. Can be left blank for attachments (content type derived from filename option if available)
    • options - an optional options object
      • filename - String filename for an attachment node
      • baseBoundary - String shared part of the unique multipart boundary (generated randomly if not set)
      • keepBcc - Boolean If true keep the Bcc value in generated headers (default is to remove it)
      • textEncoding - set default content encoding, either 'base64' or 'quoted-printable'
      • hostname - optional hostname for default Message-Id values. Normally hostname from the from address is used but this might not be available
      • disableUrlAccess - if set to true then fails with an error when a node tries to load content from URL
      • disableFileAccess - if set to true then fails with an error when a node tries to load content from a file

    Methods

    The same methods apply to the root node created with new BuildMail() and to any child nodes.

    createChild

    Creates and appends a child node to the node object

    node.createChild(contentType, options)

    The same arguments apply as with new BuildMail(). Created node object is returned.

    Example

    new BuildMail('multipart/mixed').
        createChild('multipart/related').
            createChild('text/plain');

    Generates the following mime tree:

    multipart/mixed
      ↳ multipart/related
          ↳ text/plain

    appendChild

    Appends an existing child node to the node object. Removes the node from an existing tree if needed.

    node.appendChild(childNode)

    Where

    • childNode - child node to be appended

    Method returns appended child node.

    Example

    var childNode = new BuildMail('text/plain'),
        rootNode = new BuildMail('multipart/mixed');
    rootnode.appendChild(childNode);

    Generates the following mime tree:

    multipart/mixed
      ↳ text/plain

    replace

    Replaces current node with another node

    node.replace(replacementNode)

    Where

    • replacementNode - node to replace the current node with

    Method returns replacement node.

    Example

    var rootNode = new BuildMail('multipart/mixed'),
        childNode = rootNode.createChild('text/plain');
    childNode.replace(new BuildMail('text/html'));

    Generates the following mime tree:

    multipart/mixed
      ↳ text/html

    remove

    Removes current node from the mime tree. Does not make a lot of sense for a root node.

    node.remove();

    Method returns removed node.

    Example

     
    var rootNode = new BuildMail('multipart/mixed'),
        childNode = rootNode.createChild('text/plain');
    childNode.remove();

    Generates the following mime tree:

    multipart/mixed

    setHeader

    Sets a header value. If the value for selected key exists, it is overwritten.

    You can set multiple values as well by using [{key:'', value:''}] or {key: 'value'} structures as the first argument.

    node.setHeader(key, value);

    Where

    • key - String|Array|Object Header key or a list of key value pairs
    • value - String Header value

    Method returns current node.

    Example

    new BuildMail('text/plain').
        setHeader('content-disposition', 'inline').
        setHeader({
            'content-transfer-encoding': '7bit'
        }).
        setHeader([
            {key: 'message-id', value: 'abcde'}

    Generates the following header:

    Content-type: text/plain
    Content-Disposition: inline
    Content-Transfer-Encoding: 7bit
    Message-Id: <abcde>

    addHeader

    Adds a header value. If the value for selected key exists, the value is appended as a new field and old one is not touched.

    You can set multiple values as well by using [{key:'', value:''}] or {key: 'value'} structures as the first argument.

    node.addHeader(key, value);

    Where

    • key - String|Array|Object Header key or a list of key value pairs
    • value - String Header value or an array of strings to add the same key multiple times

    Method returns current node.

    Example

    new BuildMail('text/plain').
        addHeader('X-Spam', '1').
        setHeader({
            'x-spam': '2'
        }).
        setHeader([
            {key: 'x-spam', value: '3'}
        ]);

    Generates the following header:

    Content-type: text/plain
    X-Spam: 1
    X-Spam: 2
    X-Spam: 3

    Prepared headers

    Normally all headers are encoded and folded to meet the requirement of having plain-ASCII messages with lines no longer than 78 bytes. Sometimes it is preferable to not modify header values and pass these as provided. This can be achieved with the prepared option:

    new BuildMail('text/plain').
        addHeader('X-Long-Header', {
            prepared: true,
            value: 'a really long header or value with non-ascii characters 👮'
        });
     
    // normal output: 
    // X-Long-Header: a really long header or value with non-ascii characters 
    //  =?UTF-8?Q?=F0=9F=91=AE?= 
     
    // output with the prepared option: 
    // X-Long-Header: a really long header or value with non-ascii characters 👮 

    getHeader

    Retrieves the first mathcing value of a selected key

    node.getHeader(key)

    Where

    • key - String Key to search for

    Example

    new BuildMail('text/plain').getHeader('content-type'); // text/plain 

    buildHeaders

    Builds the current header info into a header block that can be used in an e-mail

    var headers = node.buildHeaders()

    Example

    new BuildMail('text/plain').
        addHeader('X-Spam', '1').
        setHeader({
            'x-spam': '2'
        }).
        setHeader([
            {key: 'x-spam', value: '3'}
        ]).buildHeaders();

    returns the following String

    Content-Type: text/plain
    X-Spam: 3
    Date: Sat, 21 Jun 2014 10:52:44 +0000
    Message-Id: <1403347964894-790a5296-0eb7c7c7-6440334f@localhost>
    MIME-Version: 1.0

    If the node is the root node, then Date and Message-Id values are generated automatically if missing

    setContent

    Sets body content for current node. If the value is a string and Content-Type is text/* then charset is set automatically. If the value is a Buffer or a Stream you need to specify the charset yourself.

    node.setContent(body)

    Where

    • body - String|Buffer|Stream|Object body content

    If the value is an object, it should include one of the following properties

    • path - path to a file that will be used as the content
    • href - URL that will be used as the content

    Example

    new BuildMail('text/plain').setContent('Hello world!');
     
    new BuildMail('text/plain; charset=utf-8').setContent(fs.createReadStream('message.txt'));

    setRaw

    Sets pre-generated output value for current node. When building the final message then this value is returned instead of building a fresh rfc822 mime message from normal input.

    This also means that other methods (getAddresses, getEnvelope etc.) that use normal input do not return valid values as the raw message is not parsed. You must set envelope contents manually with setEnvelope and you probably should set the Message-Id header (even though it wouldn't break anything if you would not set it).

    node.setRaw(message)

    Where

    • message - String|Buffer|Stream|Object MIME message

    If the value is an object, it should include one of the following properties

    • path - path to a file that will be used as the content
    • href - URL that will be used as the content

    Example

    new BuildMail().setRaw(fs.createReadStream('message.eml'));

    build

    Builds the rfc2822 message from the current node. If this is a root node, mandatory header fields are set if missing (Date, Message-Id, MIME-Version)

    node.build(callback)

    Callback returns the rfc2822 message as a Buffer

    Example

    new BuildMail('text/plain').setContent('Hello world!').build(function(err, mail){
        console.log(mail.toString('ascii'));
    });

    Returns the following string:

    Content-type: text/plain
    Date: <current datetime>
    Message-Id: <generated value>
    MIME-Version: 1.0
     
    Hello world!

    createReadStream

    If you manage large attachments you probably do not want to generate but stream the message.

    var stream = node.createReadStream(options)

    Where

    • options - Object optional Stream options (ie. highWaterMark)

    Example

    var message = new BuildMail();
    message.addHeader({
        from: 'From <from@example.com>',
        to: 'receiver1@example.com',
        cc: 'receiver2@example.com'
    });
    message.setContent(fs.createReadStream('message.txt'));
    message.createReadStream().pipe(fs.createWriteStream('message.eml'));

    transform

    If you want to modify the created stream, you can add transform streams that the output will be piped through.

    node.transform(transformStream)

    Where

    • transformStream - Stream or Function Transform stream that the output will go through before returing with createReadStream. If the value is a function the function should return a transform stream object when called.

    Example

    var PassThrough = require('stream').PassThrough;
    var message = new BuildMail();
    message.addHeader({
        from: 'From <from@example.com>',
        to: 'receiver1@example.com',
        cc: 'receiver2@example.com'
    });
    message.setContent(fs.createReadStream('message.txt'));
    message.transform(new PassThrough()); // add a stream that the output will be piped through 
    message.createReadStream().pipe(fs.createWriteStream('message.eml'));

    setEnvelope

    Set envelope object to use. If one is not set, it is generated based ong the headers.

    node.setEnvelope(envelope)

    Where

    • envelope is an envelope object in the form of {from:'address', to: ['addresses']}

    getEnvelope

    Generates a SMTP envelope object. Makes sense only for root node.

    var envelope = node.generateEnvelope()

    Method returns the envelope in the form of {from:'address', to: ['addresses']}

    Example

    new BuildMail().
        addHeader({
            from: 'From <from@example.com>',
            to: 'receiver1@example.com',
            cc: 'receiver2@example.com'
        }).
        getEnvelope();

    Returns the following object:

    {
        from: 'from@example.com',
        to: ['receiver1@example.com', 'receiver2@example.com']
    }

    messageId

    Returns Message-Id value. If it does not exist then generates one.

    var messageId = node.messageId();

    Method returns the Message-Id value <unique-message-id@example.com

    Example

    new BuildMail().
        addHeader({
            from: 'From <from@example.com>'
        }).
        messageId();

    Returns the following value:

    "<1453237212620-0657660b-8df9255d-18bcdcb5@example.com>"

    getAddresses

    Returns an address container object. Includes all parsed addresses from From, Sender, To, Cc, Bcc and Reply-To fields.

    While getEnvelope() returns 'from' value as a single address (the first one encountered) then getAddresses return all values as arrays, including from. Additionally while getEnvelope returns only from and a combined to value then getAddresses returns all fields separately.

    Possbile return values (all arrays in the form of [{name:'', address:''}]):

    • from
    • sender
    • 'reply-to'
    • to
    • cc
    • bcc

    If no addresses were found for a particular field, the field is not set in the response object.

    Example

    new BuildMail().
        addHeader({
            from: 'From <from@example.com>',
            to: '"Receiver" receiver1@example.com',
            cc: 'receiver2@example.com'
        }).
        getAddresses();

    Returns the following object:

    {
        from: [{
            name: 'From',
            address: 'from@example.com'
        }],
        to: [{
            name: 'Receiver',
            address: 'receiver1@example.com'
        }],
        cc: [{
            name: '',
            address: 'receiver2@example.com'
        }]
    }

    Notes

    Addresses

    When setting address headers (From, To, Cc, Bcc) use of unicode is allowed. If needed the addresses are converted to punycode automatically.

    Attachments

    For attachments you should minimally set filename option and Content-Disposition header. If filename is specified, you can leave content type blank - if content type is not set, it is detected from the filename.

    new BuildMail('multipart/mixed').
      createChild(false, {filename: 'image.png'}).
      setHeader('Content-Disposition', 'attachment');

    Obviously you might want to add Content-Id header as well if you want to reference this attachment from the HTML content.

    MIME structure

    Most probably you only need to deal with the following multipart types when generating messages:

    • multipart/alternative - includes the same content in different forms (usually text/plain + text/html)
    • multipart/related - includes main node and related nodes (eg. text/html + referenced attachments). Also requires a type parameter that indicates the Content-Type of the root element in the node
    • multipart/mixed - includes other multipart nodes and attachments, or single content node and attachments

    Examples

    One content node and an attachment

    multipart/mixed
      ↳ text/plain
      ↳ image/png

    Content node with referenced attachment (eg. image with Content-Type referenced by cid: url in the HTML)

    multipart/related
      ↳ text/html
      ↳ image/png

    Plaintext and HTML alternatives

    multipart/alternative
      ↳ text/html
      ↳ text/plain

    One content node with referenced attachment and a regular attachment

    multipart/mixed
      ↳ multipart/related
        ↳ text/plain
        ↳ image/png
      ↳ application/x-zip

    Alternative content with referenced attachment for HTML and a regular attachment

    multipart/mixed
      ↳ multipart/alternative
        ↳ text/plain
        ↳ multipart/related
          ↳ text/html
          ↳ image/png
      ↳ application/x-zip

    License

    MIT

    Keywords

    install

    npm i buildmail

    Downloadslast 7 days

    447,176

    version

    4.0.1

    license

    MIT

    repository

    github.com

    last publish

    collaborators

    • avatar