Sendgrid-nodejs: Substitutions not working

Created on 10 Apr 2018  ·  43Comments  ·  Source: sendgrid/sendgrid-nodejs

Issue Summary

Followed the example for using substitutions in transactional emails, without making any changes. The substitution tags are removed, but the text is not inserted. Here is a screenshot of the email I receive:

image

Steps to Reproduce

  1. Clone https://github.com/panayi/test-sg/
  2. Copy the template body from the example and create a transactional template on SendGrid UI.
  3. Edit test.js to insert your API key, your email address, and templateId you created above.
  4. Run node test.js.

Technical details:

unknown or a help wanted question

Most helpful comment

Hi, after reading @himanshupnt 's comment, I tested with a legacy template and it worked. Thanks @himanshupnt .

Later I found Sendgrid documentation Mail Send with Dynamic Transactional Templates, I've kind of got the new template (not legacy one) working. I used the same HTML template and my code was updated to:

  const sgMail = require("@sendgrid/mail");
  sgMail.setApiKey(process.env.SENDGRID_API_KEY);
  sgMail.setSubstitutionWrappers("{{", "}}"); // Configure the substitution tag wrappers globally

  const msg = {
    from: "[email protected]",
    templateId: "d-27e7d954368c46519eddc806e5cf8156",
    personalizations: [
      {
        to: [
          {
            email: "[email protected]"
          }
        ],
        dynamic_template_data: {
          name: "Someone",
          city: "Somewhere",
          subject: "Hello new world"
        }
      }
    ]
  };

  sgMail.send(msg).catch(err => console.error(err.message));

Notice that I replaced "substitutions" with "dynamic_template_data", and placed "to" inside "personalizations" as required by the docs. And I also treated subject as one of the "dynamic_template_data" and it works. (put {{subject}} in the template subject field)

Thanks.

All 43 comments

Hello @panayi,

Some things to check:

  1. Verify the Template ID is correct
  2. Verify the Template is marked active in the UI

Can you also share what your HTML looks like?

Thanks!

With Best Regards,

Elmer

Hello, @thinkingserious , I was able to reproduce the same issue as @panayi mentioned.
My Html code looks something like this

Hello first_name (Employee : employee_id)
Some HTML code

Code

sgMail.setApiKey('apikey');
sgMail.setSubstitutionWrappers('{{', '}}'); // Triied sgMail.setSubstitutionWrappers('-', '-'); as well`

const msg = {
  to: '[email protected]',
  from: '[email protected]',
  subject: 'Hello world',
  text: 'Hello plain world!',
  html: 'Hello HTML world!',
  templateId: 'template-id',
  substitutions: {
    first_name: 'Tejas',
    employee_id: 'emp123',
  },
};
sgMail.send(msg);

Note: I've even tried using substitutionWrappers: ['{{', '}}']
within msg but with no luck.

Technical details:

Any Help/Fix Appreciated as I've invested much time in this issue

Hello @tjstlekr,

In your HTML code, please change first_name to {{first_name}} and employee_id to {{employee_id}}.

Thanks!

With Best Regards,

Elmer

Hello @thinkingserious,
By HTML code, Do you mean the template code?
Why is it that the substitution tag would work fine when specified within request body here, But not when using the predefined examples on the page?
Thanks!

Yes @tjstlekr, I mean the template code as described in this example.

I can not answer your second question without concrete examples. (e.g. request body and template code).

With Best Regards,

Elmer

Sadly! I do not have access to the template code. I'll stick with another version.
Thanks anyways @thinkingserious

Have you tried:

substitutions: {
    'first_name': 'Tejas',
    'employee_id': 'emp123',
  },

Yes, @thinkingserious tried that. I have also tried the following ways


substitutions: {
    '-first_name-': 'Tejas',
    '-employee_id-': 'emp123',
  },

substitutions: {
    '%first_name%': 'Tejas',
    '%employee_id%': 'emp123',
  },

substitutions: {
    '=first_name=': 'Tejas',
    '=employee_id'=: 'emp123',
  },

@tjstlekr,

I think your solution is to get whoever can change the HTML template code to wrap the variables with a substitution character(s).

With Best Regards,

Elmer

@thinkingserious is correct. The template variables MUST be wrapped in double brackets {{name}}. Otherwise SendGrid wont know where to drop the substitutions you've sent.

the variables really need double brackets? i'll go ahead and try it but a different post by the same person showed the substitutions working with dashes, not double brackets:
screenshot 2018-06-26 14 08 12

Hello @tetreault,

By default we use double brackets. setSubstitutionWrappers allows you to modify them as you demonstrated.

Thanks!

