Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added MailAdapter and support for Mailgun API #191

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions MailAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Mail Adapter
//
// Allows you to send email using a third party API such as Mailgun.
//
// To send messages:
// var service = MailAdapter.getMailService(appId);
// if(service !== null) service.sendMail('[email protected]', 'Hello User!', 'Thanks for signing up!');
//
// Each adapter requires:-
// * validateConfig(config) -> returns a set of configuration values for each service. Different services have different config requirements
// * sendMail(to, subject, text) -> sends a message using the configured service

var MailgunAdapter = require('./MailgunAdapter');

var adapter = MailgunAdapter;
var mailConfigs = {};
var mailServices = {};

function setMailServiceConfig(appId, mailApiConfig) {

// Perform a type check on mailApiConfig to ensure it's a dictionary/object
if(typeof mailApiConfig === 'object') {

// Ensure mailApiConfig has a least a service defined, not not — default to mailgun
if(typeof mailApiConfig.service === 'undefined' || mailApiConfig.service === '') {
console.error('Error: You need to define a `service` when configuring `mailConfig` in ParseServer.');
mailApiConfig.service = 'mailgun'; // use mailgun as the default adapter
}

// Set the mail service as configured
if(mailApiConfig.service === '' || mailApiConfig.service === 'mailgun') {
adapter = MailgunAdapter;
mailApiConfig = MailgunAdapter.validateConfig(mailApiConfig);
} else {
// Handle other mail adapters here... (such as mandrill, postmark, etc
}

} else {
// Unexpected type, should be an object/dictionary.
console.log('Error: Unexpected `mailApiConfig` in MailAdapter.');
mailApiConfig = MailgunAdapter.validateConfig({}); // Just get some empty values
return false;
}

mailConfigs[appId] = mailApiConfig;
return true;
}

function clearMailService(appId) {
delete mailConfigs[appId];
delete mailServices[appId];
}

function getMailService(appId) {
if (mailServices[appId]) {
return mailServices[appId];
}

if(mailConfigs[appId] != null) {
mailServices[appId] = new adapter(appId, mailConfigs[appId]);
return mailServices[appId];
} else {
return null;
}
}

module.exports = {
mailConfigs: mailConfigs,
mailServices: mailServices,
setMailServiceConfig: setMailServiceConfig,
getMailService: getMailService,
clearMailService: clearMailService
};
57 changes: 57 additions & 0 deletions MailgunAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// A mail adapter for the Mailgun API

// options can contain:
function MailgunAdapter(appId, mailApiConfig) {
this.appId = appId;
this.apiConfig = mailApiConfig;
}

// Connects to the database. Returns a promise that resolves when the
// connection is successful.
// this.db will be populated with a Mongo "Db" object when the
// promise resolves successfully.
MailgunAdapter.prototype.sendMail = function(to, subject, text) {

var mailgun = require('mailgun-js')({apiKey: this.apiConfig.apiKey, domain: this.apiConfig.domain});

var data = {
from: this.apiConfig.fromAddress,
to: to,
subject: subject,
text: text
};

return new Promise((resolve, reject) => {
mailgun.messages().send(data, (err, body) => {
if (typeof err !== 'undefined') {
// console.log("Mailgun Error", err);
return reject(err);
}
// console.log(body);
resolve(body);
});
});
};

MailgunAdapter.validateConfig = function(config) {
var cfg = {apiKey:'', domain:'', fromAddress:''};
var helperMessage = "When creating an instance of ParseServer, you should have a mailConfig section like this: mailConfig: { service:'mailgun', apiKey:'MAILGUN_KEY_HERE', domain:'MAILGUN_DOMAIN_HERE', fromAddress:'MAILGUN_FROM_ADDRESS_HERE' }";
if(typeof config.apiKey === 'undefined' || config.apiKey === '') {
console.error('Error: You need to define a MailGun `apiKey` when configuring ParseServer. ' + helperMessage);
} else {
cfg.apiKey = config.apiKey;
}
if(typeof config.domain === 'undefined' || config.domain === '') {
console.error('Error: You need to define a MailGun `domain` when configuring ParseServer. ' + helperMessage);
} else {
cfg.domain = config.domain;
}
if(typeof config.fromAddress === 'undefined' || config.fromAddress === '') {
console.error('Error: You need to define a MailGun `fromAddress` when configuring ParseServer. ' + helperMessage);
} else {
cfg.fromAddress = config.fromAddress;
}
return cfg;
};

module.exports = MailgunAdapter;
10 changes: 10 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var batch = require('./batch'),
express = require('express'),
FilesAdapter = require('./FilesAdapter'),
S3Adapter = require('./S3Adapter'),
MailAdapter = require('./MailAdapter'),
middlewares = require('./middlewares'),
multer = require('multer'),
Parse = require('parse/node').Parse,
Expand All @@ -27,6 +28,11 @@ addParseCloud();
// "cloud": relative location to cloud code to require, or a function
// that is given an instance of Parse as a parameter. Use this instance of Parse
// to register your cloud code hooks and functions.
// "mailConfig": a dictionary of 3rd party mail service settings (such as API keys etc)
// currently only Mailgun is supported. So service, apiKey, domain and fromAddress
// are all required. Setup like mailgun: { service: 'mailgun', apiKey: 'MG_APIKEY',
// domain:'MG_DOMAIN', fromAddress:'Your App <[email protected]>' }. If you do not
// define mailConfig, no mail service will be setup.
// "appId": the application id to host
// "masterKey": the master key for requests to this app
// "facebookAppIds": an array of valid Facebook Application IDs, required
Expand All @@ -52,6 +58,10 @@ function ParseServer(args) {
if (args.databaseURI) {
DatabaseAdapter.setAppDatabaseURI(args.appId, args.databaseURI);
}
if(args.mailConfig) {
MailAdapter.setMailServiceConfig(args.appId, args.mailConfig);
}

if (args.cloud) {
addParseCloud();
if (typeof args.cloud === 'function') {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"deepcopy": "^0.5.0",
"express": "~4.2.x",
"hat": "~0.0.3",
"mailgun-js": "^0.7.7",
"mime": "^1.3.4",
"mongodb": "~2.0.33",
"multer": "~0.1.8",
Expand Down