Skip to content

Commit 128115f

Browse files
Merge pull request #650 from adamreisnz/expose-classes
Expose Client and MailService classes
2 parents 3d44762 + d8f42d0 commit 128115f

File tree

12 files changed

+338
-265
lines changed

12 files changed

+338
-265
lines changed

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2012-2017 SendGrid, Inc.
1+
Copyright (c) 2012-2018 SendGrid, Inc.
22

33
Permission is hereby granted, free of charge, to any person obtaining
44
a copy of this software and associated documentation files (the

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"test:mail": "babel-node ./node_modules/istanbul/lib/cli cover ./node_modules/mocha/bin/_mocha \"packages/mail/**/*.spec.js\"",
3434
"test:inbound": "babel-node ./node_modules/istanbul/lib/cli cover ./node_modules/mocha/bin/_mocha \"packages/inbound-mail-parser/**/*.spec.js\"",
3535
"test:contact": "babel-node ./node_modules/istanbul/lib/cli cover ./node_modules/mocha/bin/_mocha \"packages/contact-importer/**/*.spec.js\"",
36+
"test:files": "babel-node ./node_modules/istanbul/lib/cli cover ./node_modules/mocha/bin/_mocha \"test/files.spec.js\"",
3637
"test:license": "babel-node ./node_modules/istanbul/lib/cli cover ./node_modules/mocha/bin/_mocha license.spec.js",
3738
"test:typescript": "tsc",
3839
"test": "npm run test:all -s",

packages/client/README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ const request = {
6060
};
6161
client.request(request)
6262
.then(([response, body]) => {
63-
console.log(response.statusCode);
64-
console.log(response.body);
63+
console.log(response.statusCode);
64+
console.log(body);
6565
})
6666
```
6767

@@ -82,6 +82,15 @@ You can overwrite the promise implementation you want the client to use. Default
8282
global.Promise = require('bluebird');
8383
```
8484

85+
## Instantiate Client Instances Manually
86+
```js
87+
const {Client} = require('@sendgrid/client');
88+
const sgClient1 = new Client();
89+
const sgClient2 = new Client();
90+
sgClient1.setApiKey('KEY1');
91+
sgClient2.setApiKey('KEY2');
92+
```
93+
8594
<a name="announcements"></a>
8695
# Announcements
8796

packages/client/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
const client = require('./src/client');
4+
const Client = require('./src/classes/client');
5+
6+
module.exports = client;
7+
module.exports.Client = Client;

packages/client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"publishConfig": {
2323
"access": "public"
2424
},
25-
"main": "src/client.js",
25+
"main": "index.js",
2626
"engines": {
2727
"node": ">=6.0.0"
2828
},

packages/client/src/classes/client.js

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
'use strict';
2+
3+
/**
4+
* Dependencies
5+
*/
6+
const http = require('request');
7+
const pkg = require('../../package.json');
8+
const {
9+
helpers: {
10+
mergeData,
11+
},
12+
classes: {
13+
ResponseError,
14+
},
15+
} = require('@sendgrid/helpers');
16+
17+
/**
18+
* Sendgrid REST Client
19+
*/
20+
class Client {
21+
22+
/**
23+
* Constructor
24+
*/
25+
constructor() {
26+
27+
//API key
28+
this.apiKey = '';
29+
30+
//Default headers
31+
this.defaultHeaders = {
32+
'Accept': 'application/json',
33+
'User-agent': 'sendgrid/' + pkg.version + ';nodejs',
34+
};
35+
36+
//Empty default request
37+
this.defaultRequest = {
38+
json: true,
39+
baseUrl: 'https://api.sendgrid.com/',
40+
url: '',
41+
method: 'GET',
42+
headers: {},
43+
};
44+
}
45+
46+
/**
47+
* Set API key
48+
*/
49+
setApiKey(apiKey) {
50+
this.apiKey = apiKey;
51+
}
52+
53+
/**
54+
* Set default header
55+
*/
56+
setDefaultHeader(key, value) {
57+
this.defaultHeaders[key] = value;
58+
return this;
59+
}
60+
61+
/**
62+
* Set default request
63+
*/
64+
setDefaultRequest(key, value) {
65+
this.defaultRequest[key] = value;
66+
return this;
67+
}
68+
69+
/**
70+
* Create headers for request
71+
*/
72+
createHeaders(data) {
73+
74+
//Merge data with default headers
75+
const headers = mergeData(this.defaultHeaders, data);
76+
77+
//Add API key, but don't overwrite if header already set
78+
if (typeof headers.Authorization === 'undefined' && this.apiKey) {
79+
headers.Authorization = 'Bearer ' + this.apiKey;
80+
}
81+
82+
//Return
83+
return headers;
84+
}
85+
86+
/**
87+
* Create request
88+
*/
89+
createRequest(data) {
90+
91+
//Keep URL parameter consistent
92+
if (data.uri) {
93+
data.url = data.uri;
94+
delete data.uri;
95+
}
96+
97+
//Merge data with empty request
98+
const request = mergeData(this.defaultRequest, data);
99+
100+
//Add headers
101+
request.headers = this.createHeaders(request.headers);
102+
return request;
103+
}
104+
105+
/**
106+
* Do a request
107+
*/
108+
request(data, cb) {
109+
110+
//Create request
111+
const request = this.createRequest(data);
112+
113+
//Perform request
114+
const promise = new Promise((resolve, reject) => {
115+
http(request, (error, response, body) => {
116+
117+
//Request error
118+
if (error) {
119+
return reject(error);
120+
}
121+
122+
//Response error
123+
if (response.statusCode >= 400) {
124+
return reject(new ResponseError(response));
125+
}
126+
127+
//Successful response
128+
resolve([response, body]);
129+
});
130+
});
131+
132+
// Throw and error incase function not passed
133+
if (cb && typeof cb !== 'function') {
134+
throw new Error('Callback passed is not a function.');
135+
}
136+
137+
//Execute callback if provided
138+
if (cb) {
139+
promise
140+
.then(result => cb(null, result))
141+
.catch(error => cb(error, null));
142+
}
143+
144+
//Return promise
145+
return promise;
146+
}
147+
}
148+
149+
//Export class
150+
module.exports = Client;

packages/client/src/client.js

Lines changed: 1 addition & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -3,148 +3,7 @@
33
/**
44
* Dependencies
55
*/
6-
const http = require('request');
7-
const pkg = require('../package.json');
8-
const {
9-
helpers: {
10-
mergeData,
11-
},
12-
classes: {
13-
ResponseError,
14-
},
15-
} = require('@sendgrid/helpers');
16-
17-
/**
18-
* Sendgrid REST Client
19-
*/
20-
class Client {
21-
22-
/**
23-
* Constructor
24-
*/
25-
constructor() {
26-
27-
//API key
28-
this.apiKey = '';
29-
30-
//Default headers
31-
this.defaultHeaders = {
32-
'Accept': 'application/json',
33-
'User-agent': 'sendgrid/' + pkg.version + ';nodejs',
34-
};
35-
36-
//Empty default request
37-
this.defaultRequest = {
38-
json: true,
39-
baseUrl: 'https://api.sendgrid.com/',
40-
url: '',
41-
method: 'GET',
42-
headers: {},
43-
};
44-
}
45-
46-
/**
47-
* Set API key
48-
*/
49-
setApiKey(apiKey) {
50-
this.apiKey = apiKey;
51-
}
52-
53-
/**
54-
* Set default header
55-
*/
56-
setDefaultHeader(key, value) {
57-
this.defaultHeaders[key] = value;
58-
return this;
59-
}
60-
61-
/**
62-
* Set default request
63-
*/
64-
setDefaultRequest(key, value) {
65-
this.defaultRequest[key] = value;
66-
return this;
67-
}
68-
69-
/**
70-
* Create headers for request
71-
*/
72-
createHeaders(data) {
73-
74-
//Merge data with default headers
75-
const headers = mergeData(this.defaultHeaders, data);
76-
77-
//Add API key, but don't overwrite if header already set
78-
if (typeof headers.Authorization === 'undefined' && this.apiKey) {
79-
headers.Authorization = 'Bearer ' + this.apiKey;
80-
}
81-
82-
//Return
83-
return headers;
84-
}
85-
86-
/**
87-
* Create request
88-
*/
89-
createRequest(data) {
90-
91-
//Keep URL parameter consistent
92-
if (data.uri) {
93-
data.url = data.uri;
94-
delete data.uri;
95-
}
96-
97-
//Merge data with empty request
98-
const request = mergeData(this.defaultRequest, data);
99-
100-
//Add headers
101-
request.headers = this.createHeaders(request.headers);
102-
return request;
103-
}
104-
105-
/**
106-
* Do a request
107-
*/
108-
request(data, cb) {
109-
110-
//Create request
111-
const request = this.createRequest(data);
112-
113-
//Perform request
114-
const promise = new Promise((resolve, reject) => {
115-
http(request, (error, response, body) => {
116-
117-
//Request error
118-
if (error) {
119-
return reject(error);
120-
}
121-
122-
//Response error
123-
if (response.statusCode >= 400) {
124-
return reject(new ResponseError(response));
125-
}
126-
127-
//Successful response
128-
resolve([response, body]);
129-
});
130-
});
131-
132-
// Throw and error incase function not passed
133-
if (cb && typeof cb !== 'function') {
134-
throw new Error('Callback passed is not a function.');
135-
}
136-
137-
//Execute callback if provided
138-
if (cb) {
139-
promise
140-
.then(result => cb(null, result))
141-
.catch(error => cb(error, null));
142-
}
143-
144-
//Return promise
145-
return promise;
146-
}
147-
}
6+
const Client = require('./classes/client');
1487

1498
//Export singleton instance
1509
module.exports = new Client();

packages/mail/USE_CASES.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ This documentation provides examples for specific email use cases. Please [open
1515
* [Specifying Time to Send At](#time-to-send)
1616
* [Specifying Custom Headers](#custom-headers)
1717
* [Specifying Categories](#categories)
18-
* [Kitchen Sink - an example with all settings used](#kitchensink)
18+
* [Managing multiple API keys](#multipleapikeys)
19+
* [Kitchen Sink - an example with all settings used](#kitchen-sink)
1920
* [Deploy a Simple App on Google App Engine with Node.js](#gae)
2021
* [Deploy a Simple App on Heroku with Node.js](#heroku)
2122
* [How to Setup a Domain Whitelabel](#domain-white-label)
@@ -409,6 +410,27 @@ const msg = {
409410
};
410411
```
411412

413+
<a name="multipleapikeys"></a>
414+
## Managing multiple API keys
415+
416+
In cases where you need to manage multiple instances of the mailer (or underlying client),
417+
for example when you are using multiple API keys, you can import the mail service class and
418+
instantiate new instances as required:
419+
420+
```js
421+
const {MailService} = require('@sendgrid/mail');
422+
423+
//Instantiate mailers
424+
const sgMail1 = new MailService();
425+
const sgMail2 = new MailService();
426+
427+
//Set different API keys
428+
sgMail1.setApiKey('KEY1');
429+
sgMail2.setApiKey('KEY2');
430+
431+
//Now send emails with the mailers as per the usual
432+
```
433+
412434
<a name="kitchen-sink"></a>
413435
## Kitchen Sink - an example with all settings used
414436

0 commit comments

Comments
 (0)