Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First draft

  • Loading branch information...
commit 00b53a167b9a4e768c9e98601ab0009a2b62aa8e 1 parent b9fcc04
Andris Reinman authored
View
104 examples/example_smtp.js
@@ -1,75 +1,77 @@
var nodemailer = require('../lib/mail');
-// Set up SMTP server settings
-nodemailer.SMTP = {
- host: 'smtp.gmail.com',
- port: 465,
- use_authentication: true,
- ssl: true,
- user: undefined,
- pass: undefined,
- debug: true
-};
+//
+
+// Create a SMTP transport object
+var transport = new nodemailer.Transport("SMTP", {
+ service: 'gmail', // use well known service
+ auth: {
+ user: "test.nodemailer@gmail.com",
+ pass: "Nodemailer123"
+ }
+ });
console.log('SMTP Configured');
-// unique cid value for the embedded image
-var cid = Date.now() + '.image.png';
// Message object
var message = {
- sender: 'Sender Name <from@example.com>',
- to: '"Receiver Name" <to@example.com>',
- subject: 'Nodemailer is unicode friendly ✔',
+
+ // define transport to deliver this message
+ transport: transport,
+
+ // sender info
+ from: 'Sender Name <andris@node.ee>',
+
+ // Comma separated list of recipients
+ to: '"Receiver Name" <andris.reinman@gmail.com>',
+
+ // Subject of the message
+ subject: 'Nodemailer is unicode friendly ✔', //
- body: 'Hello to myself!',
- html:'<p><b>Hello</b> to myself <img src="cid:' + cid + '"/></p>',
- debug: true,
+ // plaintext body
+ text: 'Hello to myself!',
+
+ // HTML body
+ html:'<p><b>Hello</b> to myself <img src="cid:note@node"/></p>'+
+ '<p>Here\'s a nyan cat for you from <a href="http://nyanc'+
+ 'at.cat/">nyancat.cat</a>:<br/><img src="cid:nyan@node"/></p>',
+
+ // An array of attachments
attachments:[
+
+ // String attachment
{
- filename: 'notes.txt',
- contents: 'Some notes about this e-mail'
+ fileName: 'notes.txt',
+ contents: 'Some notes about this e-mail',
+ contentType: 'text/plain' // optional, would be detected from the filename
},
+
+ // Binary Buffer attachment
{
- filename: 'image.png',
+ fileName: 'image.png',
contents: new Buffer('iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' +
'//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' +
'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC', 'base64'),
- cid: cid
+
+ cid: 'note@node' // should be as unique as possible
+ },
+
+ // File Stream attachment
+ {
+ fileName: 'nyancat.png',
+ filePath: __dirname+"/nyancat.png",
+ cid: 'nyan@node' // should be as unique as possible
}
]
};
-// Callback to be run after the sending is completed
-var callback = function(error, success){
+console.log('Sending Mail');
+nodemailer.sendMail(message, function(error){
if(error){
console.log('Error occured');
console.log(error.message);
return;
}
- if(success){
- console.log('Message sent successfully!');
- }else{
- console.log('Message failed, reschedule!');
- }
-};
-
-console.log('Sending Mail');
-
-// Catch uncaught errors
-process.on('uncaughtException', function(e){
- console.log('Uncaught Exception', e.stack);
-});
-
-// Send the e-mail
-var mail;
-try{
- mail = nodemailer.send_mail(message, callback);
-}catch(e) {
- console.log('Caught Exception',e);
-}
-
-var oldemit = mail.emit;
-mail.emit = function(){
- console.log('Mail.emit', arguments);
- oldemit.apply(mail, arguments);
-};
+ console.log('Message sent successfully!');
+ transport.close();
+});
View
BIN  examples/nyancat.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
32 lib/engines/sendmail.js
@@ -0,0 +1,32 @@
+var exec;
+
+try{
+ spawn = require('child_process').spawn;
+}catch(E){
+ // probably on Windows Node.js v0.5.0 - v0.5.2
+}
+
+module.exports = SendmailTransport;
+
+function SendmailTransport(config){
+ this.path = typeof config=="string"?config:"sendmail";
+}
+
+SendmailTransport.sendMail = function(emailMessage, callback) {
+
+ if(!spawn){
+ return callback && callback(new Error("No support for child processes in this version of Node.JS, use SMTP instead"));
+ }
+
+ // sendmail strips this header line
+ emailMessage.options.keepBcc = true;
+
+ var sendmail = spawn(this.path, "-t");
+
+ sendmail.on('exit', function (code) {
+ callback(code?new Error("Sendmail exited with "+code):null);
+ });
+
+ mailcomposer.pipe(sendmail.stdin);
+ mailcomposer.streamMessage();
+};
View
70 lib/engines/smtp.js
@@ -0,0 +1,70 @@
+
+var wellKnownHosts = require("../wellknown"),
+ simplesmtp = require("simplesmtp");
+
+
+module.exports = SMTPTransport;
+
+function SMTPTransport(options){
+ var keys, key, i, len;
+
+ this.options = options || {};
+
+ this.initOptions();
+
+ this.pool = simplesmtp.createClientPool(this.options.port,
+ this.options.host, this.options);
+}
+
+SMTPTransport.prototype.initOptions = function(){
+ // provide support for legacy API
+ if(this.options.use_authentication === false){
+ delete this.options.auth;
+ delete this.options.user;
+ delete this.options.pass;
+ }else if(this.options.user || this.options.pass){
+ if(!this.options.auth){
+ this.options.auth = {};
+ }
+ this.options.auth.user = this.options.auth.user || this.options.user;
+ this.options.auth.pass = this.options.auth.pass || this.options.pass;
+ delete this.options.user;
+ delete this.options.pass;
+ }
+
+ if(this.options.ssl){
+ this.options.secureConnection = true;
+ delete this.options.ssl;
+ }
+
+ if(this.options.tls === false){
+ this.options.ignoreTLS = true;
+ delete this.options.tls;
+ }
+
+ // lets be modest just in case
+ this.options.maxConnections = this.options.maxConnections || 1;
+
+ // use well known settings if service is defined
+ if(this.options.service && wellKnownHosts[this.options.service]){
+ keys = Object.keys(wellKnownHosts[this.options.service]);
+ for(i=0, len=keys.length; i<len; i++){
+ key = keys[i];
+ this.options[key] = this.options[key] || 
+ wellKnownHosts[this.options.service][key];
+ }
+ }
+}
+
+SMTPTransport.prototype.sendMail = function(emailMessage, callback){
+ if(this.options.requiresAuth &&
+ (!this.options.auth || !this.options.auth.user || !this.options.auth.pass)){
+ return callback(new Error("Authentication required, invalid details provided"));
+ }
+
+ this.pool.sendMail(emailMessage, callback);
+}
+
+SMTPTransport.prototype.close = function(callback){
+ this.pool.close(callback);
+}
View
141 lib/mail.js
@@ -1,3 +1,5 @@
+var Transport = require("./transport").Transport,
+ MailComposer = require("mailcomposer").MailComposer;
/*
* Version constants
@@ -5,3 +7,142 @@
var X_MAILER_NAME = "Nodemailer",
X_MAILER_VERSION = "0.3.0; +http://www.nodemailer.org";
+
+module.exports.Transport = Transport;
+
+module.exports.sendMail = module.exports.send_mail = function(options, callback){
+ var mailer = new Nodemailer(options);
+ mailer.validateSettings(function(err){
+ if(err){
+ return callback(err);
+ }else{
+ mailer.sendMail(callback);
+ }
+ });
+}
+
+
+/**
+ *
+ */
+function Nodemailer(options){
+ this.options = options || {};
+
+ this.transport = this.options.transport;
+
+ this.mailcomposer = new MailComposer();
+
+ if(!this.transport){
+ this.transport = this.getGlobalTransport();
+ }
+}
+
+// support legacy transport settings
+Nodemailer.prototype.getGlobalTransport = function(){
+ if(this.options.SMTP){
+ return new Transport("SMTP", this.options.SMTP);
+ }else if(this.options.sendmail){
+ return new Transport("sendmail", this.options.sendmail);
+ }else if(this.options.SES){
+ return new Transport("SES", this.options.SES);
+ }else if(module.exports.SMTP){
+ return new Transport("SMTP", module.exports.SMTP);
+ }else if(module.exports.sendmail){
+ return new Transport("sendmail", module.exports.sendmail);
+ }else if(module.exports.SES){
+ return new Transport("SES", module.exports.SES);
+ }
+ return false;
+}
+
+Nodemailer.prototype.validateSettings = function(callback){
+ if(!this.transport || !this.transport.transport){
+ return callback(new Error("No transport method defined"));
+ }
+ callback(null);
+}
+
+Nodemailer.prototype.sendMail = function(callback){
+ // compose the e-mail
+ this.generateMailObject();
+ // send the message using preselected transport method
+ this.transport.sendMail(this.mailcomposer, callback);
+};
+
+Nodemailer.prototype.generateMailObject = function(){
+
+ // set envelope data, subject etc.
+ this.setGeneralOptions();
+
+ // set module defined headers (date, message-id, etc.)
+ this.setModuleHeaders();
+
+ // set user defined headers (if any)
+ this.setUserHeaders();
+
+ // set attachments (if any)
+ this.setAttachments();
+
+}
+
+Nodemailer.prototype.setGeneralOptions = function(){
+ var acceptedFields = ["from", "sender", "to", "subject", "replyTo", "debug",
+ "reply_to", "cc", "bcc", "body", "text", "html"],
+ mailOptions = {},
+ keys = Object.keys(this.options),
+ key;
+
+ for(var i=0, len=keys.length; i<len; i++){
+ key = keys[i];
+ if(acceptedFields.indexOf(key) >=0 && this.options[key]){
+ mailOptions[key] = this.options[key];
+ }
+ }
+
+ if(this.options.debug){
+ console.log(mailOptions);
+ }
+
+ this.mailcomposer.setMessageOption(mailOptions);
+}
+
+Nodemailer.prototype.setUserHeaders = function(){
+ if(typeof this.options.headers != "object"){
+ return;
+ }
+ var keys = Object.keys(this.options.headers),
+ key;
+
+ for(var i=0, len=keys.length; i<len; i++){
+ key = keys[i];
+ if(this.options.headers[key]){
+ this.mailcomposer.addHeader(key, this.options.headers[key]);
+ }
+ }
+}
+
+Nodemailer.prototype.setModuleHeaders = function(){
+
+ // Mailer name + version
+ this.mailcomposer.addHeader("X-Mailer", X_MAILER_NAME+
+ (X_MAILER_VERSION?" ("+X_MAILER_VERSION+")":""));
+
+ // Date
+ this.mailcomposer.addHeader("Date", new Date().toUTCString());
+
+ // Message ID
+ this.mailcomposer.addHeader("Message-Id", "<"+
+ Date.now()+Math.random().toString(16).substr(1)+"@"+
+ X_MAILER_NAME+">");
+}
+
+Nodemailer.prototype.setAttachments = function(){
+ if(!Array.isArray(this.options.attachments)){
+ return;
+ }
+ var attachment;
+ for(var i=0, len=this.options.attachments.length; i<len; i++){
+ attachment = this.options.attachments[i];
+ this.mailcomposer.addAttachment(attachment);
+ }
+}
View
43 lib/transport.js
@@ -0,0 +1,43 @@
+var SendmailTransport = require("./engines/sendmail"),
+ SMTPTransport = require("./engines/smtp");
+
+
+module.exports.Transport = Transport;
+
+function Transport(type, options){
+
+ this.options = options;
+
+ switch((type || "").toString().trim().toUpperCase()){
+ case "SMTP":
+ this.transport = new SMTPTransport(this.options);
+ break;
+ case "SES":
+ this.transport = new SESransport(this.options);
+ break;
+ case "SENDMAIL":
+ this.transport = new SendmailTransport(this.options);
+ break;
+ default:
+ this.transport = false;
+ }
+
+}
+
+Transport.prototype.sendMail = function(emailMessage, callback){
+ if(!this.transport){
+ return callback(new Error("Invalid transport method defined"));
+ }
+
+ this.transport.sendMail(emailMessage, callback);
+}
+
+Transport.prototype.close = function(callback){
+ if(!this.transport){
+ return callback(new Error("Invalid transport method defined"));
+ }
+
+ if(typeof this.transport.close == "function"){
+ this.transport.close(callback);
+ }
+}
View
29 lib/wellknown.js
@@ -0,0 +1,29 @@
+
+
+module.exports = {
+ "gmail":{
+ host: "smtp.gmail.com",
+ secureConnection: true,
+ port: 465,
+ requiresAuth: true
+ },
+ "yahoo":{
+ host: "smtp.mail.yahoo.com",
+ secureConnection: true,
+ port: 465,
+ requiresAuth: true
+ },
+ "hotmail":{
+ host: "smtp.live.com",
+ port: 587,
+ requiresAuth: true
+ },
+ "hot.ee":{
+ host: "mail.hot.ee",
+ requiresAuth: true
+ },
+ "mail.ee":{
+ host: "smtp.mail.ee",
+ requiresAuth: true
+ }
+}
View
6 package.json
@@ -22,7 +22,11 @@
}
],
"dependencies": {
- "mimelib-noiconv":"*"
+ "mailcomposer": "*",
+ "simplesmtp": "*"
+ },
+ "devDependencies": {
+ "nodeunit": "*"
},
"engine": {
"node": ">=0.5"
Please sign in to comment.
Something went wrong with that request. Please try again.