Skip to content

Commit 8a1d3e2

Browse files
committed
added locale
1 parent 429c1ec commit 8a1d3e2

File tree

4 files changed

+58
-38
lines changed

4 files changed

+58
-38
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[Full Changelog](https://github.com/mtrezza/parse-server-api-mail-adapter/compare/1.0.0...master)
55

66
- FIX: Removed unused config parameter from docs. [#1](https://github.com/mtrezza/parse-server-api-mail-adapter/pull/1). Thanks to [mtrezza](https://github.com/mtrezza)
7+
- NEW: Added locale to API callback. [#2](https://github.com/mtrezza/parse-server-api-mail-adapter/pull/2). Thanks to [mtrezza](https://github.com/mtrezza)
78

89
### 1.0.0
910
- NEW: Initial commit.

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,12 @@ const server = new ParseServer({
9898
}
9999
}
100100
},
101-
// The asynronous callback that contains the composed email payload to be passed on to an 3rd party API. The payload may need to be convert specifically for the API; conversion for common APIs is conveniently available in the `ApiPayloadConverter`. Below is an example for the Mailgun client.
102-
apiCallback: async (payload) => {
101+
// The asynronous callback that contains the composed email payload to
102+
// be passed on to an 3rd party API and optional meta data. The payload
103+
// may need to be converted specifically for the API; conversion for
104+
// common APIs is conveniently available in the `ApiPayloadConverter`.
105+
// Below is an example for the Mailgun client.
106+
apiCallback: async ({ payload, locale }) => {
103107
const mailgunPayload = ApiPayloadConverter.mailgun(payload);
104108
await mailgunClient.messages.create(mailgunDomain, mailgunPayload);
105109
}

spec/ApiMailAdapter.spec.js

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ describe('ApiMailAdapter', () => {
147147

148148
await adapter.sendPasswordResetEmail(options);
149149
expect(_sendMail.calls.all()[0].args[0]).toEqual(expectedArguments);
150-
expect(apiCallback.calls.all()[0].args[0].from).toEqual(config.sender);
151-
expect(apiCallback.calls.all()[0].args[0].to).toEqual(user.get('email'));
152-
expect(apiCallback.calls.all()[0].args[0].subject).toMatch("Reset");
153-
expect(apiCallback.calls.all()[0].args[0].text).toMatch("reset");
154-
expect(apiCallback.calls.all()[0].args[0].html).toMatch("reset");
150+
expect(apiCallback.calls.all()[0].args[0].payload.from).toEqual(config.sender);
151+
expect(apiCallback.calls.all()[0].args[0].payload.to).toEqual(user.get('email'));
152+
expect(apiCallback.calls.all()[0].args[0].payload.subject).toMatch("Reset");
153+
expect(apiCallback.calls.all()[0].args[0].payload.text).toMatch("reset");
154+
expect(apiCallback.calls.all()[0].args[0].payload.html).toMatch("reset");
155155
});
156156
});
157157

@@ -175,11 +175,11 @@ describe('ApiMailAdapter', () => {
175175

176176
await adapter.sendVerificationEmail(options);
177177
expect(_sendMail.calls.all()[0].args[0]).toEqual(expectedArguments);
178-
expect(apiCallback.calls.all()[0].args[0].from).toEqual(config.sender);
179-
expect(apiCallback.calls.all()[0].args[0].to).toEqual(user.get('email'));
180-
expect(apiCallback.calls.all()[0].args[0].subject).toMatch("Verification");
181-
expect(apiCallback.calls.all()[0].args[0].text).toMatch("verify");
182-
expect(apiCallback.calls.all()[0].args[0].html).toMatch("verify");
178+
expect(apiCallback.calls.all()[0].args[0].payload.from).toEqual(config.sender);
179+
expect(apiCallback.calls.all()[0].args[0].payload.to).toEqual(user.get('email'));
180+
expect(apiCallback.calls.all()[0].args[0].payload.subject).toMatch("Verification");
181+
expect(apiCallback.calls.all()[0].args[0].payload.text).toMatch("verify");
182+
expect(apiCallback.calls.all()[0].args[0].payload.html).toMatch("verify");
183183
});
184184
});
185185