With Best Regards,

Elmer

I've encountered the same issue as @panayi .

I followed the transactional-templates sample. I've set substitution wrappers and in the template, wrapped substitutions in double brackets. However, the email I received had removed all substitutions without replacing with those I provided.

I tried with both Code editor and Design editor for the template.

Technical details:

Thanks!

Hi @nrator,

If the substitutions were replaced with blank strings, I'd double check that the variables you are iterating on are not empty. If you do verify they are not empty, could you please share the code snippit along with the relevant HTML so I can try and reproduce?

Thanks!

With Best Regards,

Elmer

Hi @thinkingserious

I am not using variables but string so they are not empty. Below are the code snippet, HTML and the result I got:

Code

const sgMail = require("@sendgrid/mail");
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
sgMail.setSubstitutionWrappers("{{", "}}"); // Configure the substitution tag wrappers globally

const msg = {
  from: "[email protected]", // my personal email
  to: "[email protected]", // my another personal email
  subject: "Hello world",
  text: "Hello plain world!",
  html: "<p>Hello HTML world!</p>",
  templateId: "d-27e7d954368c46519eddc806e5cf8156",
  substitutions: {
    name: "Some One",
    city: "Denver"
  }
};

  sgMail.send(msg).catch(err => console.error(err.message));

HTML template

<html>
<head>
    <title></title>
</head>
<body>
Hello {{name}},
<br /><br/>
I'm glad you are trying out the template feature!
<br /><br/>
<%body%>
<br /><br/>
I hope you are having a great day in {{city}} :)
<br /><br/>
</body>
</html>

Email I got

Hello , 

I'm glad you are trying out the template feature! 

<%body%> 

I hope you are having a great day in :) 

Technical details
sendgrid-nodejs Version: @sendgrid/[email protected]
Node.js Version: 8.11.2

Best regards,
Jason

Hi I am having the same issue with transactional templates. The variables won't pickup. Using test data to preview the template in SG dashboard, everything looks correct.
Emails get sent to the right person, and with the correct template except, missing variable values.
I created a legacy template 2 days back which worked fine and today I switched to newer
transactional templates and it doesn't work. I just duplicated the old legacy template which was
working fine.
"@sendgrid/mail": "6.3.1" | Node.js 8.10
Here is my code :

async function sendEmail({ email, firstName, password }) {
  const msg = {
    to: [{ email, firstName }],
    from: {
      email: "[email protected]",
      name: "name"
    },
    asm: {
      group_id: 1234
    },
    templateId: "d-64b15a042b2d41d7a4b5b6a4eea649c5",
    substitutions: {
      userName: firstName,
      email,
      password
    }
  }
  try {
    await sgMail.send(msg);
  } catch(e){
    e.message
  }

  };

And here is the html template :

<h3>Hi {{userName}},</h3>

<div><span style="font-size:16px;">Your account has been setup. To login please use</span></div>

<div><span style="font-size:16px;">the credentials below.</span></div>

<div>&nbsp;</div>

<div><span style="font-size:16px;"><strong>Email:</strong>&nbsp;{{email}}</span></div>

<div><strong><span style="font-size:16px;">Password:&nbsp;</span></strong><span style="color: rgb(0, 0, 0); font-family: arial; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;">{{password}}</span></div>

<div><span style="font-weight: 600; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-family: arial; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size: 16px;">SignIn Url: <a href="https://a.abc.com">https://a.abc.com/</a></span></span></div>

<div>&nbsp;</div>

<div>&nbsp;</div>

<div><span style="font-size:16px;">Please let us know if you need any help, email us at <a href="mailto:[email protected]">[email protected]</a></span></div>

Cheers

I just switched over to the legacy template with same html code and it works. Can it be due to new changes in V3 API?

Hi, after reading @himanshupnt 's comment, I tested with a legacy template and it worked. Thanks @himanshupnt .

Later I found Sendgrid documentation Mail Send with Dynamic Transactional Templates, I've kind of got the new template (not legacy one) working. I used the same HTML template and my code was updated to:

  const sgMail = require("@sendgrid/mail");
  sgMail.setApiKey(process.env.SENDGRID_API_KEY);
  sgMail.setSubstitutionWrappers("{{", "}}"); // Configure the substitution tag wrappers globally

  const msg = {
    from: "[email protected]",
    templateId: "d-27e7d954368c46519eddc806e5cf8156",
    personalizations: [
      {
        to: [
          {
            email: "[email protected]"
          }
        ],
        dynamic_template_data: {
          name: "Someone",
          city: "Somewhere",
          subject: "Hello new world"
        }
      }
    ]
  };

  sgMail.send(msg).catch(err => console.error(err.message));

