sendgrid / email-templates

A repository of common email templates to use and modify to your heart's content.

Home Page:https://sendgrid.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dynamic template data for multiple recipients

JayCunha opened this issue · comments

Actual Behaviour

Right now, I can only send dynamic template data for one recipient at a time. Example of my code:

{
"personalizations": [
{
"to": [
{
"email": "john.doe@example.com",
"name": "John Doe"
}
],
"dynamic_template_data": {
"firstName": "John",
"lastName": "Doe"
},
"subject": "Hello, World!"
}
],
"from": {
"email": "noreply@johndoe.com",
"name": "John Doe"
},
"reply_to": {
"email": "noreply@johndoe.com",
"name": "John Doe"
},
"template_id": "<<YOUR_TEMPLATE_ID>>"
}

Expected Behaviour

I want to send dynamic template data for each recipient, but I don't know how. The idea is to send personalized e-mails for multiple recipients one at a time, instead of sending emails one by one. I tried to search for an example but I couldn't find it. Do you have any?

Yes, you can send one mail to multiple recipient. I have faced same problem but I have solved the issue. Just use separate personalizations.
Example Json:

{
  "personalizations": [
    {
      "to": [
        {
          "email": "john.doe@example.com",
          "name": "John Doe"
        }
      ],
      "dynamic_template_data": {
        "firstName": "John",
        "lastName": "Doe"
      },
      "subject": "Hello, World!"
    },
    {
      "to": [
        {
          "email": "john.doe@example.com",
          "name": "John Doe"
        }
      ],
      "dynamic_template_data": {
        "firstName": "John",
        "lastName": "Doe"
      },
      "subject": "Hello, World!"
    }
  ],
  "from": {
    "email": "noreply@johndoe.com",
    "name": "John Doe"
  },
  "reply_to": {
    "email": "noreply@johndoe.com",
    "name": "John Doe"
  },
  "template_id": "<<YOUR_TEMPLATE_ID>>"
}

Since this issue hasn't been closed, how do I inject my dynamic template data into the model when using the SendGridMessage object in C#?

var mail = new SendGridMessage
{
    Attachments = new List<Attachment>(),
    From = new EmailAddress()
    {
        Email = emailConfig.FromAddress,
        Name = emailConfig.FromName
    },
    TemplateId = EmailConstants.ConfirmationEmailTemplateId,
    Subject = subject
};

mail.Personalizations = new List<Personalization>() {
    TemplateData = ???
};

@logany-hi

For you reference:-

public virtual async Task<bool> SendEmailPersonalized<TValue>(Dictionary<string, string> to, string templateId, Dictionary<string, TValue> templateData, string? fromName = null, string? fromEmail = null)
    {
        var msg = new SendGridMessage();
        msg.SetFrom(new EmailAddress(fromEmail ?? sendGridOptions.FromEmail, fromName ?? sendGridOptions.FromName));
        msg.SetTemplateId(templateId);

        msg.Personalizations = new List<Personalization>();

        foreach (var r in to)
        {
            msg.Personalizations.Add(new Personalization()
            {
                Tos = new List<EmailAddress>() { new EmailAddress(r.Key, r.Value) },
                TemplateData = templateData[r.Key]
            }); 
        }

        var response = await sendGridClient.SendEmailAsync(msg);
        if (response.StatusCode >= System.Net.HttpStatusCode.OK && response.StatusCode <= System.Net.HttpStatusCode.IMUsed)
        {
            return true;
        }

        logger.LogWarning("SendEmail returned a negative status. Response: {@response} for {@to} address. TemplateId: {@templateId}", response, to, templateId);
        return false;
    }


//-------------------------------
//Caller of above function
//-------------------------------
foreach (var t in alertsList)
        {
            await _emailService.SendEmailPersonalized(
                t.AlertRecipient.ToDictionary(a => a.Email??Notifications.CommonData.Empty_UserEmail_Replacement, a => a.Name??Notifications.CommonData.Empty_UserName_Replacement)
                ,alertType.TemplateId!
                ,t.AlertRecipient.ToDictionary(a => a.Email?? Notifications.CommonData.Empty_UserEmail_Replacement, a => new CampaignGoalAchieved
                {
                    DonorName = a.Name??Notifications.CommonData.Empty_UserName_Replacement,
                    CampaignName = "Test Campaign Name",
                    CampaignLink = "http://sample.com",
                    GoalAchieved = "25"
                })
                , alertType.Sender
                , alertType.SenderEmail
            );

            t.Status = Notifications.AlertStatus.Processed;
            await UpdateAlertAsync(_Mapper.Map<Alert, AlertDto>(t));
        }

commented

I also had issues with it.
The docs are pretty disappointing :(

What worked for me -
create a separate object for each email. Not using the personalization key.

example:

const yourArrayOfEmails = [{someData: 1, email: 'a@hi.com'}, {someData: 2, email: 'b@hi.com'}]

yourArrayOfEmails.map(emailDetails => {
  return {
    from: {
        email: EMAIL_FROM,
        name: EMAIL_NAME,
    },
    templateId: EMAIL_TEMPLATE_ID,
  
    // dynamic
    to: emailDetails.email,
    dynamicTemplateData: {
        someData: emailDetails.someData,
    },
  }
})