diff --git a/docs/use-cases/README.md b/docs/use-cases/README.md index e350d0d54..cb66faae4 100644 --- a/docs/use-cases/README.md +++ b/docs/use-cases/README.md @@ -4,6 +4,7 @@ This documentation provides examples for specific Twilio SendGrid v3 API use cas * [Send a Single Email to a Single Recipient](single-email-single-recipient.md) * [Send a Single Email to Multiple Recipients](single-email-multiple-recipients.md) * [Send Multiple Emails to Multiple Recipients](multiple-emails-multiple-recipients.md) +* [Send Multiple Emails with Personalizations](multiple-emails-personalizations.md) * [CC, BCC and Reply To](cc-bcc-reply-to.md) * [Flexible Email Address Fields](flexible-address-fields.md) * [Handling Success/Failure/Errors](success-failure-errors.md) diff --git a/docs/use-cases/multiple-emails-personalizations.md b/docs/use-cases/multiple-emails-personalizations.md new file mode 100644 index 000000000..7a45dd03f --- /dev/null +++ b/docs/use-cases/multiple-emails-personalizations.md @@ -0,0 +1,39 @@ +# Send Multiple Emails with Personalizations + +Personalizations are an array of objects, each representing a separate email, that allow you to customize the metadata of each email sent within a request. The below example shows how multiple emails, each with varying metadata, are sent with personalizations. + +Refer to [the Sendgrid documentation](https://docs.sendgrid.com/for-developers/sending-email/personalizations) for more details about personalizations. +```js +const sgMail = require('@sendgrid/mail'); +const sgHelpers = require('@sendgrid/helpers'); +const Personalization = sgHelpers.classes.Personalization; + +sgMail.setApiKey(process.env.SENDGRID_API_KEY); +const msg = { + from: 'sender1@example.org', + subject: 'Hello world', + text: 'Hello plain world!', + html: '

Hello HTML world!

