sendgrid / sendgrid-nodejs

The Official Twilio SendGrid Led, Community Driven Node.js API Library
https://sendgrid.com
MIT License
3k stars 781 forks source link

Substitutions not working #676

Closed panayi closed 6 years ago

panayi commented 6 years ago

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:

thinkingserious commented 6 years ago

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

tjstlekr commented 6 years ago

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: 'myemail@example.org',
  from: 'sender@example.org',
  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

thinkingserious commented 6 years ago

Hello @tjstlekr,

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

Thanks!

With Best Regards,

Elmer

tjstlekr commented 6 years ago

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!

thinkingserious commented 6 years ago

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

tjstlekr commented 6 years ago

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

thinkingserious commented 6 years ago

Have you tried:

substitutions: {
    'first_name': 'Tejas',
    'employee_id': 'emp123',
  },
tjstlekr commented 6 years ago

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',
  },
thinkingserious commented 6 years ago

@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

mckenzieja commented 6 years ago

@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.

tetreault commented 6 years ago

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
thinkingserious commented 6 years ago

Hello @tetreault,

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

Thanks!

With Best Regards,

Elmer

hangindev commented 6 years ago

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!

thinkingserious commented 6 years ago

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

hangindev commented 6 years ago

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: "xxx@gmail.com", // my personal email
  to: "yyy@gmail.com", // 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/mail@6.3.1 Node.js Version: 8.11.2

Best regards, Jason

himanshupnt commented 6 years ago

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: "support@abc.com",
      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:a@abc.com">a@abc.com</a></span></div>

Cheers

himanshupnt commented 6 years ago

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?

hangindev commented 6 years ago

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: "xxx@gmail.com",
    templateId: "d-27e7d954368c46519eddc806e5cf8156",
    personalizations: [
      {
        to: [
          {
            email: "yyy@gmail.com"
          }
        ],
        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.

himanshupnt commented 6 years ago

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

thidasapankaja commented 6 years ago

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?

hangindev commented 6 years ago

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.

thidasapankaja commented 6 years ago

@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 :)

hangindev commented 6 years ago

@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!

jayprado commented 6 years ago

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: 'recipient@example.org',
  from: 'sender@example.org',
  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. 🎉

thinkingserious commented 6 years ago

Please follow this issue: #703

jseyfert commented 5 years ago

change 'substitutions' to 'dynamic_template_data'

aroach commented 5 years ago

@jseyfert shouldn't it be dynamic_template_data?

jseyfert commented 5 years ago

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

roymilder commented 5 years ago

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/mail@6.2.1) I've updated the package, change my code and now it is working:

using @sendgrid/mail@6.3.1

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,
            });
aroach commented 5 years ago

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/mail@6.2.1) I've updated the package, change my code and now it is working:

using @sendgrid/mail@6.3.1

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 .

ghost commented 5 years ago

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.

darren-dev commented 5 years ago
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.

OleksiiM commented 5 years ago

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

thinkingserious commented 5 years ago

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

OleksiiM commented 5 years ago

@thinkingserious, yes it does. Thank you.

thinkingserious commented 5 years ago

@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.

OleksiiM commented 5 years ago

@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.

roymilder commented 5 years ago

@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!

thinkingserious commented 5 years ago

@Whatthefoxsays ^^

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

Travotics commented 5 years ago

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: 'recipient@example.org',
  from: 'sender@example.org',
  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.

thinkingserious commented 5 years ago

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

CoreyCole commented 5 years ago

@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.

dmclavel commented 4 years ago

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: "xxx@gmail.com",
    templateId: "d-27e7d954368c46519eddc806e5cf8156",
    personalizations: [
      {
        to: [
          {
            email: "yyy@gmail.com"
          }
        ],
        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. :/