diff options
author | scottmotte <scott@scottmotte.com> | 2013-07-18 22:53:15 +0000 |
---|---|---|
committer | scottmotte <scott@scottmotte.com> | 2013-07-19 23:52:27 +0000 |
commit | b423fd9b313991cdd2fdcd24ec05f725ad76870a (patch) | |
tree | 016657730dafd83bf2c130f0ba433041d60e0688 /lib/sendgrid.js | |
parent | 07e93f39d4c82019cd270a9a9331748f5d40d1c4 (diff) | |
download | sendgrid-nodejs-b423fd9b313991cdd2fdcd24ec05f725ad76870a.zip sendgrid-nodejs-b423fd9b313991cdd2fdcd24ec05f725ad76870a.tar.gz sendgrid-nodejs-b423fd9b313991cdd2fdcd24ec05f725ad76870a.tar.bz2 |
Switch to using request, additional specs, and a bit less code by switching and trusting request to the web api
Diffstat (limited to 'lib/sendgrid.js')
-rw-r--r-- | lib/sendgrid.js | 205 |
1 files changed, 53 insertions, 152 deletions
diff --git a/lib/sendgrid.js b/lib/sendgrid.js index 84135b5..68752a9 100644 --- a/lib/sendgrid.js +++ b/lib/sendgrid.js @@ -1,19 +1,12 @@ "use strict"; var package_json = require('./../package.json'); -var querystring = require('querystring'); -var https = require('https'); -var nodemailer = require('nodemailer'); -var _ = require('underscore'); -var path = require('path'); -var mime = require('mime'); +var nodemailer = require('nodemailer'); +var request = require('request'); var Email = require('./email'); -var SMTP = "SMTP"; -if (process.env.NODE_ENV == "test") { - SMTP = "STUB"; -} + /* * Class for handling communications with SendGrid. * @@ -24,10 +17,22 @@ function SendGrid(api_user, api_key) { this.api_user = api_user; this.api_key = api_key; this.version = package_json.version; + this.SMTP = "SMTP"; + if (process.env.NODE_ENV == "test") { + this.SMTP = "STUB"; + } +} + +/* + * Sends an email via web. See .web method for more details. + * + */ +SendGrid.prototype.send = function(email, callback) { + this.web(email, callback); } /* - * Sends an email via REST and returns true if the + * Sends an email via web and returns true if the * message was sent successfully. * * @param {Email|Object} email An email object or a hash that has @@ -35,83 +40,64 @@ function SendGrid(api_user, api_key) { * @param {Function} callback A function to call when the processing is done. * This parameter is optional. */ -SendGrid.prototype.send = function(email, callback) { +SendGrid.prototype.web = function(email, callback) { + var api_user = this.api_user; + var api_key = this.api_key; + var self = this , cb = callback || function() { }; - var boundary = Math.random(); - if (email.constructor !== Email) { email = new Email(email); } - function send_rest() { - var post_data; - var options = { - host: 'sendgrid.com', - path: '/api/mail.send.json', - method: 'POST' - }; - - if (email.hasFiles()) { - post_data = self.getMultipartData(email, boundary); - var length = 0; - for (var buf in post_data) { - length += post_data[buf].length; - } - options.headers = { - 'Content-Type': 'multipart/form-data; boundary=' + boundary, - 'Content-Length': length - }; - } else { - post_data = self.getPostData(email); - options.headers = { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': post_data.length - }; - } - - var request = https.request(options, function(res) { - res.setEncoding('utf8'); - var content = ''; - res.on('data', function(chunk) { - content += chunk; - }); - res.on('end', function() { + function send_web() { + var req = request({ + method : 'POST', + uri : "https://sendgrid.com/api/mail.send.json" + }, function(err, resp, body) { + if (err) { + return cb(false, err); + } else { try { - var json = JSON.parse(content); - cb(json.message == 'success', json.errors); - } catch (e) { + var json = JSON.parse(body); + return cb(json.message == 'success', json.errors); + } catch (err) { cb(false, "Invalid JSON response from server"); } - }); - }).on('error', function(e) { - cb(false, e); - }); - - // If the email has files, it will be a multipart request. - // TODO: make this feel less dirty. - if (email.hasFiles()) { - for (var key in post_data) { - request.write(post_data[key]); + } + }); + + var form = email.toWebFormat(); + form['api_user'] = api_user; + form['api_key'] = api_key; + + var reqForm = req.form(); + for (var field in form) { + var value = form[field]; + if (value.filename) { + if (value.cid) { + reqForm.append("content["+value.filename+"]", value.cid); + } + reqForm.append("files["+value.filename+"]", value.content, {filename: value.filename, contentType: value.contentType}); + } else { + try { + reqForm.append(field, value); + } catch(err) {} } - } else { - request.write(post_data); } - - request.end(); } if (email.hasFiles()) { email.processFiles(function(success, message) { if (success) { - send_rest(); + send_web(); } else { cb(false, message); } }); } else { - send_rest(); + send_web(); } }; @@ -130,7 +116,7 @@ SendGrid.prototype.smtp = function(email, callback) { , cb = callback || function() { }; // SMTP settings - smtpTransport = nodemailer.createTransport(SMTP, { + smtpTransport = nodemailer.createTransport(this.SMTP, { service: 'SendGrid', auth: { user: this.api_user, @@ -155,89 +141,4 @@ SendGrid.prototype.smtp = function(email, callback) { send_smtp(); }; -/* - * Function for internal use. - * - * Used for returning the parameters for sending an email via REST. - * - * This method is only used when there are no attachments on the email object. - * - * @param {Email} email The email object to be sent via REST. - * @return {String} Querystring format of the email to be sent. - */ -SendGrid.prototype.getPostData = function(email) { - var data = { - api_user: this.api_user, - api_key: this.api_key - } - - _.extend(data, email.toWebFormat()); - - return querystring.stringify(data); -}; - -/* - * Function for internal use. - * - * Used for returning the parameters for sending an email via REST. - * - * This method is used when there are attachments on the email object. - * - * @param {Email} email The email object to be sent via REST. - * @param {String} boundary The boundary to use between multipart sections. - * @return {Array[Buffer]} An array of buffers for each section of - * the multipart/form-data request. - */ -SendGrid.prototype.getMultipartData = function(email, boundary) { - var data = []; - data.push(new Buffer(encodeField(boundary, 'api_user', this.api_user))); - data.push(new Buffer(encodeField(boundary, 'api_key', this.api_key))); - - _(email.toWebFormat()).each(function(v, k) { - data.push(new Buffer(encodeField(boundary, k, v))); - }); - - _(email.files).each(function(file) { - if (file.cid) { - data.push(new Buffer(encodeField(boundary, 'content[' + file.filename + ']', file.cid))); - } - data.push(encodeFile(boundary, file.contentType, 'files[' + file.filename + ']', file.filename)); - data.push(file.content); - data.push(new Buffer('\r\n')); - }); - - return data; -}; - -/* - * Function for encoding a field as a multipart/form-data request. - * - * @param {String} boundary The boundary to use between requests. - * @param {String} name The name of the parameter. - * @param {String} value The value of the parameter. - * @return {String} The string representing the multipart/form-data section. - */ -function encodeField(boundary, name, value) { - var return_part = "--" + boundary + "\r\n"; - return_part += "Content-Disposition: form-data; name=\"" + name + "\"\r\n\r\n"; - return_part += value + "\r\n"; - return return_part; -} - -/* - * Function for encoding a file as a multipart/form-data request. - * - * @param {String} boundary The boundary to use between requests. - * @param {String} type The Content-Type of the file - * @param {String} name The name of the parameter. - * @param {String} filename The name of the file. - * @return {String} The string representing the multipart/form-data section. - */ -function encodeFile(boundary, type, name, filename) { - var return_part = "--" + boundary + "\r\n"; - return_part += "Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"\r\n"; - return_part += "Content-Type: " + type + "\r\n\r\n"; - return return_part; -} - module.exports = SendGrid; |