', + personalizations: [] +}; + +const personalization1 = new Personalization(); +personalization1.setTo(['recipient2@example.org', 'recipient3@example.org']); +personalization1.setCc('recipient4@example.org'); +msg.personalizations.push(personalization1); + +const personalization2 = new Personalization(); +personalization2.setTo(['recipient5@example.org', 'recipient6@example.org', 'recipient7@example.org']); +personalization2.setFrom('sender2@example.org'); +personalization2.setCc('recipient8@example.org'); +msg.personalizations.push(personalization2); + +const personalization3 = new Personalization(); +personalization3.setTo('recipient9@example.org'); +personalization3.setFrom('sender3@example.org'); +personalization3.setCc('recipient10@example.org'); +personalization3.setSubject('Greetings world'); +msg.personalizations.push(personalization3); + +sgMail.send(msg); +``` diff --git a/packages/helpers/classes/personalization.d.ts b/packages/helpers/classes/personalization.d.ts index f90a59bab..43163abf9 100644 --- a/packages/helpers/classes/personalization.d.ts +++ b/packages/helpers/classes/personalization.d.ts @@ -2,6 +2,7 @@ import { EmailData, EmailJSON } from "./email-address"; export interface PersonalizationData { to: EmailData | EmailData[], + from?: EmailData, cc?: EmailData | EmailData[], bcc?: EmailData | EmailData[], subject?: string; @@ -14,6 +15,7 @@ export interface PersonalizationData { export interface PersonalizationJSON { to: EmailJSON | EmailJSON[]; + from?: EmailJSON; cc?: EmailJSON[]; bcc?: EmailJSON[]; headers?: { [key: string]: string; }; @@ -44,6 +46,11 @@ export default class Personalization { */ setTo(to: EmailData | EmailData[]): void; + /** + * Set from + */ + setFrom(from: EmailData): void; + /** * Add a single to */ diff --git a/packages/helpers/classes/personalization.js b/packages/helpers/classes/personalization.js index e90ee2b8a..188113b31 100644 --- a/packages/helpers/classes/personalization.js +++ b/packages/helpers/classes/personalization.js @@ -53,12 +53,13 @@ class Personalization { //Extract properties from data const { - to, cc, bcc, subject, headers, customArgs, sendAt, + to, from, cc, bcc, subject, headers, customArgs, sendAt, substitutions, substitutionWrappers, dynamicTemplateData, } = data; //Set data this.setTo(to); + this.setFrom(from); this.setCc(cc); this.setBcc(bcc); this.setSubject(subject); @@ -109,6 +110,16 @@ class Personalization { this.to = EmailAddress.create(to); } + /** + * Set from + * */ + setFrom(from) { + if (typeof from === 'undefined') { + return; + } + this.from = EmailAddress.create(from); + } + /** * Add a single to */ @@ -309,7 +320,7 @@ class Personalization { //Get data from self const { - to, cc, bcc, subject, headers, customArgs, sendAt, + to, from, cc, bcc, subject, headers, customArgs, sendAt, substitutions, substitutionWrappers, dynamicTemplateData, } = this; @@ -347,6 +358,9 @@ class Personalization { if (typeof sendAt !== 'undefined') { json.sendAt = sendAt; } + if (typeof from !== 'undefined') { + json.from = from; + } //Return as snake cased object return toSnakeCase(json, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers']); diff --git a/packages/helpers/classes/personalization_specs/PERSONALIZATION-SPECS-README.md b/packages/helpers/classes/personalization_specs/PERSONALIZATION-SPECS-README.md index 0e71bfb58..0a104a62d 100644 --- a/packages/helpers/classes/personalization_specs/PERSONALIZATION-SPECS-README.md +++ b/packages/helpers/classes/personalization_specs/PERSONALIZATION-SPECS-README.md @@ -3,6 +3,7 @@ - setSubject() - set-subject.spec.js - setSendAt() - set-send-at.spec.js - setTo() - set-to.spec.js +- setFrom() - set-from.spec.js - addTo() - add-to.spec.js - setCc() - set-cc.spec.js - addCc() - add-cc.spec.js diff --git a/packages/helpers/classes/personalization_specs/from-data.spec.js b/packages/helpers/classes/personalization_specs/from-data.spec.js index 6d1a500f6..c2d186669 100644 --- a/packages/helpers/classes/personalization_specs/from-data.spec.js +++ b/packages/helpers/classes/personalization_specs/from-data.spec.js @@ -23,6 +23,7 @@ describe('Personalization', function() { //Data const data = { to: 'to@example.org', + from: 'from@example.org', cc: ['cc1@example.org', 'cc2@example.org'], bcc: ['bcc1@example.org', 'bcc2@example.org'], subject: 'Test', @@ -47,6 +48,7 @@ describe('Personalization', function() { it('should have set all properties', () => { p.fromData(data); expect(p.to[0].email).to.equal('to@example.org'); + expect(p.from.email).to.equal('from@example.org'); expect(p.cc[0].email).to.equal('cc1@example.org'); expect(p.cc[1].email).to.equal('cc2@example.org'); expect(p.bcc[0].email).to.equal('bcc1@example.org'); diff --git a/packages/helpers/classes/personalization_specs/set-from.spec.js b/packages/helpers/classes/personalization_specs/set-from.spec.js new file mode 100644 index 000000000..1fc3f0d17 --- /dev/null +++ b/packages/helpers/classes/personalization_specs/set-from.spec.js @@ -0,0 +1,45 @@ +'use strict'; + +/** + * Dependencies + */ +const Personalization = require('../personalization'); +const EmailAddress = require('../email-address'); + +/** + * Tests + */ +describe('Personalization', function() { + + //Create new personalization before each test + let p; + beforeEach(function() { + p = new Personalization(); + }); + + //Set from + describe('setFrom()', function() { + it('should accept string values', function() { + p.setFrom('test@example.org'); + expect(p.from).to.be.an.instanceof(EmailAddress); + expect(p.from.email).to.equal('test@example.org'); + }); + it('should properly update from value', function() { + p.setFrom('test1@example.com'); + p.setFrom('test2@example.com'); + p.setFrom('test3@example.com'); + p.setFrom('test4@example.com'); + expect(p.from.email).to.equal('test4@example.com'); + }); + it('should accept no input', function() { + expect(function() { + p.setFrom(); + }).not.to.throw(Error); + }); + it('should not overwrite value with no input', function() { + p.setFrom('test@example.org'); + p.setFrom(); + expect(p.from.email).to.equal('test@example.org'); + }); + }); +}); diff --git a/packages/helpers/classes/personalization_specs/to-json.spec.js b/packages/helpers/classes/personalization_specs/to-json.spec.js index 1bab9a5da..25811285f 100644 --- a/packages/helpers/classes/personalization_specs/to-json.spec.js +++ b/packages/helpers/classes/personalization_specs/to-json.spec.js @@ -31,6 +31,13 @@ describe('Personalization', function() { expect(json.to[0]).to.be.an.instanceof(EmailAddress); expect(json.to[0].email).to.equal('test@example.org'); }); + it('should set the from field', function() { + p.setFrom('testfrom@example.org'); + const json = p.toJSON(); + expect(json).to.have.property('from'); + expect(json.from).to.be.an.instanceof(EmailAddress); + expect(json.from.email).to.equal('testfrom@example.org'); + }); it('should set the cc field', function() { p.setCc('testcc@example.org'); const json = p.toJSON(); diff --git a/test/typescript/helpers.ts b/test/typescript/helpers.ts index d280ff8fe..b39aaff93 100644 --- a/test/typescript/helpers.ts +++ b/test/typescript/helpers.ts @@ -10,6 +10,7 @@ new helpers.classes.EmailAddress({ name: "Some One", email: "someone@example.org new helpers.classes.Personalization({ to: "someone@example.org", + from: "somebody@example.org", subject: "Hello Some One", dynamicTemplateData: { translations: {