Skip to content

Commit

Permalink
Merge pull request #691 from prohabits/master
Browse files Browse the repository at this point in the history
Added support for dynamicTemplateData
  • Loading branch information
thinkingserious authored Jun 14, 2018
2 parents a38a831 + afc4e65 commit 15d9b0a
Show file tree
Hide file tree
Showing 17 changed files with 1,237 additions and 437 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"chai": "^4.0.1",
"chai-as-promised": "^6.0.0",
"dirty-chai": "^1.2.2",
"eslint": "^3.19.0",
"eslint": "^4.19.1",
"istanbul": "^1.0.0-alpha.2",
"lerna": "^2.0.0-rc.5",
"mocha": "^3.4.2",
Expand Down
53 changes: 5 additions & 48 deletions packages/client/yarn.lock
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@sendgrid/helpers@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@sendgrid/helpers/-/helpers-6.0.0.tgz#b7ae9b927822e6a3a3e44abb2486e68d03e25220"
dependencies:
chalk "^2.0.1"


"@types/form-data@*":
version "2.2.0"
Expand All @@ -30,24 +26,18 @@ ajv@^4.9.1:
co "^4.6.0"
json-stable-stringify "^1.0.1"

ansi-styles@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
dependencies:
color-convert "^1.9.0"

asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"

[email protected], assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"

assert-plus@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"

assert-plus@^1.0.0, [email protected]:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"

asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
Expand Down Expand Up @@ -76,28 +66,10 @@ caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"

chalk@^2.0.1:
version "2.1.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e"
dependencies:
ansi-styles "^3.1.0"
escape-string-regexp "^1.0.5"
supports-color "^4.0.0"

co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"

color-convert@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
dependencies:
color-name "^1.1.1"

color-name@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"

combined-stream@^1.0.5, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
Expand Down Expand Up @@ -126,10 +98,6 @@ ecc-jsbn@~0.1.1:
dependencies:
jsbn "~0.1.0"

escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"

extend@~3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
Expand Down Expand Up @@ -167,10 +135,6 @@ har-validator@~4.2.1:
ajv "^4.9.1"
har-schema "^1.0.5"

has-flag@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"

hawk@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
Expand Down Expand Up @@ -312,12 +276,6 @@ stringstream@~0.0.4:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"

supports-color@^4.0.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.1.tgz#65a4bb2631e90e02420dba5554c375a4754bb836"
dependencies:
has-flag "^2.0.0"

tough-cookie@~2.3.0:
version "2.3.2"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
Expand All @@ -343,4 +301,3 @@ [email protected]:
resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
dependencies:
extsprintf "1.0.2"

