3

I use parse-server-amazon-ses-email-adapter and would like to know how to localize the verification email and reset password email.

My clue is to check user's fields and then assign the correct template on server.js or AmazonSESAdapter.js. The problem is that user properties are empty, besides email, username.

For instance, at the example below, firstName is undefined.

Thanks.

emailAdapter: {
      module: 'parse-server-amazon-ses-email-adapter',
      options: {
        // The address that your emails come from
        fromAddress: 'Iron rr',
        accessKeyId: 'gg',
        secretAccessKey: 'gg',
        region: 'eu-west-1',
        // The template section
        templates: {
          passwordResetEmail: {
            subject: 'Redefinir sua senha Iron Trainers',
            pathPlainText: '/opt/bitnami/apps/parse/htdocs/node_modules/parse-server/node_modules/parse-server-amazon-ses-email-adapter/test/email-templates/password_reset_email.txt',
            pathHtml: '/opt/bitnami/apps/parse/htdocs/node_modules/parse-server/node_modules/parse-server-amazon-ses-email-adapter/test/email-templates/password_reset_email.html',
            callback: (user) => {
                return {
                  firstName: user.get('firstName')
                }
              }
              // Now you can use {{firstName}} in your templates
          },
          verificationEmail: {
            subject: 'Confirmar email no Iron Trainers',
            pathPlainText: '/opt/bitnami/apps/parse/htdocs/node_modules/parse-server/node_modules/parse-server-amazon-ses-email-adapter/test/email-templates/verification_email.txt',
            pathHtml: '/opt/bitnami/apps/parse/htdocs/node_modules/parse-server/node_modules/parse-server-amazon-ses-email-adapter/test/email-templates/resendEmailVerification.html',
            callback: (user) => {
                return {
                  firstName: user.get('firstName')
                }
              }
              // Now you can use {{firstName}} in your templates
          },
          customEmailAlert: {
            subject: 'Urgent notification!',
            pathPlainText: '/opt/bitnami/apps/parse/htdocs/node_modules/parse-server/node_modules/parse-server-amazon-ses-email-adapter/test/email-templates/custom_alert.txt',
            pathHtml: '/opt/bitnami/apps/parse/htdocs/node_modules/parse-server/node_modules/parse-server-amazon-ses-email-adapter/test/email-templates/custom_alert.html',
          }
        }
8
  • By localize you mean en, eu language type localization or something else? Commented Apr 27, 2018 at 5:41
  • yes, language translation. Thanks. Commented Apr 27, 2018 at 5:49
  • Can you post the server.js too? Commented Apr 27, 2018 at 6:50
  • this above code is from server.js, I can also post the complete file/code. Commented Apr 27, 2018 at 7:14
  • Yeah do a pastebin of the same, remove any confidential info. Commented Apr 27, 2018 at 7:18

2 Answers 2

2

As per my understanding this can be done but through a code change in the plugin.

There is a if-else condition at below line in code

https://github.com/ecohealthalliance/parse-server-amazon-ses-email-adapter/blob/0bce9b6c81681c3829a17b208d839d23c846ab05/src/AmazonSESAdapter.js#L90

Since you have not provided any feedback and I have not way to setup this, I have assume that the else part is what gets executed

  const {
    link,
    appName,
    user,
    templateConfig
  } = options;
  const {
    callback
  } = templateConfig;
  let userVars;

  if (callback && typeof callback === 'function') {
    userVars = callback(user);
    // If custom user variables are not packaged in an object, ignore it
    const validUserVars = userVars && userVars.constructor && userVars.constructor.name === 'Object';
    userVars = validUserVars ? userVars : {};
  }

  pathPlainText = templateConfig.pathPlainText;
  pathHtml = templateConfig.pathHtml;

  templateVars = Object.assign({
    link,
    appName,
    username: user.get('username'),
    email: user.get('email')
  }, userVars);

  message = {
    from: this.fromAddress,
    to: user.get('email'),
    subject: templateConfig.subject
  };
}

Now in this part, 2 lines decide the template to be used

pathPlainText = templateConfig.pathPlainText;
pathHtml = templateConfig.pathHtml;

By this time, the callback you have provided has been called. Now in the callback you can set a variable, let assume it is name locale. So you can update the code like below

pathPlainText = templateConfig.pathPlainText + (userVars["locale"] || "en");
pathHtml = templateConfig.pathHtml + (userVars["locale"] || "en");

And then you will create templates which have the locale in the file path and with updated code the correct template will be picked.

You can also look at @bgran answer, at first look I do believe that should work as well

Sign up to request clarification or add additional context in comments.

4 Comments

This will definitely work, but you'll need to fork parse-server-amazon-ses-email-adapter if you want to use it. The answer below will work with the existing parse-server-amazon-ses-email-adapter.
Yes, totally agreed and highlighted in my last line as well
@TarunLalwani, thanks a lot, this works perfectly. Although, I have one more question... how could I access another parse class in the callback, not only the user object? thanks.
It hard to say because if it in an object in a scope which you can't control it would be tough. Also a class and instance are two different things. If you want to use class you can just required it but if you need an instance then you will need to make code modification and see how they can shared between the two scopes
2

You'll need to do your localization in the template callback.

The callback is synchronous, so all of your localization will also need to be synchronous.

emailTemplate.html

<div>
  {{localizedText}}
</div>

Other templates for each locale:

emailTemplate.en.html

<p>
  Hi {{nome}}...
</p>

The emailer logic:

// The same templater used by parse-server-amazon-ses-email-adapter
import template from 'lodash.template'

/* ... */

const TemplatesByLocale = {
  en: fs.readFileSync('./emailTemplate.en.html'),
}

verificationEmail: {
  /* ... */
  pathHtml: './path/to/emailTemplate.html',
  callback: (user) => {
    const locale = getLocaleSomehow(user) // needs to be synchronous
    const localizedTemplate = TemplatesByLocale[locale]

    const compiled = template(localizedTemplate, {
      // same interpolation as parse-server-amazon-ses-email-adapter
      interpolate: /{{([\s\S]+?)}}/g
    })
    const localizedText = compiled({
      nome: user.get('nome'), /* ... */
    })
    return {
      localizedText: localizedText,
    }
  },
  /* ... */
}

It's worth noting that parse-server-amazon-ses-email-adapter will use the HTML template (the one specified via pathHtml) before it uses the plain text template, so if you've specified an HTML template you can just leave off the pathPlainText property.

7 Comments

This won't work because there is decision making that needs to happen based on the variables and that cannot be done in the template
You can do the decision making in the template callback. Guess this wasn't clear in the answer, but you do the localization in the template callback and then render the result in the template.
Can you add a example of the same to your answer?
Sure thing, will add an example.
If you need to have separate template files for each locale, the example above will work. This is kind of a hack around the library though, and you'll need to write only synchronous code in the template callback.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.