Repository: sendgrid/sendgrid-java (java)

Issue:
Add Dynamic Template Support
#### Issue Summary

On 7/24/2018, our team publicly launched dynamic content for transactional templates. It is now available for all customers sending over v3 of our Mail Send API. Iterate over lists, handle conditionals and more, thanks to native support for a subset of Handlebars syntax!

More information can be found in our [blog post announcement](https://sendgrid.com/blog/how-to-use-sendgrids-dynamic-templates-for-your-transactional-emails/).

You can currently use this feature by manually creating the request body as [shown here](https://github.com/sendgrid/sendgrid-java/blob/master/USAGE.md#v3-mail-send). 

Now, we need to create helper code and examples for this SDK.

#### Acceptance Criteria

* [Implement a helper similar to what we have for the legacy templates](https://github.com/sendgrid/sendgrid-java/blob/master/USE_CASES.md#transactional-templates)
* Update the [USE_CASES.md](https://github.com/sendgrid/sendgrid-java/blob/master/USE_CASES.md#transactional-templates) example to demonstrate the new *Dynamic Templates* using the helper and re-name the current example to *Legacy*

#### Documentation
- [Reference Implementation](https://github.com/sendgrid/sendgrid-nodejs/pull/691#issuecomment-407490342)
- [How to Send an Email With Dynamic Transactional Templates](https://sendgrid.com/docs/User_Guide/Transactional_Templates/how_to_send_an_email_with_transactional_templates.html)
- [Using Handlebars](https://sendgrid.com/docs/User_Guide/Transactional_Templates/Using_handlebars.html)
- [Interactive API Docs](https://dynamic-templates.api-docs.io/3.0/mail-send-with-dynamic-transactional-templates/v3-mail-send)


Pull request description:
Dynamic templates support
Fixes #447

Hello everyone, this is my first contribution! I'am really excited in fix any problem that I may have missed, although I believe everything is ok. :smiley:  

# Changes #
- Implemented a helper similar to what we have for the legacy templates
- Update thed USE_CASES.md example to demonstrate the new Dynamic Templates using the helper and re-name the current example to Legacy


Patch:
diff --git a/USE_CASES.md b/USE_CASES.md
index 5ec4899..204f74c 100644
--- a/USE_CASES.md
+++ b/USE_CASES.md
@@ -2,9 +2,10 @@ This documentation provides examples for specific use cases. Please [open an iss
 
 # Table of Contents
 
-* [Transactional Templates](#transactional_templates)
-* [How to Setup a Domain Whitelabel](#domain_whitelabel)
-* [How to View Email Statistics](#email_stats)
+* [Transactional Templates](#transactional-templates)
+* [Legacy Templates](#legacy-templates)
+* [How to Setup a Domain Whitelabel](#domain-whitelabel)
+* [How to View Email Statistics](#email-stats)
 
 <a name="transactional-templates"></a>
 # Transactional Templates
@@ -13,6 +14,102 @@ For this example, we assume you have created a [transactional template](https://
 
 Template ID (replace with your own):
 
+```text
+d-2c214ac919e84170b21855cc129b4a5f
+```
+
+Template Body:
+
+```html
+<html>
+  <head>
+    <title></title>
+  </head>
+  <body>
+    Hello {{name}},
+    <br/><br/>
+    I'm glad you are trying out the template feature!
+    <br/><br/>
+    I hope you are having a great day in {{city}} :)
+    <br/><br/>
+  </body>
+</html>
+```
+
+## With Mail Helper Class
+
+```java
+import com.sendgrid.*;
+import java.io.IOException;
+
+public class Example {
+  public static void main(String[] args) throws IOException {
+    Mail mail = new Mail();
+    mail.setFrom(new Email("teste@example.com"));
+    mail.setTemplateId("d-2c214ac919e84170b21855cc129b4a5f");
+
+    Personalization personalization = new Personalization();
+    personalization.addDynamicTemplateData("name", "Example User");
+    personalization.addDynamicTemplateData("city", "Denver");
+    personalization.addTo(new Email("test@example.com"));
+    mail.addPersonalization(personalization);
+            
+    SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
+    Request request = new Request();
+    try {
+      request.setMethod(Method.POST);
+      request.setEndpoint("mail/send");
+      request.setBody(mail.build());
+      Response response = sg.api(request);
+      System.out.println(response.getStatusCode());
+      System.out.println(response.getBody());
+      System.out.println(response.getHeaders());
+    } catch (IOException ex) {
+      throw ex;
+    }
+  }
+}
+```
+
+## Without Mail Helper Class
+
+```java
+import com.sendgrid.*;
+import java.io.IOException;
+
+public class Example {
+  public static void main(String[] args) throws IOException {
+    try {
+      SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
+      Request request = new Request();
+      request.setMethod(Method.POST);
+      request.setEndpoint("mail/send");
+      request.setBody("{
+        \"from\": {\"email\": \"test@example.com\"},
+        \"personalizations\":
+        [{
+          \"to\": [{\"email\": \"test@example.com\"}],
+          \"dynamic_template_data\": {\"name\": \"Example User\", \"city\": \"Denver\"}
+        }],
+        \"template_id\": \"d-2c214ac919e84170b21855cc129b4a5f\"}");
+      Response response = sg.api(request);
+      System.out.println(response.getStatusCode());
+      System.out.println(response.getBody());
+      System.out.println(response.getHeaders());
+    } catch (IOException ex) {
+      throw ex;
+    }
+  }
+}
+```
+
+<a name="legacy-templates"></a>
+# Legacy Templates
+
+For this example, we assume you have created a [legacy template](https://sendgrid.com/docs/User_Guide/Transactional_Templates/index.html). Following is the template content we used for testing.
+
+Template ID (replace with your own):
+
 ```text
 13b8f94f-bcae-4ec6-b752-70d6cb59f932
 ```
@@ -27,19 +124,19 @@ Template Body:
 
 ```html
 <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>
+  <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>
 ```
 
@@ -90,7 +187,20 @@ public class Example {
       Request request = new Request();
       request.setMethod(Method.POST);
       request.setEndpoint("mail/send");
-      request.setBody("{\"personalizations\":[{\"to\":[{\"email\":\"test@example.com\"}],\"substitutions\":{\"-name-\":\"Example User\",\"-city-\":\"Denver\"},\"subject\":\"Hello World from the SendGrid Java Library!\"}],\"from\":{\"email\":\"test@example.com\"},\"content\":[{\"type\":\"text/html\",\"value\": \"I'm replacing the <strong>body tag</strong>\"}],\"template_id\": \"13b8f94f-bcae-4ec6-b752-70d6cb59f932\"}");
+      request.setBody("{
+        \"personalizations\":
+        [{
+          \"to\": [{\"email\": \"test@example.com\"}],
+          \"substitutions\": {\"-name-\": \"Example User\", \"-city-\": \"Denver\"},
+          \"subject\": \"Hello World from the SendGrid Java Library!\"
+        }],
+        \"from\": {\"email\": \"test@example.com\"},
+        \"content\":
+        [{
+          \"type\": \"text/html\",
+          \"value\": \"I'm replacing the <strong>body tag</strong>\"
+        }]
+        ,\"template_id\": \"13b8f94f-bcae-4ec6-b752-70d6cb59f932\"}");
       Response response = sg.api(request);
       System.out.println(response.getStatusCode());
       System.out.println(response.getBody());
@@ -102,14 +212,14 @@ public class Example {
 }
 ```
 
-<a name="domain_whitelabel"></a>
+<a name="domain-whitelabel"></a>
 # How to Setup a Domain Whitelabel
 
 You can find documentation for how to setup a domain whitelabel via the UI [here](https://sendgrid.com/docs/Classroom/Basics/Whitelabel/setup_domain_whitelabel.html) and via API [here](https://github.com/sendgrid/sendgrid-java/blob/master/USAGE.md#whitelabel).
 
 Find more information about all of SendGrid's whitelabeling related documentation [here](https://sendgrid.com/docs/Classroom/Basics/Whitelabel/index.html).
 
-<a name="email_stats"></a>
+<a name="email-stats"></a>
 # How to View Email Statistics
 
 You can find documentation for how to view your email statistics via the UI [here](https://app.sendgrid.com/statistics) and via API [here](https://github.com/sendgrid/sendgrid-java/blob/master/USAGE.md#stats).
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 943b2b5..66599a6 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -16,7 +16,7 @@ RUN chmod +x ./install.sh && \
 WORKDIR /root/sources
 RUN git clone https://github.com/sendgrid/sendgrid-java.git
 WORKDIR /root
-RUN ln -s /root/sources/sendgrid-java/sendgrid
+RUN ln -s /root/sources/sendgrid-java
 
 COPY entrypoint.sh entrypoint.sh
 RUN chmod +x entrypoint.sh
diff --git a/docker/USAGE.md b/docker/USAGE.md
index 125b90f..0cb27fe 100644
--- a/docker/USAGE.md
+++ b/docker/USAGE.md
@@ -23,7 +23,10 @@ You can mount repositories in the `/mnt/sendgrid-java` and `/mnt/java-http-clien
 
 <a name="Testing"></a>
 # Testing
-Testing is easy!  Run the container, `cd sendgrid`, and run `./gradlew test`.
+Testing is easy!  
+1. Run the container: `docker run -it sendgrid/sendgrid-java`
+2. `cd sendgrid-java`
+3. run `./gradlew test`
 
 <a name="about"></a>
 # About
diff --git a/examples/helpers/mail/Example.java b/examples/helpers/mail/Example.java
index d595d0d..77c73eb 100644
--- a/examples/helpers/mail/Example.java
+++ b/examples/helpers/mail/Example.java
@@ -207,6 +207,26 @@ public class Example {
     return mail;
   }
 
+  // API V3 Dynamic Template implementation
+  public static Mail buildDynamicTemplate() throws IOException {
+    Mail mail = new Mail();
+
+    Email fromEmail = new Email();
+    fromEmail.setName("Example User");
+    fromEmail.setEmail("test@example.com");
+    mail.setFrom(fromEmail);
+
+    mail.setTemplateId("d-c6dcf1f72bdd4beeb15a9aa6c72fcd2c");
+
+    Personalization personalization = new Personalization();
+    personalization.addDynamicTemplateData("name", "Example User");
+    personalization.addDynamicTemplateData("city", "Denver");
+    personalization.addTo(new Email("test@example.com"));
+    mail.addPersonalization(personalization);
+    
+    return mail;
+  }
+
   // Minimum required to send an email
   public static Mail buildHelloEmail() throws IOException {
     Email from = new Email("test@example.com");
@@ -261,8 +281,28 @@ public class Example {
     }
   }
 
+  public static void dynamicTemplateExample() throws IOException {
+    SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
+    sg.addRequestHeader("X-Mock", "true");
+
+    Request request = new Request();
+    Mail dynamicTemplate = buildDynamicTemplate();
+    try {
+      request.setMethod(Method.POST);
+      request.setEndpoint("mail/send");
+      request.setBody(dynamicTemplate.build());
+      Response response = sg.api(request);
+      System.out.println(response.getStatusCode());
+      System.out.println(response.getBody());
+      System.out.println(response.getHeaders());
+    } catch (IOException ex) {
+      throw ex;
+    }
+  }
+
   public static void main(String[] args) throws IOException {
-    baselineExample();
-    kitchenSinkExample();
+    // baselineExample();
+    // kitchenSinkExample();
+    dynamicTemplateExample();
   }
 }
\ No newline at end of file
diff --git a/src/main/java/com/sendgrid/helpers/mail/objects/Personalization.java b/src/main/java/com/sendgrid/helpers/mail/objects/Personalization.java
index e364645..3ace82f 100644
--- a/src/main/java/com/sendgrid/helpers/mail/objects/Personalization.java
+++ b/src/main/java/com/sendgrid/helpers/mail/objects/Personalization.java
@@ -19,8 +19,9 @@ public class Personalization {
   @JsonProperty("headers") private Map<String,String> headers;
   @JsonProperty("substitutions") private Map<String,String> substitutions;
   @JsonProperty("custom_args") private Map<String,String> customArgs;
+  @JsonProperty("dynamic_template_data") private Map<String,Object> dynamicTemplateData;
   @JsonProperty("send_at") private long sendAt;
-  
+
   @JsonProperty("to")
   public List<Email> getTos() {
     if(tos == null)
@@ -144,6 +145,19 @@ public class Personalization {
     this.sendAt = sendAt;
   }
 
+  @JsonProperty("dynamic_template_data")
+  public Map<String,Object> getDynamicTemplateData() {
+    return dynamicTemplateData == null
+            ? Collections.<String,Object>emptyMap() : dynamicTemplateData;
+  }
+
+  public void addDynamicTemplateData(String key, Object value) {
+    if (dynamicTemplateData == null) {
+      dynamicTemplateData = new HashMap<String,Object>();
+    }
+    dynamicTemplateData.put(key, value);
+  }
+
   @Override
   public int hashCode() {
     final int prime = 31;


Test patch:
diff --git a/src/test/java/com/sendgrid/helpers/MailTest.java b/src/test/java/com/sendgrid/helpers/MailTest.java
index 67d893a..40ac75c 100644
--- a/src/test/java/com/sendgrid/helpers/MailTest.java
+++ b/src/test/java/com/sendgrid/helpers/MailTest.java
@@ -6,6 +6,11 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import java.io.IOException;
 
 public class MailTest {
@@ -96,6 +101,48 @@ public class MailTest {
     personalization2.setSendAt(1443636843);
     mail.addPersonalization(personalization2);
 
+    Personalization personalization3 = new Personalization();
+    Email to3 = new Email();
+    to3.setName("Example User");
+    to3.setEmail("test@example.com");
+    personalization3.addTo(to3);
+    to3.setName("Example User");
+    to3.setEmail("test@example.com");
+    personalization3.addTo(to3);
+    Email cc3 = new Email();
+    cc3.setName("Example User");
+    cc3.setEmail("test@example.com");
+    personalization3.addCc(cc3);
+    cc3.setName("Example User");
+    cc3.setEmail("test@example.com");
+    personalization3.addCc(cc3);
+    Email bcc3 = new Email();
+    bcc3.setName("Example User");
+    bcc3.setEmail("test@example.com");
+    personalization3.addBcc(bcc3);
+    bcc3.setName("Example User");
+    bcc3.setEmail("test@example.com");
+    personalization3.addBcc(bcc3);
+    personalization3.setSubject("Hello World from the Personalized SendGrid Java Library");
+    personalization3.addHeader("X-Test", "test");
+    personalization3.addHeader("X-Mock", "true");
+    List<Map<String, String>> items = new ArrayList<>();
+    Map<String, String> item1 = new HashMap<>();
+    item1.put("text", "New Line Sneakers");
+    item1.put("price", "$ 79.95");
+    items.add(item1);
+    Map<String, String> item2 = new HashMap<>();
+    item2.put("text", "Old Line Sneakers");
+    item1.put("price", "$ 59.95");
+    items.add(item2);
+    personalization3.addDynamicTemplateData("name", "Example User");
+    personalization3.addDynamicTemplateData("city", "Denver");
+    personalization3.addDynamicTemplateData("items", items);
+    personalization3.addCustomArg("user_id", "343");
+    personalization3.addCustomArg("type", "marketing");
+    personalization3.setSendAt(1443636843);
+    mail.addPersonalization(personalization3);
+
     Content content = new Content();
     content.setType("text/plain");
     content.setValue("some text here");
@@ -199,7 +246,7 @@ public class MailTest {
     replyTo.setEmail("test@example.com");
     mail.setReplyTo(replyTo);
 
-    Assert.assertEquals(mail.build(), "{\"from\":{\"name\":\"Example User\",\"email\":\"test@example.com\"},\"subject\":\"Hello World from the SendGrid Java Library\",\"personalizations\":[{\"to\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"cc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"bcc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"subject\":\"Hello World from the Personalized SendGrid Java Library\",\"headers\":{\"X-Mock\":\"true\",\"X-Test\":\"test\"},\"substitutions\":{\"%city%\":\"Denver\",\"%name%\":\"Example User\"},\"custom_args\":{\"type\":\"marketing\",\"user_id\":\"343\"},\"send_at\":1443636843},{\"to\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"cc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"bcc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"subject\":\"Hello World from the Personalized SendGrid Java Library\",\"headers\":{\"X-Mock\":\"true\",\"X-Test\":\"test\"},\"substitutions\":{\"%city%\":\"Denver\",\"%name%\":\"Example User\"},\"custom_args\":{\"type\":\"marketing\",\"user_id\":\"343\"},\"send_at\":1443636843}],\"content\":[{\"type\":\"text/plain\",\"value\":\"some text here\"},{\"type\":\"text/html\",\"value\":\"<html><body>some text here</body></html>\"}],\"attachments\":[{\"content\":\"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12\",\"type\":\"application/pdf\",\"filename\":\"balance_001.pdf\",\"disposition\":\"attachment\",\"content_id\":\"Balance Sheet\"},{\"content\":\"BwdW\",\"type\":\"image/png\",\"filename\":\"banner.png\",\"disposition\":\"inline\",\"content_id\":\"Banner\"}],\"template_id\":\"13b8f94f-bcae-4ec6-b752-70d6cb59f932\",\"sections\":{\"%section1%\":\"Substitution Text for Section 1\",\"%section2%\":\"Substitution Text for Section 2\"},\"headers\":{\"X-Test1\":\"1\",\"X-Test2\":\"2\"},\"categories\":[\"May\",\"2016\"],\"custom_args\":{\"campaign\":\"welcome\",\"weekday\":\"morning\"},\"send_at\":1443636842,\"asm\":{\"group_id\":99,\"groups_to_display\":[4,5,6,7,8]},\"ip_pool_name\":\"23\",\"mail_settings\":{\"bcc\":{\"enable\":true,\"email\":\"test@example.com\"},\"bypass_list_management\":{\"enable\":true},\"footer\":{\"enable\":true,\"text\":\"Footer Text\",\"html\":\"<html><body>Footer Text</body></html>\"},\"sandbox_mode\":{\"enable\":true},\"spam_check\":{\"enable\":true,\"threshold\":1,\"post_to_url\":\"https://spamcatcher.sendgrid.com\"}},\"tracking_settings\":{\"click_tracking\":{\"enable\":true,\"enable_text\":false},\"open_tracking\":{\"enable\":true,\"substitution_tag\":\"Optional tag to replace with the open image in the body of the message\"},\"subscription_tracking\":{\"enable\":true,\"text\":\"text to insert into the text/plain portion of the message\",\"html\":\"<html><body>html to insert into the text/html portion of the message</body></html>\",\"substitution_tag\":\"Optional tag to replace with the open image in the body of the message\"},\"ganalytics\":{\"enable\":true,\"utm_source\":\"some source\",\"utm_term\":\"some term\",\"utm_content\":\"some content\",\"utm_campaign\":\"some name\",\"utm_medium\":\"some medium\"}},\"reply_to\":{\"name\":\"Example User\",\"email\":\"test@example.com\"}}");
+    Assert.assertEquals(mail.build(), "{\"from\":{\"name\":\"Example User\",\"email\":\"test@example.com\"},\"subject\":\"Hello World from the SendGrid Java Library\",\"personalizations\":[{\"to\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"cc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"bcc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"subject\":\"Hello World from the Personalized SendGrid Java Library\",\"headers\":{\"X-Mock\":\"true\",\"X-Test\":\"test\"},\"substitutions\":{\"%city%\":\"Denver\",\"%name%\":\"Example User\"},\"custom_args\":{\"type\":\"marketing\",\"user_id\":\"343\"},\"send_at\":1443636843},{\"to\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"cc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"bcc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"subject\":\"Hello World from the Personalized SendGrid Java Library\",\"headers\":{\"X-Mock\":\"true\",\"X-Test\":\"test\"},\"substitutions\":{\"%city%\":\"Denver\",\"%name%\":\"Example User\"},\"custom_args\":{\"type\":\"marketing\",\"user_id\":\"343\"},\"send_at\":1443636843},{\"to\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"cc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"bcc\":[{\"name\":\"Example User\",\"email\":\"test@example.com\"},{\"name\":\"Example User\",\"email\":\"test@example.com\"}],\"subject\":\"Hello World from the Personalized SendGrid Java Library\",\"headers\":{\"X-Mock\":\"true\",\"X-Test\":\"test\"},\"custom_args\":{\"type\":\"marketing\",\"user_id\":\"343\"},\"dynamic_template_data\":{\"city\":\"Denver\",\"items\":[{\"price\":\"$ 59.95\",\"text\":\"New Line Sneakers\"},{\"text\":\"Old Line Sneakers\"}],\"name\":\"Example User\"},\"send_at\":1443636843}],\"content\":[{\"type\":\"text/plain\",\"value\":\"some text here\"},{\"type\":\"text/html\",\"value\":\"<html><body>some text here</body></html>\"}],\"attachments\":[{\"content\":\"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12\",\"type\":\"application/pdf\",\"filename\":\"balance_001.pdf\",\"disposition\":\"attachment\",\"content_id\":\"Balance Sheet\"},{\"content\":\"BwdW\",\"type\":\"image/png\",\"filename\":\"banner.png\",\"disposition\":\"inline\",\"content_id\":\"Banner\"}],\"template_id\":\"13b8f94f-bcae-4ec6-b752-70d6cb59f932\",\"sections\":{\"%section1%\":\"Substitution Text for Section 1\",\"%section2%\":\"Substitution Text for Section 2\"},\"headers\":{\"X-Test1\":\"1\",\"X-Test2\":\"2\"},\"categories\":[\"May\",\"2016\"],\"custom_args\":{\"campaign\":\"welcome\",\"weekday\":\"morning\"},\"send_at\":1443636842,\"asm\":{\"group_id\":99,\"groups_to_display\":[4,5,6,7,8]},\"ip_pool_name\":\"23\",\"mail_settings\":{\"bcc\":{\"enable\":true,\"email\":\"test@example.com\"},\"bypass_list_management\":{\"enable\":true},\"footer\":{\"enable\":true,\"text\":\"Footer Text\",\"html\":\"<html><body>Footer Text</body></html>\"},\"sandbox_mode\":{\"enable\":true},\"spam_check\":{\"enable\":true,\"threshold\":1,\"post_to_url\":\"https://spamcatcher.sendgrid.com\"}},\"tracking_settings\":{\"click_tracking\":{\"enable\":true,\"enable_text\":false},\"open_tracking\":{\"enable\":true,\"substitution_tag\":\"Optional tag to replace with the open image in the body of the message\"},\"subscription_tracking\":{\"enable\":true,\"text\":\"text to insert into the text/plain portion of the message\",\"html\":\"<html><body>html to insert into the text/html portion of the message</body></html>\",\"substitution_tag\":\"Optional tag to replace with the open image in the body of the message\"},\"ganalytics\":{\"enable\":true,\"utm_source\":\"some source\",\"utm_term\":\"some term\",\"utm_content\":\"some content\",\"utm_campaign\":\"some name\",\"utm_medium\":\"some medium\"}},\"reply_to\":{\"name\":\"Example User\",\"email\":\"test@example.com\"}}");
   }
 
   @Test
@@ -210,7 +257,7 @@ public class MailTest {
 
     Assert.assertSame(from, mail.getFrom());
   }
-  
+
   @Test
   public void mailDeserialization() throws IOException {
     Email to = new Email("foo@bar.com");