diff --git a/CHANGELOG.md b/CHANGELOG.md index 71df536115..6cab892532 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ __BREAKING CHANGES:__ ___ - IMPROVE: Optimize queries on classes with pointer permissions. [#7061](https://github.com/parse-community/parse-server/pull/7061). Thanks to [Pedro Diaz](https://github.com/pdiaz) - FIX: request.context for afterFind triggers. [#7078](https://github.com/parse-community/parse-server/pull/7078). Thanks to [dblythy](https://github.com/dblythy) +- NEW: Added convenience method Parse.Cloud.sendMail(...) to send email via mail adapter in Cloud Code. [#7089](https://github.com/parse-community/parse-server/pull/7089). Thanks to [dblythy](https://github.com/dblythy) ### 4.5.0 [Full Changelog](https://github.com/parse-community/parse-server/compare/4.4.0...4.5.0) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 9b95bbf8b0..7f0fe70aa0 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -3168,3 +3168,29 @@ describe('afterLogin hook', () => { await query.find({ context: { a: 'a' } }); }); }); + +describe('sendEmail', () => { + it('can send email via Parse.Cloud', async done => { + const emailAdapter = { + sendMail: mailData => { + expect(mailData).toBeDefined(); + expect(mailData.to).toBe('test'); + done(); + }, + }; + await reconfigureServer({ + emailAdapter: emailAdapter, + }); + const mailData = { to: 'test' }; + await Parse.Cloud.sendEmail(mailData); + }); + + it('cannot send email without adapter', async () => { + const logger = require('../lib/logger').logger; + spyOn(logger, 'error').and.callFake(() => {}); + await Parse.Cloud.sendEmail({}); + expect(logger.error).toHaveBeenCalledWith( + 'Failed to send email because no mail adapter is configured for Parse Server.' + ); + }); +}); diff --git a/src/cloud-code/Parse.Cloud.js b/src/cloud-code/Parse.Cloud.js index c04c48205e..80eead1f31 100644 --- a/src/cloud-code/Parse.Cloud.js +++ b/src/cloud-code/Parse.Cloud.js @@ -1,5 +1,6 @@ import { Parse } from 'parse/node'; import * as triggers from '../triggers'; +const Config = require('../Config'); function isParseObjectConstructor(object) { return typeof object === 'function' && Object.prototype.hasOwnProperty.call(object, 'className'); @@ -528,6 +529,37 @@ ParseCloud.beforeConnect = function (handler, validationHandler) { ); }; +/** + * Sends an email through the Parse Server mail adapter. + * + * **Available in Cloud Code only.** + * **Requires a mail adapter to be configured for Parse Server.** + * + * ``` + * Parse.Cloud.sendEmail({ + * from: 'Example ', + * to: 'contact@example.com', + * subject: 'Test email', + * text: 'This email is a test.' + * }); + *``` + * + * @method sendEmail + * @name Parse.Cloud.sendEmail + * @param {Object} data The object of the mail data to send. + */ +ParseCloud.sendEmail = function (data) { + const config = Config.get(Parse.applicationId); + const emailAdapter = config.userController.adapter; + if (!emailAdapter) { + config.loggerController.error( + 'Failed to send email because no mail adapter is configured for Parse Server.' + ); + return; + } + return emailAdapter.sendMail(data); +}; + /** * Registers a before live query subscription function. *