Notice that I replaced "substitutions" with "dynamic_template_data", and placed "to" inside "personalizations" as required by the docs. And I also treated subject as one of the "dynamic_template_data" and it works. (put {{subject}} in the template subject field)

Thanks.

@nrator That did it for me as well. Thanks for posting it!

I'm having the same problem and I opened an issue as well (After trying out solutions mentioned at the beginning). However I was able to add name and city to the template following mentioned by @nrator . But was unable to replace <%subject%> and <%body%> as they are included in the email which I receive . How can I replace <%body%> and <%subject%> ? @himanshupnt how did you solve this?

Hi @pankaja92 , I couldn't get <%subject%> working as well. Now my way of dealing subject is treating it as one of the "dynamic_template_data", which means I wrap it in {{ }} instead of <% %> and handle it inside "dynamic_template_data".

I've found this sendgrid docs which may help. The subject param doesn't seem working though.

@nrator Thanks . It worked. So, there' no need of <%body%> as well right (as it also won't work as the example given) .

Btw, not the issue specific - but, do you have any experience or example to send a list of details via this library ? I'm looking for something that might help me to build my app :)

@pankaja92 I am not sure what do you mean by sending a list of details. You may read this sendgrid blog post about new features of the dynamic templates, basically you can now iterate over lists of items or use basic conditionals to generate dynamic contents.

For actual codes, you may refer to this repo.

Hope it helps!

Hi all, spent a few hours on this issue as well.

Instead of using substitutions, use dynamicTemplateData in the main msg object instead:

const sgMail = require('@sendgrid/mail')

sgMail.setApiKey(process.env.SENDGRID_API_KEY)
sgMail.setSubstitutionWrappers('{{', '}}')

const msg = {
  to: '[email protected]',
  from: '[email protected]',
  templateId: 'd-27e7d954368c46519eddc806e5cf8156',
  dynamicTemplateData: {
    name: 'Some One',
    city: 'Denver',
  },
}

sgMail.send(msg)

Reference: https://github.com/sendgrid/sendgrid-nodejs/pull/691

According to that PR, when the templateId is a dynamic template (prefixed with d-), the substitutions isn't sent at all, so the dynamicTemplateData object should be used.

They've created an issue here to improve the add dynamic templates usage to the docs, but until then I hope this helps. 🎉

Please follow this issue: #703

change 'substitutions' to 'dynamic_template_data'

@jseyfert shouldn't it be dynamic_template_data?

@aroach you are correct. I have updated my comment.

At first it didn't work on my side either.
I've noticed that my version was a bit out of date (I was using @sendgrid/[email protected])
I've updated the package, change my code and now it is working:

using @sendgrid/[email protected]

const result = await this.sgMail.send({
                personalizations: [{
                    to: this._to
                }],
                dynamicTemplateData: {
                    test: 'test' <== working (code in template: {{ test }})
                },
                templateId: this._templateId,
            });

I should note that the code below is not working:

const result = await this.sgMail.send({
                personalizations: [{
                    to: this._to,
                dynamicTemplateData: {
                    test: 'test' <== NOT working (code in template: {{ test }})
                }
                }],
                templateId: this._templateId,
            });

Yep, you need to use v6.3.1 for dynamic_template_data support.

On Tue, Dec 11, 2018 at 4:15 AM Roy Milder notifications@github.com wrote:

At first it didn't work on my side either.
I've noticed that my version was a bit out of date (I was using
@sendgrid/[email protected])
I've updated the package, change my code and now it is working:

using @sendgrid/[email protected]

const result = await this.sgMail.send({
personalizations: [{
to: this._to
}],
dynamicTemplateData: {
test: 'test' <== working (code in template: {{ test }})
},
templateId: this._templateId,
});


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/sendgrid/sendgrid-nodejs/issues/676#issuecomment-446166152,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACL-sjFRFP8txUETNWFVLs0chW5yyL1Nks5u35OzgaJpZM4TOB5l
.

Hi, do not forget
not create transactional template, create legacy template and make a copy of it.
then every steps that you do gonna work.

dynamicTemplateData

Works for me. I have the latest version of the SendGrid library, and am using it through Firebase (Functions). The main issue now is the lack of TypeScript support - and the documentation.

@roymilder , thank you so much. Your answer made my day - the substitutions for dynamic templates are very unclear.
Kudos!

Hello @OleksiiM,

Does this example help?

@darren-dev,

Thanks for helping out! With regards to lack of TypeScript support and documentation, are you referring to the Firebase side?

@uups,

Thanks for helping out!