@@ -216,7 +216,7 @@ describe('ApiMailAdapter', () => {
216216
it('creates payload with correct properties', async () => {
217217
const adapter = new ApiMailAdapter(config);
218218
spyOn(adapter, 'apiCallback').and.callFake(apiResponseSuccess);
219-
const _createPayload = spyOn(adapter, '_createPayload').and.callThrough();
219+
const _createApiData = spyOn(adapter, '_createApiData').and.callThrough();
220220
const options = {
221221
sender: config.sender,
222222
recipient: '[email protected]',
@@ -235,7 +235,7 @@ describe('ApiMailAdapter', () => {
235235

236236
await expectAsync(adapter.sendMail(options)).toBeResolved();
237237

238-
const payload = (await _createPayload.calls.all()[0].returnValue);
238+
const { payload } = (await _createApiData.calls.all()[0].returnValue);
239239
expect(payload.from).toMatch(options.sender);
240240
expect(payload.to).toMatch(options.recipient);
241241
expect(payload.subject).toMatch(options.subject);
@@ -247,7 +247,7 @@ describe('ApiMailAdapter', () => {
247247
it('creates payload with correct properties when overriding extras', async () => {
248248
const adapter = new ApiMailAdapter(config);
249249
spyOn(adapter, 'apiCallback').and.callFake(apiResponseSuccess);
250-
const _createPayload = spyOn(adapter, '_createPayload').and.callThrough();
250+
const _createApiData = spyOn(adapter, '_createApiData').and.callThrough();
251251
const options = {
252252
sender: config.sender,
253253
recipient: '[email protected]',
@@ -266,7 +266,7 @@ describe('ApiMailAdapter', () => {
266266

267267
await expectAsync(adapter.sendMail(options)).toBeResolved();
268268

269-
const payload = (await _createPayload.calls.all()[0].returnValue);
269+
const { payload } = (await _createApiData.calls.all()[0].returnValue);
270270
expect(payload.from).toMatch(options.sender);
271271
expect(payload.to).toMatch(options.recipient);
272272
expect(payload.subject).toMatch(options.subject);
@@ -349,7 +349,7 @@ describe('ApiMailAdapter', () => {
349349
const _loadFile = spyOn(adapter, '_loadFile').and.callThrough();
350350
const options = { message: {}, template: config.templates.customEmail };
351351

352-
await adapter._createPayload(options);
352+
await adapter._createApiData(options);
353353
const subjectFileData = await fs.readFile(options.template.subjectPath);
354354
const textFileData = await fs.readFile(options.template.textPath);
355355
const htmlFileData = await fs.readFile(options.template.htmlPath);
@@ -371,7 +371,7 @@ describe('ApiMailAdapter', () => {
371371
placeholders: { appName: 'ExampleApp' }
372372
};
373373

374-
await adapter._createPayload(options);
374+
await adapter._createApiData(options);
375375

376376
expect(_fillPlaceholders.calls.all()[0].args[0]).not.toContain('ExampleApp');
377377
expect(_fillPlaceholders.calls.all()[1].args[0]).not.toContain('ExampleApp');
@@ -418,10 +418,11 @@ describe('ApiMailAdapter', () => {
418418
describe('localization', () => {
419419
let adapter;
420420
let options;
421+
let apiCallback;
421422

422423
beforeEach(async () => {
423424
adapter = new ApiMailAdapter(config);
424-
spyOn(adapter, 'apiCallback').and.callFake(apiResponseSuccess);
425+
apiCallback = spyOn(adapter, 'apiCallback').and.callFake(apiResponseSuccess);
425426

426427
options = {
427428
message: {},
@@ -432,7 +433,7 @@ describe('ApiMailAdapter', () => {
432433

433434
it('uses user locale variable from user locale callback', async () => {
434435
const _loadFile = spyOn(adapter, '_loadFile').and.callThrough();
435-
await adapter._createPayload(options);
436+
await adapter._createApiData(options);
436437

437438
const subjectFileData = await fs.readFile(path.join(__dirname, 'templates/de-AT/custom_email_subject.txt'));
438439
const textFileData = await fs.readFile(path.join(__dirname, 'templates/de-AT/custom_email.txt'));
@@ -452,7 +453,7 @@ describe('ApiMailAdapter', () => {
452453
return !/\/templates\/de-AT\//.test(path);
453454
});
454455
const _loadFile = spyOn(adapter, '_loadFile').and.callThrough();
455-
await adapter._createPayload(options);
456+
await adapter._createApiData(options);
456457

457458
const subjectFileData = await fs.readFile(path.join(__dirname, 'templates/de/custom_email_subject.txt'));
458459
const textFileData = await fs.readFile(path.join(__dirname, 'templates/de/custom_email.txt'));
@@ -472,7 +473,7 @@ describe('ApiMailAdapter', () => {
472473
return !/\/templates\/de(-AT)?\//.test(path);
473474
});
474475
const _loadFile = spyOn(adapter, '_loadFile').and.callThrough();
475-
await adapter._createPayload(options);
476+
await adapter._createApiData(options);
476477

477478
const subjectFileData = await fs.readFile(path.join(__dirname, 'templates/custom_email_subject.txt'));
478479
const textFileData = await fs.readFile(path.join(__dirname, 'templates/custom_email.txt'));
@@ -485,5 +486,16 @@ describe('ApiMailAdapter', () => {
485486
expect(textSpyData.toString('utf8')).toEqual(textFileData.toString('utf8'));
486487
expect(htmlSpyData.toString('utf8')).toEqual(htmlFileData.toString('utf8'));
487488
});
489+
490+
it('makes user locale available in API callback', async () => {
491+
const locale = await options.template.localeCallback();
492+
const email = {
493+
templateName: 'customEmailWithLocaleCallback',
494+
recipient: '[email protected]',
495+
direct: true
496+
}
497+
await adapter._sendMail(email);
498+
expect(apiCallback.calls.all()[0].args[0].locale).toContain(locale);
499+
});
488500
});
489501
});

src/ApiMailAdapter.js

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -182,34 +182,37 @@ class ApiMailAdapter extends MailAdapter {
182182
};
183183
}
184184

185-
// Compose email
186-
const payload = await this._createPayload({ message, template, placeholders, user });
185+
// Create API data
186+
const apiData = await this._createApiData({ message, template, placeholders, user });
187187

188188
// Send email
189-
return await this.apiCallback(payload);
189+
return await this.apiCallback(apiData);
190190
}
191191

192192
/**
193-
* @typedef {Object} CreatePayloadResponse
194-
* @property {String} from The sender email address.
195-
* @property {String} to The recipient email address.
196-
* @property {String} replyTo The reply-to address.
197-
* @property {String} subject The subject.
198-
* @property {String} text The plain-text content.
199-
* @property {String} html The HTML content.
200-
* @property {String} message The MIME content.
193+
* @typedef {Object} CreateApiDataResponse
194+
* @property {Object} payload The generic API payload.
195+
* @property {String} payload.from The sender email address.
196+
* @property {String} payload.to The recipient email address.
197+
* @property {String} payload.replyTo The reply-to address.
198+
* @property {String} payload.subject The subject.
199+
* @property {String} payload.text The plain-text content.
200+
* @property {String} payload.html The HTML content.
201+
* @property {String} payload.message The MIME content.
202+
* @property {String} [locale] The user locale, if it has been determined via the
203+
* locale callback.
201204
*/
202205
/**
203-
* @function _createPayload
204-
* @description Creates the API payload.
206+
* @function _createApiData
207+
* @description Creates the API data, includes the payload and optional meta data.
205208
* @param {Object} options The payload options.
206209
* @param {Object} options.message The message to send.
207210
* @param {Object} options.template The email template to use.
208211
* @param {Object} [options.placeholders] The email template placeholders.
209212
* @param {Object} [options.user] The Parse User who is the email recipient.
210-
* @returns {Promise<CreatePayloadResponse>} The generic API payload.
213+
* @returns {Promise<CreateApiDataResponse>} The API data.
211214
*/
212-
async _createPayload(options) {
215+
async _createApiData(options) {
213216
let { message } = options;
214217
const { template, user, placeholders={} } = options;
215218
const { placeholderCallback, localeCallback } = template;
@@ -293,7 +296,7 @@ class ApiMailAdapter extends MailAdapter {
293296
payload.replyTo = message.replyTo;
294297
}
295298

296-
return payload;
299+
return { payload, locale };
297300
}
298301

299302
/**

0 commit comments

Comments
 (0)