summaryrefslogtreecommitdiffstats
path: root/lib/sendgrid.js
diff options
context:
space:
mode:
authorscottmotte <scott@scottmotte.com>2013-07-18 22:53:15 +0000
committerscottmotte <scott@scottmotte.com>2013-07-19 23:52:27 +0000
commitb423fd9b313991cdd2fdcd24ec05f725ad76870a (patch)
tree016657730dafd83bf2c130f0ba433041d60e0688 /lib/sendgrid.js
parent07e93f39d4c82019cd270a9a9331748f5d40d1c4 (diff)
downloadsendgrid-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.js205
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;