Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,39 @@ const server = new ParseServer({
});
```

### Example for ZeptoMail Service

This is an example for the ZeptoMail Service client using the ZeptoMail JavaScript SDK.
Provide comma separated email adddresses in recepient parameter to send to multiple.

```js
// Configure mail client
var { SendMailClient } = require('zeptomail');

const url = process.env.ZEPTOMAIL_URL;
const token = process.env.ZEPTOMAIL_TOKEN;
let zeptoMaiClient = new SendMailClient({url, token});


// Configure Parse Server
const server = new ParseServer({
...otherServerOptions,

emailAdapter: {
module: 'parse-server-api-mail-adapter',
options: {
... otherAdapterOptions,

apiCallback: async ({ payload, locale }) => {
const zeptoMailPayload = ApiPayloadConverter.zeptomail({api: '1.1', originalPayload: payload});
await zeptoMaiClient.sendMail(zeptoMailPayload);
},
}
}
});
```


## Custom API

This is an example of how the API payload can be adapted in the adapter configuration `apiCallback` according to a custom email provider's API specification.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"madge:circular": "npm run madge --arg=--circular",
"test": "nyc --reporter=lcov jasmine",
"posttest": "nyc report --reporter=json && codecov -f coverage/*.json",
"prepare": "npm run build && npm test",
"prepare": "npm run build && nopm test",
"demo": "node ./demo"
}
}
43 changes: 43 additions & 0 deletions spec/ApiMailAdapter.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,49 @@ describe('ApiMailAdapter', () => {
expect(payload.Message.Body.Text.Data).toBe(examplePayload.text);
expect(payload.Message.Body.Html.Data).toBe(examplePayload.html);
});

describe('convert ZeptoMail API v1.1 payload', () => {
it('converts payload for ZeptoMail for single recepient', () => {
const payload = converter.zeptomail({api: '1.1',payload: examplePayload});
expect(payload.from.address).toEqual(examplePayload.from);
expect(payload.to).toBeInstanceOf(Array);
expect(payload.to.length).toBe(1);
expect(payload.to[0].email_address.address).toEqual(examplePayload.to);
expect(payload.reply_to).toBeInstanceOf(Array);
expect(payload.reply_to.length).toBe(1);
expect(payload.reply_to[0].address).toEqual(examplePayload.replyTo);
expect(payload.subject).toBe(examplePayload.subject);
expect(payload.textbody).toBe(examplePayload.text);
expect(payload.htmlbody).toBe(examplePayload.html);
});

it('converts payload for ZeptoMail for multiple recepients', () => {
const multipleRecepientExamplePayload = {
from: "[email protected]",
to: "[email protected],[email protected]",
replyTo: "[email protected], [email protected]",
subject: "ExampleSubject",
text: "ExampleText",
html: "ExampleHtml"
}
const payload = converter.zeptomail({api: '1.1',payload: multipleRecepientExamplePayload});
expect(payload.from.address).toEqual(multipleRecepientExamplePayload.from);
expect(payload.to).toBeInstanceOf(Array);
const toAddresses = payload.to.map(entry => entry.email_address.address);
payload.to.forEach((entry, index) => {
expect(entry.email_address.address).toBe(toAddresses[index]);
});
expect(payload.reply_to).toBeInstanceOf(Array);
const replyToAddresses = payload.reply_to[0].address.split(',').map(addr => addr.trim());
const [firstAddress, secondAddress] = replyToAddresses;
expect(replyToAddresses).toContain(firstAddress);
expect(replyToAddresses).toContain(secondAddress);
expect(payload.subject).toBe(multipleRecepientExamplePayload.subject);
expect(payload.textbody).toBe(multipleRecepientExamplePayload.text);
expect(payload.htmlbody).toBe(multipleRecepientExamplePayload.html);
});
});

});

describe('invoke _sendMail', function () {
Expand Down
53 changes: 53 additions & 0 deletions src/ApiPayloadConverter.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,59 @@ class ApiPayloadConverter {

return payload;
}

/**
* @description Converts the mail payload for the ZeptoMail.
* @param {Object} originalPayload The original payload (provider agnostic). originalPayload has two components 1. api and 2. payload.
* @returns {Object} The payload according to ZeptoMail SDK specification.
*/
static zeptomail(originalPayload) {

// Clone payload
const payload = Object.assign({}, originalPayload.payload);
switch (originalPayload.api) {
case '1.1':

// Transform sender
payload.from = {
address: payload.from
}
const emailString = payload.to;
const emailAddresses = emailString.split(',').map(email => email.trim());
const formattedEmails = emailAddresses.map((address) => ({
email_address: {
address: address.trim()
}
}));
payload.to = formattedEmails
if (payload.replyTo) {
payload.reply_to = [{
address: payload.replyTo
}
];
delete payload.replyTo;
}

// If message has content
if (payload.subject || payload.textbody || payload.htmlbody) {
if (payload.text || payload.html) {
payload.textbody = {};
if (payload.text) {
payload.textbody = payload.text,
delete payload.text;
}
if (payload.html) {
payload.htmlbody = payload.html
delete payload.html;
}
}
}
break;
default:
throw new Error('Unsupported ZeptoMail API version');
}
return payload;
}
}

module.exports = ApiPayloadConverter;
Loading