Accounts Password - Forgot Password

Is there a way to intervene and get the token and send the link through my own email function?

I’d like to send the forgot password e-mails through mailguns API so I can use their templates.

You could set your MAIL_URL setting to mailgun, so all your email goes via them

Hmm , But I don’t think there is a way I can utilize their templates then. I currently send e-mails through the API as such, So I was hoping to have a way to specify the link in the JSON data.

        let sendTo = Meteor.settings.NOTIFY_EMAIL
        let subject = `New Contact for ${Meteor.settings.SITE_NAME}: ${}`
        const mg = mailgun({apiKey: Meteor.settings.MAILGUN_API, domain: Meteor.settings.MAILGUN_DOMAIN});
        let data = {
            from: Meteor.settings.SERVER_EMAIL,
            to: sendTo,
            subject: subject,
            template: "newcontact-notification",
            'h:X-Mailgun-Variables': `${JSON.stringify(contact)}`
        mg.messages().send(data, function (error, body) {

In that case, you could replace the email package with your own implementation which uses the API instead.

Copy the email folder from the meteor repo into your project under /packages/email/ and then edit the code to use the API when Email.send is used

1 Like

That’s what I did, except I didnt copy the email package first, I just wrote my own Email.send() function which replaced the default function, and which uses the mailgun api.

1 Like

I’ve done this - a slightly different way to the above but perhaps overriding the Email.send might be a better approach? Not sure so I’ll post my solution in the hopes of a discussion.

My ‘Reset Password’ button, rather than using the Accounts Password built in helper function, calls my own method:

// Allow reset password email to be sent via Postmark
export const resetPassword = new ValidatedMethod({
	name: 'reset-password',
	validate: new SimpleSchema({
		email: String,
	run({ email }) {
    if ( !Meteor.isSimulation && Meteor.isServer ) {
      // This is a function that links to Postmark and sends out the reset password email
			const {
			} = require('../../helpers/server/emailNotifications');
			const user = Accounts.findUserByEmail(email);
			if (!user) {
				// TODO: Send an email here rather than throwing an error
				throw new Meteor.Error(
					`No user exists with this username`,
			// Create a password reset token
			// Reference 1:
			// Reference 2:
			const tokenRecord = {
				token: Random.secret(),
				when: new Date(),

				{ _id: user._id },
				{ $set: { 'services.password.reset': tokenRecord } },

			Meteor._ensure(user, 'services', 'password').reset = tokenRecord;

			// Send the email
			const resetUrl = Meteor.absoluteUrl(
				to: user.emails[0].address,
				vars: {
					// other data from the user object to personalise this

As per the comments, I relied heavily on these two references to write this function:

1 Like

In addition to overwriting the default Email.send() function, I should add that I also replace the Accounts.emailTemplates... functions with functions which return a mailgun template object instead of text.

I use one ‘generic’ template and change the title, message and button by using template variables. E.g.:

Accounts.emailTemplates.resetPassword.text = function (user, url) {
	return {
		title: "Forgot your password?",
		html: "It happens to the best of us. The good news is you can change it right now.",
		link: url,

Then, replace Email.send with…

const mailgun = require('mailgun-js')({
	apiKey: Meteor.settings.private.mailgun.apiKey,
	domain: Meteor.settings.private.mailgun.domain,

// overwrite default Email.send function which is used internally by the Accounts packages...
Email.send = function(options) {
  // use mailgun templates?
  if (typeof options.text=='object') {
    options.template = 'generic';
    options['h:X-Mailgun-Variables'] = JSON.stringify(options.text);
    delete options.text;