Sendgrid complex data into dynamic template data in java

2.4k Views Asked by At

I am using the latest version of send grid, my mustache template is working fine on local. I have created a dynamic template on send grid, now I need to send a complex object as input data in the template.

for example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{#trueFlag}}
    true flag :<p>{{orderId}}</p>
{{/trueFlag}}
-----
{{^falseFlag}}
    false flag : <p>{{orderId}}</p>
{{/falseFlag}}

href
<a href="{{websiteUrl}}?">WeSome</a>

image
<img src="{{imageUrl}}" alt="{{imageAlt}}">

{{#features}}
    {{.}}
{{/features}}
-----
feature
<p>{{feature.featureName}}</p>
<p>{{feature.featureType}}</p>
-----
{{#features}}
    {{featureName}}
    {{featureType}}
{{/features}}
-----------
<table>
    <tr>
        <th>Id</th>
        <th>Name</th>
        <th>Price</th>
    </tr>
    {{#features}}
        <tr>
            <td>{{featureName}}</td>
            <td>{{featureType}}</td>
        </tr>
    {{/features}}
</table>
</body>
</html>

complex object is

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.List;

@Data
public class TemplateObject {
    private boolean trueFlag;
    private boolean falseFlag;
    private String orderId;
    private String websiteUrl;
    private String imageUrl;
    private String imageAlt;
    List<Feature> features;
    Feature feature;

    @Data
    @AllArgsConstructor
    public static class Feature {
        String featureName;
        String featureType;
    }
}

JSON generated from the above object is

{
  "trueFlag": true,
  "falseFlag": false,
  "orderId": "1",
  "websiteUrl": "wesome.org",
  "imageUrl": "http://s7d7.scene7.com/is/image/BedBathandBeyond/1565212198531p?$130$",
  "imageAlt": "2Cuisinart® Replacement1 Charcoal Water Filters (Set of 2)",
  "features": [
    {
      "featureName": "feature 2",
      "featureType": "feature type 2"
    },
    {
      "featureName": "feature 3",
      "featureType": "feature type 3"
    }
  ],
  "feature": {
    "featureName": "feature 1",
    "featureType": "feature type 1"
  }
}

this JSON is correct, and I have validated it using send grid test JSON data functionality on the web app.

now I need to pass this complex object to SendGrid.

     Mail mail = new Mail();
        Email fromEmail = new Email();
        fromEmail.setName("shri");
        fromEmail.setEmail("[email protected]");
        mail.setFrom(fromEmail);
        mail.setTemplateId("d-xxxx");
        Personalization personalization = new Personalization();
        Gson gson = new Gson();
        String s = gson.toJson(templateObject);
    

//      if i paas data as individual key value its working
        personalization.addDynamicTemplateData("imageUrl", "http://s7d7.scene7.com/is/image/BedBathandBeyond/1565212198531p?$130$");

//      but i need to paas this object
        personalization.addDynamicTemplateData("dynamic_template_data", s);
        personalization.addTo(new Email("[email protected]"));
        System.out.println(gson.toJson(personalization));
        mail.addPersonalization(personalization);
1

There are 1 best solutions below

0
On

Twilio SendGrid developer evangelist here.

I'm not a Java developer, so hadn't seen this before, but it seems like it is slightly awkward to add dynamic template data like this to an email.

The code in the library behind addDynamicTemplateData looks like this:

  public void addDynamicTemplateData(String key, Object value) {
    if (dynamicTemplateData == null) {
      dynamicTemplateData = new HashMap<String, Object>();
    }
    dynamicTemplateData.put(key, value);
  }

So, it only accepts one key and data at a time. So, you can either add your object to the dynamic template data under one key within the internal HashMap and refer to that key throughout your template or iterate through the keys of your object and add each key and subsequent value to the dynamic data.

In the first option, don't serialize the template data and pass it with a single key, like "data" to addDynamicTemplateData

personalization.addDynamicTemplateData("data", templateObject);

The JSON object that will be sent to the API will then look like:

{
  "data":
    {
      "trueFlag": true,
      "falseFlag": false,
      // etc...
    }
}

And you should update your handlebars template to use the root of "data". For example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{#data.trueFlag}}
    true flag :<p>{{data.orderId}}</p>
{{/data.trueFlag}}

Alternatively, you can run through the keys of your template data and add them to the dynamic data individually:

personalization.addDynamicTemplateData("trueFlag",   templateObject.getTrueFlag());
personalization.addDynamicTemplateData("falseFlag",  templateObject.getFalseFlag());
personalization.addDynamicTemplateData("orderId",    templateObject.getOrderId());
personalization.addDynamicTemplateData("websiteUrl", templateObject.getWebsiteUrl());
personalization.addDynamicTemplateData("imageUrl",   templateObject.getImageUrl());
personalization.addDynamicTemplateData("imageAlt",   templateObject.getImageAlt());
personalization.addDynamicTemplateData("features",   templateObject.getFeatures());

Then you can keep the handlebars template the same.


The Java SendGrid library is open source and supports external contributions. The addDynamicTemplateData method was contributed in this way. It looks as though someone suggested that the a setDynamicTemplateData(Map<String, String> dynamicTemplateData) method was implemented (though it really should have been Map<String, Object>) but it seems that didn't make it into the final implementation. If something like this would be useful, then please do suggest it in the repo issues.