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 ) {