Fork me on GitHub

simplesmtp

DEPRECATION NOTICE

This module is deprecated for production use. For SMTP servers use Haraka, for SMTP clients use smtp-connection.

Simplesmtp is a module written for Node v0.6 and slightly updated for Node v0.8. It does not use Node v0.10 streams and probably is going to have a rocky future with Node v0.12. I do not have time to keep it up to date, the thing probably needs a major rewrite for Node v0.12.

Should be fine though for integration testing purposes.

Info

This is a module to easily create custom SMTP servers and clients - use SMTP as a first class protocol in Node.JS!

Build Status NPM version

Version warning!

If you are using node v0.6, then the last usable version of simplesmtp is v0.2.7

Current version of simplesmtp is fully supported for Node v0.8+

Support simplesmtp development

Donate to author

SMTP Server

Simple SMTP server

For a simple inbound only, no authentication SMTP server you can use

simplesmtp.createSimpleServer([options], requestListener).listen(port);

Example

simplesmtp.createSimpleServer({SMTPBanner:"My Server"}, function(req){
    req.pipe(process.stdout);
    req.accept();
}).listen(port);

Properties

Methods

Events

Advanced SMTP server

Usage

Create a new SMTP server instance with

var smtp = simplesmtp.createServer([options]);

And start listening on selected port

smtp.listen(25, [function(err){}]);

SMTP options can include the following:

Example

var simplesmtp = require("simplesmtp"),
    fs = require("fs");

var smtp = simplesmtp.createServer();
smtp.listen(25);

smtp.on("startData", function(connection){
    console.log("Message from:", connection.from);
    console.log("Message to:", connection.to);
    connection.saveStream = fs.createWriteStream("/tmp/message.txt");
});

smtp.on("data", function(connection, chunk){
    connection.saveStream.write(chunk);
});

smtp.on("dataReady", function(connection, callback){
    connection.saveStream.end();
    console.log("Incoming message saved to /tmp/message.txt");
    callback(null, "ABC1"); // ABC1 is the queue id to be advertised to the client
    // callback(new Error("Rejected as spam!")); // reported back to the client
});

Events

SMTP Client

Usage

SMTP client can be created with simplesmtp.connect(port[,host][, options]) where

Connection options

The following connection options can be used with simplesmtp.connect:

Connection events

Once a connection is set up the following events can be listened to:

Sending an envelope

When an 'idle' event is emitted, an envelope object can be sent to the server. This includes a string from and an array of strings to property.

Envelope can be sent with client.useEnvelope(envelope)

// run only once as 'idle' is emitted again after message delivery
client.once("idle", function(){
    client.useEnvelope({
        from: "me@example.com",
        to: ["receiver1@example.com", "receiver2@example.com"]
    });
});

The to part of the envelope includes all recipients from To:, Cc: and Bcc: fields.

If setting the envelope up fails, an error is emitted. If only some (not all) recipients are not accepted, the mail can still be sent but an rcptFailed event is emitted.

client.on("rcptFailed", function(addresses){
    console.log("The following addresses were rejected: ", addresses);
});

If the envelope is set up correctly a 'message' event is emitted.

Sending a message

When 'message' event is emitted, it is possible to send mail. To do this you can pipe directly a message source (for example an .eml file) to the client or alternatively you can send the message with client.write calls (you also need to call client.end() once the message is completed.

If you are piping a stream to the client, do not leave the 'end' event out, this is needed to complete the message sequence by the client.

client.on("message", function(){
    fs.createReadStream("test.eml").pipe(client);
});

Once the message is delivered a 'ready' event is emitted. The event has an parameter which indicates if the message was transmitted( (true) or not (false) and another which includes the last received data from the server.

client.on("ready", function(success, response){
    if(success){
        console.log("The message was transmitted successfully with "+response);
    }
});

XOAUTH

simplesmtp supports XOAUTH2 and XOAUTH authentication.

XOAUTH2

To use this feature you can set XOAuth2 param as an auth option

var mailOptions = {
    ...,
    auth:{
        XOAuth2: {
            user: "example.user@gmail.com",
            clientId: "8819981768.apps.googleusercontent.com",
            clientSecret: "{client_secret}",
            refreshToken: "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI",
            accessToken: "vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg==",
            timeout: 3600
        }
    }
}

accessToken and timeout values are optional. If login fails a new access token is generated automatically.

XOAUTH

To use this feature you can set XOAuthToken param as an auth option

var mailOptions = {
    ...,
    auth:{
        XOAuthToken: "R0VUIGh0dHBzOi8vbWFpbC5nb29...."
    }
}

Alternatively it is also possible to use XOAuthToken generators (supported by Nodemailer) - this needs to be an object with a mandatory method generate that takes a callback function for generating a XOAUTH token string. This is better for generating tokens only when needed - there is no need to calculate unique token for every e-mail request, since a lot of these might share the same connection and thus the cleint needs not to re-authenticate itself with another token.

var XOGen = {
    token: "abc",
    generate: function(callback){
        if(1 != 1){
            return callback(new Error("Tokens can't be generated in strange environments"));
        }
        callback(null, new Buffer(this.token, "utf-8").toString("base64"));
    }
}

var mailOptions = {
    ...,
    auth:{
        XOAuthToken: XOGen
    }
}

Error types

Emitted errors include the reason for failing in the name property

There's also an additional property in the error object called data that includes the last response received from the server (if available for the current error type).

About reusing the connection

You can reuse the same connection several times but you can't send a mail through the same connection concurrently. So if you catch and 'idle' event lock the connection to a message process and unlock after 'ready'.

On 'error' events you should reschedule the message and on 'end' events you should recreate the connection.

Closing the client

By default the client tries to keep the connection up. If you want to close it, run client.quit() - this sends a QUIT command to the server and closes the connection

client.quit();

SMTP Client Connection pool

simplesmtp has the option for connection pooling if you want to reuse a bulk of connections.

Usage

Create a connection pool of SMTP clients with

simplesmtp.createClientPool(port[,host][, options])

where

Connection options

The following connection options can be used with simplesmtp.connect:

Send an e-mail

E-mails can be sent through the pool with

pool.sendMail(mail[, callback])

where

Errors

In addition to SMTP client errors another error name is used

License

MIT