With Best Regards,

Elmer

@thinkingserious, yes it does. Thank you.

@OleksiiM,

Where did you look first? I'm trying to figure out how to make sure folks who need to use dynamic templates go to the link I sent you first.

@thinkingserious
Started here.

It says:
"Sending Transactional Templates
You can send transactional templates using one of three ways:
Using the SMTP Relay
Including the template ID in the templates parameter of the Web API v3 Mail Send endpoint
Using the x-smtpapi parameter in the Web API v2 Mail Send endpoint"

So I jumped to "Including the template ID in the templates parameter of the Web API v3 Mail Send endpoint".

Why it was unclear:
last page shows the list of possible "Request body parameters" which is showing the template_id but says nothing about "dynamic_template_data" field. I have tried to go with "personalizations" + "substitutions" + "template_id" and it did not work.
Also, since I am a new Sendgrid user, I was not aware of "old" templates and "new" (dynamic) templates and the difference between them (sendgrid doc pages from above are not saying anything about that).

Thank you for asking and making the docs better. I hope that other folks will avoid this type of troubles.

@thinkingserious if I may add:
I'm currently using these docs: https://sendgrid.com/docs/API_Reference/api_v3.html

The instructions on sending e-mail (https://sendgrid.api-docs.io/v3.0/mail-send) do not mention dynamic_template_data at all in personalizations.

So that is unclear as well.

Hope it helps!

@Whatthefoxsays ^^

Thanks @OleksiiM & @roymilder! We appreciate your contributions back to the Twilio SendGrid community :)

Hi all, spent a few hours on this issue as well.

Instead of using substitutions, use dynamicTemplateData in the main msg object instead:

const sgMail = require('@sendgrid/mail')

sgMail.setApiKey(process.env.SENDGRID_API_KEY)
sgMail.setSubstitutionWrappers('{{', '}}')

const msg = {
  to: '[email protected]',
  from: '[email protected]',
  templateId: 'd-27e7d954368c46519eddc806e5cf8156',
  dynamicTemplateData: {
    name: 'Some One',
    city: 'Denver',
  },
}

sgMail.send(msg)

Reference: #691

According to that PR, when the templateId is a dynamic template (prefixed with d-), the substitutions isn't sent at all, so the dynamicTemplateData object should be used.

They've created an issue here to improve the add dynamic templates usage to the docs, but until then I hope this helps. 🎉

Hustling since 2 days I saw this and got this to work.

Hello @Travotics,

What documentation did you start with before you found the above? I'm trying to improve this experience. Thanks!

With Best Regards,

Elmer

@thinkingserious https://github.com/sendgrid/sendgrid-nodejs/blob/master/use-cases/kitchen-sink.md

Does not have dynamicTemplateData but it does have substitutionWrappers and substitutions.

In addition to updating the docs, it would also be a good idea to update the type interface MailData (https://github.com/sendgrid/sendgrid-nodejs/blob/master/packages/helpers/classes/mail.d.ts#L117). For @sendgrid/mail releases that don't support the substitutions, they should expect a V2MailData parameter that has the substititons and substitutionWrappers fields omitted.

Hi, after reading @himanshupnt 's comment, I tested with a legacy template and it worked. Thanks @himanshupnt .

Later I found Sendgrid documentation Mail Send with Dynamic Transactional Templates, I've kind of got the new template (not legacy one) working. I used the same HTML template and my code was updated to:

  const sgMail = require("@sendgrid/mail");
  sgMail.setApiKey(process.env.SENDGRID_API_KEY);
  sgMail.setSubstitutionWrappers("{{", "}}"); // Configure the substitution tag wrappers globally

  const msg = {
    from: "[email protected]",
    templateId: "d-27e7d954368c46519eddc806e5cf8156",
    personalizations: [
      {
        to: [
          {
            email: "[email protected]"
          }
        ],
        dynamic_template_data: {
          name: "Someone",
          city: "Somewhere",
          subject: "Hello new world"
        }
      }
    ]
  };

  sgMail.send(msg).catch(err => console.error(err.message));

Notice that I replaced "substitutions" with "dynamic_template_data", and placed "to" inside "personalizations" as required by the docs. And I also treated subject as one of the "dynamic_template_data" and it works. (put {{subject}} in the template subject field)

Thanks.

Thank you so much for this! I've spent considerable time debugging for this. :/

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thinkingserious picture thinkingserious  ·  4Comments

nicoasp picture nicoasp  ·  3Comments

thidasapankaja picture thidasapankaja  ·  4Comments

thinkingserious picture thinkingserious  ·  4Comments

metalshan picture metalshan  ·  3Comments