From 9a3e528471508eaab7cf1493523304dbe83f480c Mon Sep 17 00:00:00 2001 From: "Aydrian J. Howard" <aydrian@gmail.com> Date: Mon, 21 Mar 2016 15:23:32 -0400 Subject: [PATCH 1/3] Added support for Relay Webhooks --- docs/resources/relayWebhooks.md | 55 ++++++ examples/relayWebhooks/create_relayWebhook.js | 19 ++ examples/relayWebhooks/delete_relayWebhook.js | 15 ++ examples/relayWebhooks/find_relayWebhook.js | 15 ++ .../relayWebhooks/get_all_relayWebhooks.js | 14 ++ examples/relayWebhooks/update_relayWebhook.js | 18 ++ lib/relayWebhooks.js | 115 ++++++++++++ lib/sparkpost.js | 1 + test/spec/relayWebhooks.spec.js | 163 ++++++++++++++++++ 9 files changed, 415 insertions(+) create mode 100644 docs/resources/relayWebhooks.md create mode 100644 examples/relayWebhooks/create_relayWebhook.js create mode 100644 examples/relayWebhooks/delete_relayWebhook.js create mode 100644 examples/relayWebhooks/find_relayWebhook.js create mode 100644 examples/relayWebhooks/get_all_relayWebhooks.js create mode 100644 examples/relayWebhooks/update_relayWebhook.js create mode 100644 lib/relayWebhooks.js create mode 100644 test/spec/relayWebhooks.spec.js diff --git a/docs/resources/relayWebhooks.md b/docs/resources/relayWebhooks.md new file mode 100644 index 0000000..52c6e7d --- /dev/null +++ b/docs/resources/relayWebhooks.md @@ -0,0 +1,55 @@ +# Relay Webhooks + +This library provides easy access to the [Relay Webhooks](https://www.sparkpost.com/api#/reference/relay-webhooks/) Resource. + +## Methods +* **all(options, callback)** + List all relay webhooks. + * `callback` - executed after task is completed. **required** + * standard `callback(err, data)` + * `err` - any error that occurred + * `data` - full response from request client +* **find(webhookId, callback)** + Retrieve details about a specified relay webhook by its id + * `webhookId` - the id of the relay webhook you want to look up **required** + * `callback` - see all function +* **create(options, callback)** + Create a new recipient list + * `options.target` - url of the target to which to POST relay batches **required** + * `options.domain` - inbound domain associated with this webhook **required** + * `options.name` - user-friendly name + * `options.authToken` - authentication token to present in the X-MessageSystems-Webhook-Token header of POST requests to target + * `options.protocol` - inbound messaging protocol associated with this webhook + * `callback` - see all function +* **update(options, callback)** + Update an existing relay webhook + * `options.webhookId` - the id of the relay webhook you want to update **required** + * `options.target` - url of the target to which to POST relay batches + * `options.domain` - inbound domain associated with this webhook + * `options.name` - user-friendly name + * `options.authToken` - authentication token to present in the X-MessageSystems-Webhook-Token header of POST requests to target + * `options.protocol` - inbound messaging protocol associated with this webhook + * `callback` - see all function +* **delete(webhookId, callback)** + Delete an existing relay webhook + * `webhookId` - the id of the webhook you want to delete **required** + * `callback` - see all function + +## Examples + +```js +var SparkPost = require('sparkpost'); +var client = new SparkPost('YOUR_API_KEY'); + +client.relayWebhooks.all(function(err, data) { + if(err) { + console.log(err); + return; + } + + console.log(data.body); +}); + +``` + +Check out all the examples provided [here](/examples/relayWebhooks). diff --git a/examples/relayWebhooks/create_relayWebhook.js b/examples/relayWebhooks/create_relayWebhook.js new file mode 100644 index 0000000..0475de2 --- /dev/null +++ b/examples/relayWebhooks/create_relayWebhook.js @@ -0,0 +1,19 @@ +'use strict'; + +var key = 'YOURAPIKEY' + , SparkPost = require('sparkpost') + , client = new SparkPost(key) + , options = { + name: 'Test Relay Webhook' + , target: 'http://client.test.com/test-webhook' + , domain: 'inbound.example.com' + }; + +client.relayWebhooks.create(options, function(err, res) { + if (err) { + console.log(err); + } else { + console.log(res.body); + console.log('Congrats you can use our client library!'); + } +}); diff --git a/examples/relayWebhooks/delete_relayWebhook.js b/examples/relayWebhooks/delete_relayWebhook.js new file mode 100644 index 0000000..62704c0 --- /dev/null +++ b/examples/relayWebhooks/delete_relayWebhook.js @@ -0,0 +1,15 @@ +'use strict'; + +var key = 'YOURAPIKEY' + , SparkPost = require('sparkpost') + , client = new SparkPost(key) + , webhookId = '123456789'; + +client.relayWebhooks['delete'](webhookId, function(err, res) { + if (err) { + console.log(err); + } else { + console.log(res.body); + console.log('Congrats you can use our client library!'); + } +}); diff --git a/examples/relayWebhooks/find_relayWebhook.js b/examples/relayWebhooks/find_relayWebhook.js new file mode 100644 index 0000000..96c9a07 --- /dev/null +++ b/examples/relayWebhooks/find_relayWebhook.js @@ -0,0 +1,15 @@ +'use strict'; + +var key = 'YOURAPIKEY' + , SparkPost = require('sparkpost') + , client = new SparkPost(key) + , webhookId = '123456789'; + +client.relayWebhooks.find(webhookId, function(err, res) { + if (err) { + console.log(err); + } else { + console.log(res.body); + console.log('Congrats you can use our client library!'); + } +}); diff --git a/examples/relayWebhooks/get_all_relayWebhooks.js b/examples/relayWebhooks/get_all_relayWebhooks.js new file mode 100644 index 0000000..864f9e3 --- /dev/null +++ b/examples/relayWebhooks/get_all_relayWebhooks.js @@ -0,0 +1,14 @@ +'use strict'; + +var key = 'YOURAPIKEY' + , SparkPost = require('sparkpost') + , client = new SparkPost(key); + +client.relayWebhooks.all(function(err, res) { + if (err) { + console.log(err); + } else { + console.log(res.body); + console.log('Congrats you can use our client library!'); + } +}); diff --git a/examples/relayWebhooks/update_relayWebhook.js b/examples/relayWebhooks/update_relayWebhook.js new file mode 100644 index 0000000..95ed5dc --- /dev/null +++ b/examples/relayWebhooks/update_relayWebhook.js @@ -0,0 +1,18 @@ +'use strict'; + +var key = 'YOURAPIKEY' + , SparkPost = require('sparkpost') + , client = new SparkPost(key) + , options = { + webhookId: '123456789' + , target: 'http://client.test.com/test-webhook' + }; + +client.relayWebhooks.update(options, function(err, res) { + if (err) { + console.log(err); + } else { + console.log(res.body); + console.log('Congrats you can use our client library!'); + } +}); diff --git a/lib/relayWebhooks.js b/lib/relayWebhooks.js new file mode 100644 index 0000000..ba731e2 --- /dev/null +++ b/lib/relayWebhooks.js @@ -0,0 +1,115 @@ +'use strict'; + +var api = 'relay-webhooks'; + +var toApiFormat = function(input) { + var model = { + match: {} + }; + + model.target = input.target; + model.match.domain = input.domain; + + model.name = input.name; + model.auth_token = input.authToken; + model.match.protocol = input.protocol; + + return model; +}; + +module.exports = function(client) { + var relayWebhooks = { + all: function(callback) { + var reqOpts = { + uri: api + }; + client.get(reqOpts, callback); + }, + find: function(webhookId, callback) { + if(typeof webhookId === 'function') { + callback = webhookId; + webhookId = null; + } + + if(!webhookId) { + callback(new Error('webhookId is required')); + return; + } + + var options = { + uri: api + '/' + webhookId + }; + client.get(options, callback); + }, + create: function(options, callback) { + if(typeof options === 'function') { + callback = options; + options = null; + } + + if(!options) { + callback(new Error('options are required')); + return; + } + + if(!options.target) { + callback(new Error('target is required in options')); + return; + } + + if(!options.domain) { + callback(new Error('domain is required in options')); + return; + } + + var reqOpts = { + uri: api + , json: toApiFormat(options) + }; + client.post(reqOpts, callback); + }, + update: function(options, callback) { + if(typeof options === 'function') { + callback = options; + options = null; + } + + if(!options) { + callback(new Error('options are required')); + return; + } + + if(!options.webhookId) { + callback(new Error('webhookId is required in options')); + return; + } + + var webhookId = options.webhookId; + var reqOpts = { + uri: api + '/' + webhookId + , json: toApiFormat(options) + }; + client.put(reqOpts, callback); + } + }; + + relayWebhooks['delete'] = function(webhookId, callback) { + if (typeof webhookId === 'function') { + callback = webhookId; + webhookId = null; + } + + if (!webhookId) { + callback(new Error('webhookId is required')); + return; + } + + var options = { + uri: api + '/' + webhookId + }; + + client['delete'](options, callback); + }; + + return relayWebhooks; +}; diff --git a/lib/sparkpost.js b/lib/sparkpost.js index 0f2ce9f..ee06b3f 100644 --- a/lib/sparkpost.js +++ b/lib/sparkpost.js @@ -56,6 +56,7 @@ var SparkPost = function(apiKey, options) { this.apiVersion = options.apiVersion || defaults.apiVersion; this.recipientLists = require('./recipientLists')(this); + this.relayWebhooks = require('./relayWebhooks')(this); this.sendingDomains = require('./sendingDomains')(this); this.suppressionList = require('./suppressionList')(this); this.templates = require('./templates')(this); diff --git a/test/spec/relayWebhooks.spec.js b/test/spec/relayWebhooks.spec.js new file mode 100644 index 0000000..ec5f9e9 --- /dev/null +++ b/test/spec/relayWebhooks.spec.js @@ -0,0 +1,163 @@ +var chai = require('chai') + , expect = chai.expect + , sinon = require('sinon') + , sinonChai = require('sinon-chai'); + +chai.use(sinonChai); + +describe('Relay Webhooks Library', function() { + var client, relayWebhooks; + + beforeEach(function() { + client = { + get: sinon.stub().yields(), + post: sinon.stub().yields(), + put: sinon.stub().yields(), + 'delete': sinon.stub().yields() + }; + + relayWebhooks = require('../../lib/relayWebhooks')(client); + }); + + describe('all Method', function() { + it('should call client get method with the appropriate uri', function(done) { + relayWebhooks.all(function(err, data) { + expect(client.get.firstCall.args[0].uri).to.equal('relay-webhooks'); + done(); + }); + }); + }); + + describe('find Method', function() { + it('should call client get method with the appropriate uri', function(done) { + relayWebhooks.find('test', function() { + expect(client.get.firstCall.args[0]).to.deep.equal({uri: 'relay-webhooks/test'}); + done(); + }); + }); + + it('should throw an error if webhookId is null', function(done) { + relayWebhooks.find(null, function(err) { + expect(err.message).to.equal('webhookId is required'); + expect(client.get).not.to.have.been.called; + done(); + }); + }); + + it('should throw an error if webhookId is missing', function(done) { + relayWebhooks.find(function(err) { + expect(err.message).to.equal('webhookId is required'); + expect(client.get).not.to.have.been.called; + done(); + }); + }); + }); + + describe('create Method', function() { + it('should call client post method with the appropriate uri', function(done) { + var options = { + target: 'test', + domain: 'inbound.example.com' + }; + + relayWebhooks.create(options, function(err, data) { + expect(client.post.firstCall.args[0].uri).to.equal('relay-webhooks'); + done(); + }); + }); + + it('should throw an error if options is null', function(done) { + relayWebhooks.create(null, function(err) { + expect(err.message).to.equal('options are required'); + expect(client.post).not.to.have.been.called; + done(); + }); + }); + + it('should throw an error if options is missing', function(done) { + relayWebhooks.create(function(err) { + expect(err.message).to.equal('options are required'); + expect(client.post).not.to.have.been.called; + done(); + }); + }); + + it('should throw an error if target is missing from options', function(done) { + relayWebhooks.create({domain: 'inbound.example.com'}, function(err) { + expect(err.message).to.equal('target is required in options'); + expect(client.put).not.to.have.been.called; + done(); + }); + }); + + it('should throw an error if domain is missing from options', function(done) { + relayWebhooks.create({target: 'test'}, function(err) { + expect(err.message).to.equal('domain is required in options'); + expect(client.put).not.to.have.been.called; + done(); + }); + }); + }); + + describe('update Method', function() { + it('should call client put method with the appropriate uri', function(done) { + var options = { + webhookId: "test" + }; + + relayWebhooks.update(options, function(err, data) { + expect(client.put.firstCall.args[0].uri).to.equal('relay-webhooks/test'); + done(); + }); + }); + + it('should throw an error if options is null', function(done) { + relayWebhooks.update(null, function(err) { + expect(err.message).to.equal('options are required'); + expect(client.put).not.to.have.been.called; + done(); + }); + }); + + it('should throw an error if options is missing', function(done) { + relayWebhooks.update(function(err) { + expect(err.message).to.equal('options are required'); + expect(client.put).not.to.have.been.called; + done(); + }); + }); + + it('should throw an error if webhookId is missing from options', function(done) { + relayWebhooks.update({}, function(err) { + expect(err.message).to.equal('webhookId is required in options'); + expect(client.put).not.to.have.been.called; + done(); + }); + }); + }); + + describe('delete Method', function() { + it('should call client delete method with the appropriate uri', function(done) { + relayWebhooks['delete']('test', function(err, data) { + expect(client['delete'].firstCall.args[0].uri).to.equal('relay-webhooks/test'); + done(); + }); + }); + + it('should throw an error if webhookId is null', function(done) { + relayWebhooks['delete'](null, function(err) { + expect(err.message).to.equal('webhookId is required'); + expect(client['delete']).not.to.have.been.called; + done(); + }); + }); + + it('should throw an error if webhookId is missing', function(done) { + relayWebhooks['delete'](function(err) { + expect(err.message).to.equal('webhookId is required'); + expect(client['delete']).not.to.have.been.called; + done(); + }); + }); + }); +}); From 5245a7efd077931aeba9f3dc54f89a307620f41b Mon Sep 17 00:00:00 2001 From: "Aydrian J. Howard" <aydrian@gmail.com> Date: Mon, 28 Mar 2016 10:34:58 -0400 Subject: [PATCH 2/3] quoted delete method cleanup and renamed webhookId to relayWebhookId --- examples/relayWebhooks/delete_relayWebhook.js | 4 +- examples/relayWebhooks/find_relayWebhook.js | 4 +- examples/relayWebhooks/update_relayWebhook.js | 2 +- lib/relayWebhooks.js | 53 +++++++++---------- test/spec/relayWebhooks.spec.js | 36 ++++++------- 5 files changed, 49 insertions(+), 50 deletions(-) diff --git a/examples/relayWebhooks/delete_relayWebhook.js b/examples/relayWebhooks/delete_relayWebhook.js index 62704c0..e401783 100644 --- a/examples/relayWebhooks/delete_relayWebhook.js +++ b/examples/relayWebhooks/delete_relayWebhook.js @@ -3,9 +3,9 @@ var key = 'YOURAPIKEY' , SparkPost = require('sparkpost') , client = new SparkPost(key) - , webhookId = '123456789'; + , relayWebhookId = '123456789'; -client.relayWebhooks['delete'](webhookId, function(err, res) { +client.relayWebhooks.delete(relayWebhookId, function(err, res) { if (err) { console.log(err); } else { diff --git a/examples/relayWebhooks/find_relayWebhook.js b/examples/relayWebhooks/find_relayWebhook.js index 96c9a07..272ca44 100644 --- a/examples/relayWebhooks/find_relayWebhook.js +++ b/examples/relayWebhooks/find_relayWebhook.js @@ -3,9 +3,9 @@ var key = 'YOURAPIKEY' , SparkPost = require('sparkpost') , client = new SparkPost(key) - , webhookId = '123456789'; + , relayWebhookId = '123456789'; -client.relayWebhooks.find(webhookId, function(err, res) { +client.relayWebhooks.find(relayWebhookId, function(err, res) { if (err) { console.log(err); } else { diff --git a/examples/relayWebhooks/update_relayWebhook.js b/examples/relayWebhooks/update_relayWebhook.js index 95ed5dc..302e5eb 100644 --- a/examples/relayWebhooks/update_relayWebhook.js +++ b/examples/relayWebhooks/update_relayWebhook.js @@ -4,7 +4,7 @@ var key = 'YOURAPIKEY' , SparkPost = require('sparkpost') , client = new SparkPost(key) , options = { - webhookId: '123456789' + relayWebhookId: '123456789' , target: 'http://client.test.com/test-webhook' }; diff --git a/lib/relayWebhooks.js b/lib/relayWebhooks.js index ba731e2..dc22bce 100644 --- a/lib/relayWebhooks.js +++ b/lib/relayWebhooks.js @@ -25,19 +25,19 @@ module.exports = function(client) { }; client.get(reqOpts, callback); }, - find: function(webhookId, callback) { - if(typeof webhookId === 'function') { - callback = webhookId; - webhookId = null; + find: function(relayWebhookId, callback) { + if(typeof relayWebhookId === 'function') { + callback = relayWebhookId; + relayWebhookId = null; } - if(!webhookId) { - callback(new Error('webhookId is required')); + if(!relayWebhookId) { + callback(new Error('relayWebhookId is required')); return; } var options = { - uri: api + '/' + webhookId + uri: api + '/' + relayWebhookId }; client.get(options, callback); }, @@ -79,36 +79,35 @@ module.exports = function(client) { return; } - if(!options.webhookId) { - callback(new Error('webhookId is required in options')); + if(!options.relayWebhookId) { + callback(new Error('relayWebhookId is required in options')); return; } - var webhookId = options.webhookId; + var relayWebhookId = options.relayWebhookId; var reqOpts = { - uri: api + '/' + webhookId + uri: api + '/' + relayWebhookId , json: toApiFormat(options) }; client.put(reqOpts, callback); - } - }; - - relayWebhooks['delete'] = function(webhookId, callback) { - if (typeof webhookId === 'function') { - callback = webhookId; - webhookId = null; - } + }, + delete: function(relayWebhookId, callback) { + if (typeof relayWebhookId === 'function') { + callback = relayWebhookId; + relayWebhookId = null; + } - if (!webhookId) { - callback(new Error('webhookId is required')); - return; - } + if (!relayWebhookId) { + callback(new Error('relayWebhookId is required')); + return; + } - var options = { - uri: api + '/' + webhookId - }; + var options = { + uri: api + '/' + relayWebhookId + }; - client['delete'](options, callback); + client.delete(options, callback); + } }; return relayWebhooks; diff --git a/test/spec/relayWebhooks.spec.js b/test/spec/relayWebhooks.spec.js index ec5f9e9..ea2991f 100644 --- a/test/spec/relayWebhooks.spec.js +++ b/test/spec/relayWebhooks.spec.js @@ -13,7 +13,7 @@ describe('Relay Webhooks Library', function() { get: sinon.stub().yields(), post: sinon.stub().yields(), put: sinon.stub().yields(), - 'delete': sinon.stub().yields() + delete: sinon.stub().yields() }; relayWebhooks = require('../../lib/relayWebhooks')(client); @@ -36,17 +36,17 @@ describe('Relay Webhooks Library', function() { }); }); - it('should throw an error if webhookId is null', function(done) { + it('should throw an error if relayWebhookId is null', function(done) { relayWebhooks.find(null, function(err) { - expect(err.message).to.equal('webhookId is required'); + expect(err.message).to.equal('relayWebhookId is required'); expect(client.get).not.to.have.been.called; done(); }); }); - it('should throw an error if webhookId is missing', function(done) { + it('should throw an error if relayWebhookId is missing', function(done) { relayWebhooks.find(function(err) { - expect(err.message).to.equal('webhookId is required'); + expect(err.message).to.equal('relayWebhookId is required'); expect(client.get).not.to.have.been.called; done(); }); @@ -102,7 +102,7 @@ describe('Relay Webhooks Library', function() { describe('update Method', function() { it('should call client put method with the appropriate uri', function(done) { var options = { - webhookId: "test" + relayWebhookId: "test" }; relayWebhooks.update(options, function(err, data) { @@ -127,9 +127,9 @@ describe('Relay Webhooks Library', function() { }); }); - it('should throw an error if webhookId is missing from options', function(done) { + it('should throw an error if relayWebhookId is missing from options', function(done) { relayWebhooks.update({}, function(err) { - expect(err.message).to.equal('webhookId is required in options'); + expect(err.message).to.equal('relayWebhookId is required in options'); expect(client.put).not.to.have.been.called; done(); }); @@ -138,24 +138,24 @@ describe('Relay Webhooks Library', function() { describe('delete Method', function() { it('should call client delete method with the appropriate uri', function(done) { - relayWebhooks['delete']('test', function(err, data) { - expect(client['delete'].firstCall.args[0].uri).to.equal('relay-webhooks/test'); + relayWebhooks.delete('test', function(err, data) { + expect(client.delete.firstCall.args[0].uri).to.equal('relay-webhooks/test'); done(); }); }); - it('should throw an error if webhookId is null', function(done) { - relayWebhooks['delete'](null, function(err) { - expect(err.message).to.equal('webhookId is required'); - expect(client['delete']).not.to.have.been.called; + it('should throw an error if relayWebhookId is null', function(done) { + relayWebhooks.delete(null, function(err) { + expect(err.message).to.equal('relayWebhookId is required'); + expect(client.delete).not.to.have.been.called; done(); }); }); - it('should throw an error if webhookId is missing', function(done) { - relayWebhooks['delete'](function(err) { - expect(err.message).to.equal('webhookId is required'); - expect(client['delete']).not.to.have.been.called; + it('should throw an error if relayWebhookId is missing', function(done) { + relayWebhooks.delete(function(err) { + expect(err.message).to.equal('relayWebhookId is required'); + expect(client.delete).not.to.have.been.called; done(); }); }); From 57ab0e256aff163743288ff60a33384fc7a3bc91 Mon Sep 17 00:00:00 2001 From: "Aydrian J. Howard" <aydrian@gmail.com> Date: Mon, 28 Mar 2016 13:55:26 -0400 Subject: [PATCH 3/3] Updated README.md --- README.md | 2 ++ lib/sparkpost.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d560a5b..264d02c 100644 --- a/README.md +++ b/README.md @@ -132,8 +132,10 @@ sp.transmissions.send({ ## SparkPost API Resources Supported in Node Client Library Click on the desired API to see usage and more information +* [Inbound Domains](/docs/resources/inboundDomains.md) - `client.inboundDomains` ([examples](/examples/inboundDomains)) * [Message Events](/docs/resources/messageEvents.md) - `client.messageEvents` ([examples](/examples/messageEvents)) * [Recipient Lists](/docs/resources/recipientLists.md) - `client.recipientLists` ([examples](/examples/recipientLists)) +* [Relay Webhooks](/docs/resources/relayWebhooks.md) - `client.relayWebhooks` ([examples](/examples/relayWebhooks)) * [Sending Domains](/docs/resources/sendingDomains.md) - `client.sendingDomains` ([examples](/examples/sendingDomains)) * [Suppression List](/docs/resources/suppressionList.md) - `client.suppressionList` ([examples](/examples/suppressionList)) * [Templates](/docs/resources/templates.md) - `client.templates` ([examples](/examples/templates)) diff --git a/lib/sparkpost.js b/lib/sparkpost.js index d7962b7..4afa401 100644 --- a/lib/sparkpost.js +++ b/lib/sparkpost.js @@ -56,6 +56,7 @@ var SparkPost = function(apiKey, options) { this.apiVersion = options.apiVersion || defaults.apiVersion; this.inboundDomains = require('./inboundDomains')(this); + this.messageEvents = require('./messageEvents')(this); this.recipientLists = require('./recipientLists')(this); this.relayWebhooks = require('./relayWebhooks')(this); this.sendingDomains = require('./sendingDomains')(this); @@ -63,7 +64,6 @@ var SparkPost = function(apiKey, options) { this.templates = require('./templates')(this); this.transmissions = require('./transmissions')(this); this.webhooks = require('./webhooks')(this); - this.messageEvents = require('./messageEvents')(this); }; SparkPost.prototype.request = function( options, callback ) {