From 7a1a1407a1105945a7e435e0a65b986ea34f320c Mon Sep 17 00:00:00 2001 From: Bojan Djurkovic Date: Mon, 17 Dec 2012 10:35:20 -0400 Subject: [PATCH] first commit --- LICENSE.txt | 22 +++++ README.md | 71 +++++++++++++++ mailgun.js | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 25 ++++++ 4 files changed, 364 insertions(+) create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 mailgun.js create mode 100644 package.json diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..79882f7 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2010–2012 LearnBoost + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c6627ec --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# mailgun.js + +Simple Node.js module for [Mailgun](http://www.mailgun.com). + +## Installation + +`npm install mailgun-js` + +## Usage overview + +Please see [Mailgun Documentation](http://documentation.mailgun.net) for full Mailgun API reference. +All methods take a final parameter callback with three parameters: `error`, `response`, and `body`, exactly like the request callback. +We try to parse the `body` into a javascript object, and return it to the callback as such for easier use and inspection by the client. +`response.statusCode` will be `200` if everything worked OK. See Mailgun documentation for other (error) response codes. + +```javascript +var Mailgun = require('mailgun-js'); + +var mailgun = new Mailgun('key-...............................', 'mydomain.com'); + +var data = { + from: 'Excited User ', + to: 'serobnic@mail.ru', + subject: 'Hello', + text: 'Testing some Mailgun awesomness!' +}; + +mailgun.sendMessage(data, function (error, response, body) { + console.log(body); +}); +``` + +## Constructor + +### new Mailgun(key, domain); + +Returns a Mailgun object with your Mailgun API key and Mailgun domain set on the object. + +## Methods + + + +### mailgun.sendMessage(data, callback); + +```javascript +var data = { + from: 'Excited User ', + to: 'serobnic@mail.ru', + subject: 'Hello', + text: 'Testing some Mailgun awesomness!' +}; + +mailgun.sendMessage(data, function (error, response, body) { + console.log(body); +}); +``` + +Sample `body` is a javascript object + +``` +{ message: 'Queued. Thank you.', + id: '<20121217142109.14542.78348@onelobby.mailgun.org>' } +``` + +## License + +This project is not endorsed by or affiliated with [Mailgun](http://www.mailgun.com). + +Copyright 2012 Bojan Djurkovic + +Licensed under the MIT License. diff --git a/mailgun.js b/mailgun.js new file mode 100644 index 0000000..6ee94ac --- /dev/null +++ b/mailgun.js @@ -0,0 +1,246 @@ +/*! + * mailgun-js + * Copyright(c) 2012 OneLobby + * MIT Licensed + */ + + +var request = require('request'); + +/** + * Creates new Mailgun object + * @param api_key {String} the API Key for the mailgun account + * @param domain {String} the mailgun domain + * @type {Function} + */ +var Mailgun = module.exports = function (api_key, domain) { + this.username = 'api' + this.api_key = api_key; + this.domain = domain; + this.protocol = 'https://'; + this.host = 'api.mailgun.net'; + this.endpoint = '/v2'; + + this.headers = {}; + var b = new Buffer([this.username, this.api_key].join(':')); + this.headers['Authorization'] = "Basic " + b.toString('base64'); +}; + +/** + * Creates a new email message and sends it using mailgun + * @param data {Object} the object containing the data to be sent. + * Required parameters are 'to', 'from', and 'text' or 'html' + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.sendMessage = function (data, cb) { + if (!data.to) { + return cb(new Error('You must include a \'to\' number.')); + } + if (!data.from) { + return cb(new Error('You must include a \'from\' number.')); + } + if (!data.text && !data.html) { + return cb(new Error('You must include a \'text\' or \'html\' parameter.')); + } + + return this.request('POST', '/messages', data, cb); +}; + +/** + * Lists mailboxes associated with the mailgun account + * @param data {Object} the optional object containing the GET options 'limit' and 'skip' + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.getMailboxes = function (data, cb) { + return this.request('GET', '/mailboxes', data, cb); +}; + +/** + * Creates a new mailbox associated with the mailgun account + * @param data {Object} the object containing the new mailbox name ('mailbox') and new password ('password') + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.createMailbox = function (data, cb) { + if (!data.mailbox) { + return cb(new Error('You must include name of the mailbox in the \'mailbox\' parameter.')); + } + if (!data.password) { + return cb(new Error('You must include a password for the new mailbox.')); + } + + return this.request('POST', '/mailboxes', data, cb); +}; + +/** + * Deletes a mailbox associated with the mailgun account + * @param mailbox {String} the mailbox to be deleted + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.deleteMailbox = function (mailbox, cb) { + if (!mailbox) { + return cb(new Error('You must include name of the mailbox.')); + } + + return this.request('DELETE', '/mailboxes/' + mailbox, cb); +}; + +/** + * Updates the mailbox associated with the mailgun account + * @param data {Object} the object containing the mailbox name ('mailbox') and new password ('password') + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.updateMailbox = function (data, cb) { + if (!data.mailbox) { + return cb(new Error('You must include name of the mailbox in the \'mailbox\' parameter.')); + } + if (!data.password) { + return cb(new Error('You must include a password for the mailbox.')); + } + + var mailbox = data.mailbox; + delete data.mailbox; + + return this.request('PUT', '/mailboxes/' + mailbox, data, cb); +}; + + +/** + * Lists routes associated with the mailgun account + * @param data {Object} the optional object containing the GET options 'limit' and 'skip' + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.getRoutes = function (data, cb) { + return this.request('GET', '/routes', data, cb); +}; + +/** + * Returns a single route object based on its ID. + * @param id {String} the route ID + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.getRoute = function (id, cb) { + if (!id) { + return cb(new Error('You must include id of the route.')); + } + + return this.request('GET', '/routes/' + id, cb); +}; + +/** + * Creates a new route + * @param data {Object} the object containing the priority, description, expression and action as strings + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.createRoute = function (data, cb) { + if (!data.expression) { + return cb(new Error('You must include route expression.')); + } + if (!data.action) { + return cb(new Error('You must include route action.')); + } + + return this.request('POST', '/routes', data, cb); +}; + +/** + * Updates a given route by ID. All data parameters optional: + * this API call only updates the specified fields leaving others unchanged. + * @param id {String} the route ID + * @param data {Object} the object containing the priority, description, expression and action as strings + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.updateRoute = function (id, data, cb) { + if (!id) { + return cb(new Error('You must include id of the route.')); + } + + return this.request('PUT', '/routes/' + id, data, cb); +}; + +/** + * Deletes a route based on the id. + * @param id {String} the id of the route to be deleted + * @param cb {Function} callback function accepting error, response and body + * @type {Function} + */ +Mailgun.prototype.deleteRoute = function (id, cb) { + if (!id) { + return cb(new Error('You must include the ID of the mailbox.')); + } + + return this.request('DELETE', '/routes/' + id, cb); +}; + +/** + * The main function that does all the work. The client really shouldn't call this. + * @param method {String} HTTP method + * @param resource {String} the resource + * @param data {Object} the data to be sent in the request + * @param cb {Function} callback for the request + * @return + */ + +Mailgun.prototype.request = function (method, resource, data, cb) { + + var self = this; + + if (typeof data === 'function' && !cb) { + cb = data; + data = {}; + } + + var getDomain = function() { + var d = '/' + self.domain; + //filter out API calls that do not require a domain specified + if (resource.indexOf('route') >= 0) { + d = ''; + } + return d; + }; + + var url = ''; + url = url.concat( + this.protocol, + this.username, ':', this.api_key, + '@', + this.host, + this.endpoint, + getDomain(), + resource); + + console.log(url); + + var opts = { + url: url, + method: method, + headers: this.headers, + form: data + }; + + var responseCb = function (error, response, body) { + if (response && (response.headers['content-type'] === 'application/json')) { + try { + body = JSON.parse(body); + + if (!error && response.statusCode !== 200) { + error = new Error(body.message); + } + } catch (e) { + + } + } + + return cb(error, response, body); + }; + + return request(opts, responseCb); +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..941753b --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "author": { + "name": "Bojan Djurkovic " + }, + "name": "mailgun-js", + "description": "Simple Node.js helper module for Mailgun API", + "keywords": ["email", "mailgun"], + "version": "0.1.0", + "homepage": "https://github.com/onelobby/mailgun-js", + "license": "MIT", + "repository": { + "type": "git", + "url": "git://github.com/onelobby/mailgun-js.git" + }, + "bugs" : { + "url" : "http://github.com/onelobby/mailgun-js/issues" + }, + "engines": { + "node": "0.8.x" + }, + "main": "./mailgun.js", + "dependencies": { + "request": "2.12.x" + } +} \ No newline at end of file