66 changes: 57 additions & 9 deletions packages/helpers/classes/mail.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Mail {
constructor(data) {

//Initialize array and object properties
this.isDynamic = false;
this.personalizations = [];
this.attachments = [];
this.content = [];
Expand All @@ -35,6 +36,7 @@ class Mail {
//Helper properties
this.substitutions = null;
this.substitutionWrappers = null;
this.dynamicTemplateData = null;

//Process data if given
if (data) {
Expand All @@ -55,14 +57,14 @@ class Mail {
//Convert to camel case to make it workable, making a copy to prevent
//changes to the original objects
data = deepClone(data);
data = toCamelCase(data, ['substitutions', 'customArgs', 'headers']);
data = toCamelCase(data, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers']);

//Extract properties from data
const {
to, from, replyTo, cc, bcc, sendAt, subject, text, html, content,
templateId, personalizations, attachments, ipPoolName, batchId,
sections, headers, categories, category, customArgs, asm, mailSettings,
trackingSettings, substitutions, substitutionWrappers, isMultiple,
trackingSettings, substitutions, substitutionWrappers, dynamicTemplateData, isMultiple,
} = data;

//Set data
Expand All @@ -83,8 +85,13 @@ class Mail {
this.setAsm(asm);
this.setMailSettings(mailSettings);
this.setTrackingSettings(trackingSettings);
this.setSubstitutions(substitutions);
this.setSubstitutionWrappers(substitutionWrappers);

if (this.isDynamic) {
this.setDynamicTemplateData(dynamicTemplateData)
} else {
this.setSubstitutions(substitutions);
this.setSubstitutionWrappers(substitutionWrappers);
}

//Add contents from text/html properties
this.addTextContent(text);
Expand Down Expand Up @@ -153,7 +160,7 @@ class Mail {
}

/**
* Set template ID
* Set template ID, also checks if the template is dynamic or legacy
*/
setTemplateId(templateId) {
if (typeof templateId === 'undefined') {
Expand All @@ -162,6 +169,11 @@ class Mail {
if (typeof templateId !== 'string') {
throw new Error('String expected for `templateId`');
}

if (templateId.indexOf('d-') === 0) {
this.isDynamic = true;
}

this.templateId = templateId;
}

Expand Down Expand Up @@ -226,13 +238,27 @@ class Mail {
*/
addPersonalization(personalization) {

//We should either send substitutions or dynamicTemplateData
//depending on the templateId
if (this.isDynamic && personalization.substitutions) {
delete personalization.substitutions;
} else if (personalization.dynamicTemplateData) {
delete personalization.dynamicTemplateData;
}

//Convert to class if needed
if (!(personalization instanceof Personalization)) {
personalization = new Personalization(personalization);
}

//Apply substitutions and push to array
this.applySubstitutions(personalization);
//If this is dynamic, set dynamicTemplateData, or set substitutions
if (this.isDynamic) {
this.applyDynamicTemplateData(personalization);
} else {
this.applySubstitutions(personalization);
}

//Push personalization to array
this.personalizations.push(personalization);
}

Expand Down Expand Up @@ -288,6 +314,28 @@ class Mail {
}
}

/**
* Helper which applies globally set dynamic_template_data to personalizations
*/
applyDynamicTemplateData(personalization) {
if (personalization instanceof Personalization) {
personalization.deepMergeDynamicTemplateData(this.dynamicTemplateData);
}
}

/**
* Set dynamicTemplateData
*/
setDynamicTemplateData(dynamicTemplateData) {
if (typeof dynamicTemplateData === 'undefined') {
return;
}
if (typeof dynamicTemplateData !== 'object') {
throw new Error('Object expected for `dynamicTemplateData`');
}
this.dynamicTemplateData = dynamicTemplateData;
}

/**
* Set content
*/
Expand Down Expand Up @@ -377,7 +425,7 @@ class Mail {
categories = [categories];
}
if (!Array.isArray(categories) ||
!categories.every(cat => typeof cat === 'string')) {
!categories.every(cat => typeof cat === 'string')) {
throw new Error('Array of strings expected for `categories`');
}
this.categories = categories;
Expand Down Expand Up @@ -539,7 +587,7 @@ class Mail {
}

//Return as snake cased object
return toSnakeCase(json, ['substitutions', 'customArgs', 'headers']);
return toSnakeCase(json, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers']);
}

/**************************************************************************
Expand Down
114 changes: 114 additions & 0 deletions packages/helpers/classes/mail.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,118 @@ describe('Mail', function() {
.equal('<mailto:[email protected]>');
});
});
describe('#689', function() {

it('should detect dynamic template id', function() {
const mail = new Mail({
personalizations: [{
to: '[email protected]',
headers: {
'test-header': 'test',
},
}],
from: {
email: '[email protected]',
},
templateId: 'd-df80613cccc6441ea5cd7c95377bc1ef',
subject: 'test',
content: [{
type: 'text/plain',
value: 'test',
}],
});
expect(mail.isDynamic).to.equal(true);
});
it('should detect legacy template id', function() {
const mail = new Mail({
personalizations: [{
to: '[email protected]',
headers: {
'test-header': 'test',
},
}],
from: {
email: '[email protected]',
},
templateId: 'df80613cccc6441ea5cd7c95377bc1ef',
subject: 'test',
content: [{
type: 'text/plain',
value: 'test',
}],
});
expect(mail.isDynamic).to.equal(false);
});
it('should ignore substitutions if templateId is dynamic', function() {
const mail = new Mail({
personalizations: [{
to: '[email protected]',
headers: {
'test-header': 'test',
},
substitutions: {
test2: 'Test2',
},
dynamicTemplateData: {
test2: 'Testy 2',
test3: 'Testy 3',
},
}],
dynamicTemplateData: {
test1: 'Test 1',
test2: 'Test 2',
},
substitutions: {
test1: 'Test1',
},
from: {
email: '[email protected]',
},
templateId: 'd-df80613cccc6441ea5cd7c95377bc1ef',
subject: 'test',
content: [{
type: 'text/plain',
value: 'test',
}],
});
expect(mail.substitutions).to.equal(null);
expect(mail.personalizations[0].substitutions).to.deep.equal({});

expect(mail.dynamicTemplateData).to.deep.equal({ test1: 'Test 1', test2: 'Test 2' });
expect(mail.personalizations[0].dynamicTemplateData).to.deep.equal({ test1: 'Test 1', test2: 'Testy 2', test3: 'Testy 3' });

expect(mail.toJSON()).to.deep.equal({
'content': [
{
'type': 'text/plain',
'value': 'test',
},
],
'from': {
'email': '[email protected]',
},
'personalizations': [
{
'dynamic_template_data': {
'test1': 'Test 1',
'test2': 'Testy 2',
'test3': 'Testy 3',
},
'headers': {
'test-header': 'test',
},
'to': [
{
'email': '[email protected]',
'name': '',
},
],
},
],
'subject': 'test',
'template_id': 'd-df80613cccc6441ea5cd7c95377bc1ef',
});
});

});
});
Loading

0 comments on commit 15d9b0a

Please sign in to comment.