Skip to content

Instantly share code, notes, and snippets.

@jeffreypriebe
Created January 15, 2016 04:42
Show Gist options
  • Save jeffreypriebe/238e384573136aa7d37a to your computer and use it in GitHub Desktop.
Save jeffreypriebe/238e384573136aa7d37a to your computer and use it in GitHub Desktop.
Parts of code to send email on change of a Keystone Model
//mailer.js exports an object that matches what Keystone expects for its Mandrill objects, allowing you to use node-mailer (in this case) for sending email.
var nodemailer = require('nodemailer'),
smtp = require('nodemailer-smtp-transport'),
Q = require('q'),
_ = require('underscore');
if (!process.env.SMTP_USER || !process.env.SMTP_PASS) throw new Error("Expected SMTP_USER and SMTP_PASS env, missing one or both.");
//Also see more node mailer transport options https://github.com/nodemailer/nodemailer
var transport = nodemailer.createTransport(smtp({
host: '',
port: 25,
secure: false,
ignoreTLS: true,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS
}
}));
var mapToResults = function (arr) {
return arr.map(function (r) {
return r.value;
});
};
var send = function (toSend, onSuccess, onFail) {
var message = toSend.message;
if (!message.to || message.to.length === 0) {
console.warn("WARNING: No emails found to send mail to.");
return;
}
var messageBase = {
from: "\"" + message.from_name + "\" <" + message.from_email + ">",
subject: message.subject + " - " + Date.now(),
html: message.html
};
var sendMessages = message.to.map(function (t) {
var thisMessage = _.extend({}, messageBase, {
to: "\"" + t.name + "\" <" + t.email + ">",
replyTo: "\"" + t.name + "\" <" + t.email + ">"
});
return transport.sendMail(thisMessage);
});
Q.allSettled(sendMessages).done(function (results) {
var errors = results.filter(function (r) {
return r.state !== "fulfilled";
});
if (errors && errors.length > 0) {
console.log("Errors while sending mail.");
errors.forEach(function (e) { console.error(e); });
onFail(mapToResults(errors));
}
else {
onSuccess(mapToResults(results));
}
});
};
module.exports = {
send: send,
mandrill: {
messages: {
send: send,
sendTemplate: function (a, b, c) { }
},
templates: {
render: function (a, b, c) { }
}
}
};
//Add this to the model that will be sending email
//It doesn't have to form part of the model, but it follows what we see elsewhere in Keystone, e.g. https://github.com/JedWatson/sydjs-site/blob/master/models/Post.js
//Swap out the model name of users to lookup and input your own values for the email
var mailer = require('mailer.js');
//monkey patch in async saves in mongoose 3.x, h/t:http://stackoverflow.com/a/26049430/1592 , https://github.com/Automattic/mongoose/issues/787#issuecomment-56896373
var notifyUsers = function(callback) {
var postedForm = this;
// Method to send the notification email after data has been loaded
var sendEmail = function(err, results) {
if (err) return callback(err);
if (!results || results.length === 0) {
console.warn("WARNING: No admin users found to send sponsorship notification to.");
return callback();
}
async.each(results, function(notifyUser, done) {
new keystone.Email.send({
mandrill: mailer.mandrill,
userName: notifyUser.name.first || notifyUser.name.full,
sponsorName: postedForm.name,
sponsorEmail: postedForm.email,
comments: postedForm.comments,
subject: '',
to: notifyUser,
from: {
name: 'EMAIL SENT FROM',
email: 'website@example.com'
}
}, done);
}, callback);
}
keystone.list({{MODEL NAME TO LOOKUP FOR WHOM TO SEND EMAIL TO}}).model.find().where('sendAnEmail', true).exec(sendEmail);
};
Sponsor.schema.methods.save = function(done) {
return Model.prototype.save.call(this, function(err, result) {
if(err) {
console.error(err);
return done(err, result);
}
var fns = [notifyUsers.bind(result)];
return async.series(fns, function(err) {
if (err) console.error(err);
done(err, result)
});
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment