-
Notifications
You must be signed in to change notification settings - Fork 780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for dynamicTemplateData #691
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ class Mail { | |
constructor(data) { | ||
|
||
//Initialize array and object properties | ||
this._isDynamic = false; | ||
this.personalizations = []; | ||
this.attachments = []; | ||
this.content = []; | ||
|
@@ -35,6 +36,7 @@ class Mail { | |
//Helper properties | ||
this.substitutions = null; | ||
this.substitutionWrappers = null; | ||
this.dynamicTemplateData = null; | ||
|
||
//Process data if given | ||
if (data) { | ||
|
@@ -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 | ||
|
@@ -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); | ||
|
@@ -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') { | ||
|
@@ -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; | ||
} | ||
|
||
|
@@ -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); | ||
} | ||
|
||
|
@@ -247,7 +273,7 @@ class Mail { | |
) { | ||
throw new Error('Provide at least one of to, cc or bcc'); | ||
} | ||
this.addPersonalization(new Personalization({to, cc, bcc})); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code style in this package doesn't use leading/trailing spaces after/before curly brackets, could you revert this change? |
||
this.addPersonalization(new Personalization({ to, cc, bcc })); | ||
} | ||
|
||
/** | ||
|
@@ -288,6 +314,28 @@ class Mail { | |
} | ||
} | ||
|
||
/** | ||
* Helper which applies globally set dynamic_template_data to personalizations | ||
*/ | ||
applyDynamicTemplateData(personalization) { | ||
if (personalization instanceof Personalization) { | ||
personalization.reverseMergeDynamicTemplateData(this.dynamicTemplateData); | ||
} | ||
} | ||
|
||
/** | ||
* Set substitutions | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix comment to avoid confusion |
||
*/ | ||
setDynamicTemplateData(dynamicTemplateData) { | ||
if (typeof dynamicTemplateData === 'undefined') { | ||
return; | ||
} | ||
if (typeof dynamicTemplateData !== 'object') { | ||
throw new Error('Object expected for `dynamicTemplateData`'); | ||
} | ||
this.dynamicTemplateData = dynamicTemplateData; | ||
} | ||
|
||
/** | ||
* Set content | ||
*/ | ||
|
@@ -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; | ||
|
@@ -539,7 +587,7 @@ class Mail { | |
} | ||
|
||
//Return as snake cased object | ||
return toSnakeCase(json, ['substitutions', 'customArgs', 'headers']); | ||
return toSnakeCase(json, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers']); | ||
} | ||
|
||
/************************************************************************** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,10 +8,10 @@ const Mail = require('./mail'); | |
/** | ||
* Tests | ||
*/ | ||
describe('Mail', function() { | ||
describe('Mail', function () { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you also undo these style corrections? Please respect the code style as indicated by the editor config and eslint config. If you enable ESLint in your editor it should automatically fix these issues. |
||
|
||
describe('#527', function() { | ||
it('shouldn\'t convert the headers to camel/snake case', function() { | ||
describe('#527', function () { | ||
it('shouldn\'t convert the headers to camel/snake case', function () { | ||
const mail = new Mail({ | ||
personalizations: [{ | ||
to: 'test@example.com', | ||
|
@@ -40,4 +40,118 @@ describe('Mail', function() { | |
.equal('<mailto:test@test.com>'); | ||
}); | ||
}); | ||
describe('#689', function () { | ||
|
||
it('should detect dynamic template id', function () { | ||
const mail = new Mail({ | ||
personalizations: [{ | ||
to: 'test@example.com', | ||
headers: { | ||
'test-header': 'test', | ||
}, | ||
}], | ||
from: { | ||
email: 'test@example.com', | ||
}, | ||
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: 'test@example.com', | ||
headers: { | ||
'test-header': 'test', | ||
}, | ||
}], | ||
from: { | ||
email: 'test@example.com', | ||
}, | ||
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: 'test@example.com', | ||
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: 'test@example.com', | ||
}, | ||
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": "test@example.com" | ||
}, | ||
"personalizations": [ | ||
{ | ||
"dynamic_template_data": { | ||
"test1": "Test 1", | ||
"test2": "Testy 2", | ||
"test3": "Testy 3" | ||
}, | ||
"headers": { | ||
"test-header": "test" | ||
}, | ||
"to": [ | ||
{ | ||
"email": "test@example.com", | ||
"name": "" | ||
} | ||
] | ||
} | ||
], | ||
"subject": "test", | ||
"template_id": "d-df80613cccc6441ea5cd7c95377bc1ef" | ||
}); | ||
}); | ||
|
||
}) | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking just us
this.isDynamic
for the flag, e.g. without the underscore.