Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 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
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,38 @@ 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;
const 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', 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
44 changes: 44 additions & 0 deletions spec/ApiMailAdapter.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,50 @@ 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 single recipient payload', () => {
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 multiple recipients payload', () => {
const examplePayload = {
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: examplePayload});
expect(payload.from.address).toEqual(examplePayload.from);
expect(payload.to).toBeInstanceOf(Array);
const exmplePayloadToAddresses = examplePayload.to.split(',');
const toAddresses = payload.to.map(entry => entry.email_address.address);
exmplePayloadToAddresses.forEach((address, index) => {
expect(address).toBe(toAddresses[index]);
});
expect(payload.reply_to).toBeInstanceOf(Array);
const exmpleReplyToAddresses = examplePayload.replyTo.split(',').map(addr => addr.trim());
const replyToAddresses = payload.reply_to[0].address.split(',').map(addr => addr.trim());
exmpleReplyToAddresses.forEach((exampleAddress, index) => {
expect(replyToAddresses[index]).toBe(exampleAddress);
});
expect(payload.subject).toBe(examplePayload.subject);
expect(payload.textbody).toBe(examplePayload.text);
expect(payload.htmlbody).toBe(examplePayload.html);
});
});
});

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

/**
* @description Converts the mail payload for the official Mailgun client.
* @param {Object} originalPayload The original payload (provider agnostic).
* @param {Object} data The original payload (provider agnostic).
* @returns {Object} The payload according to Mailgun client specification.
*/
static mailgun(originalPayload) {
static mailgun(data) {

// Clone payload
const payload = Object.assign({}, originalPayload);
const payload = Object.assign({}, data);

// Transform reply-to
if (payload.replyTo) {
Expand All @@ -25,13 +25,13 @@

/**
* @description Converts the mail payload for the AWS Simple Mail Service (AWS JavaScript SDK v3).
* @param {Object} originalPayload The original payload (provider agnostic).
* @param {Object} data The original payload (provider agnostic).
* @returns {Object} The payload according to AWS SDK specification.
*/
static awsSes(originalPayload) {
static awsSes(data) {

// Clone payload
const payload = Object.assign({}, originalPayload);
const payload = Object.assign({}, data);

// Transform sender
payload.Source = [payload.from];
Expand Down Expand Up @@ -92,6 +92,62 @@

return payload;
}

/**
* Converts the mail payload for the ZeptoMail.
* @param {Object} data The original payload
* @param {String} data.api The provider API version.
* @param {Object} data.payload The payload to convert to be compatible with the provider API.
* @returns {Object} The payload according to ZeptoMail SDK specification.
*/
static zeptomail(data) {

// Clone payload
const payload = Object.assign({}, data.payload);
switch (data.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 '${ data.api }'.`);

Check warning on line 147 in src/ApiPayloadConverter.js

View check run for this annotation

Codecov / codecov/patch

src/ApiPayloadConverter.js#L147

Added line #L147 was not covered by tests
}
return payload;
}
}

module.exports = ApiPayloadConverter;
Loading