diff --git a/USE_CASES.md b/USE_CASES.md index 60fdd79eb..bb46bd01f 100644 --- a/USE_CASES.md +++ b/USE_CASES.md @@ -2,16 +2,27 @@ This documentation provides examples for specific use cases. Please [open an iss # Table of Contents -* [Email - Attachments](#attachments) -* [Email - Kitchen Sink - an example with all settings used](#kitchensink) -* [Email - Send a Single Email to Multiple Recipients](#singleemailmultiplerecipients) -* [Email - Send a Single Email to a Single Recipient](#singleemailsinglerecipient) -* [Email - Send Multiple Emails to Multiple Recipients](#multipleemailsmultiplerecipients) -* [Email - Transactional Templates](#transactional-templates) -* [Transient Fault Handling](#transient-faults) -* [How to Setup a Domain Whitelabel](#domain-whitelabel) -* [How to View Email Statistics](#email-stats) -* [How to transform HTML to plain text](#html-to-plain-text) +- [Table of Contents](#table-of-contents) +- [Attachments](#attachments) +- [Kitchen Sink - an example with all settings used](#kitchen-sink---an-example-with-all-settings-used) +- [Send a Single Email to Multiple Recipients](#send-a-single-email-to-multiple-recipients) +- [Send a Single Email to a Single Recipient](#send-a-single-email-to-a-single-recipient) +- [Send Multiple Emails to Multiple Recipients](#send-multiple-emails-to-multiple-recipients) +- [Transactional Templates](#transactional-templates) + - [With Mail Helper Class](#with-mail-helper-class) + - [Without Mail Helper Class](#without-mail-helper-class) +- [_Legacy_ Transactional Templates](#legacy-transactional-templates) + - [Legacy Template With Mail Helper Class](#legacy-template-with-mail-helper-class) + - [Legacy Template Without Mail Helper Class](#legacy-template-without-mail-helper-class) +- [Transient Fault Handling](#transient-fault-handling) + - [RetryCount](#retrycount) + - [MinimumBackOff](#minimumbackoff) + - [MaximumBackOff](#maximumbackoff) + - [DeltaBackOff](#deltabackoff) + - [Examples](#examples) +- [How to Setup a Domain Whitelabel](#how-to-setup-a-domain-whitelabel) +- [How to View Email Statistics](#how-to-view-email-statistics) +- [How to transform HTML to plain text](#how-to-transform-html-to-plain-text) # Attachments @@ -469,11 +480,178 @@ namespace Example ``` -# (LEGACY) Transactional Templates +# Transactional Templates -IF YOU ARE USING OUR NEW TEMPLATES, PLEASE SEE [THIS ISSUE](https://github.com/sendgrid/sendgrid-csharp/issues/716). +For this example, we assume you have created a [transactional template](https://sendgrid.com/docs/User_Guide/Transactional_Templates/Create_and_edit_dynamic_transactional_templates.html). +Following is the template content we used for testing. -For this example, we assume you have created a [transactional 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 +d-d42b0eea09964d1ab957c18986c01828 +``` + +Email Subject: + +```text +Dynamic Subject: {{subject}} +``` + +Template Body: + +```html + + + + + +Hello {{name}}, +

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

+I hope you are having a great day in {{location.city}} :) +

+ + +``` + +## With Mail Helper Class + +```csharp +using Newtonsoft.Json; +using SendGrid; +using SendGrid.Helpers.Mail; +using System.Threading.Tasks; +using System; + +namespace Example +{ + internal class Example + { + private static void Main() + { + Execute().Wait(); + } + + static async Task Execute() + { + var apiKey = Environment.GetEnvironmentVariable("NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY"); + var client = new SendGridClient(apiKey); + var msg = new SendGridMessage(); + msg.SetFrom(new EmailAddress("test@example.com", "Example User")); + msg.AddTo(new EmailAddress("test@example.com", "Example User")); + msg.SetTemplateId("d-d42b0eea09964d1ab957c18986c01828"); + + var dynamicTemplateData = new ExampleTemplateData + { + Subject = "Hi!", + Name = "Example User", + Location = new Location + { + City = "Birmingham", + Country = "United Kingdom" + } + }; + + msg.SetTemplateData(dynamicTemplateData); + var response = await client.SendEmailAsync(msg); + Console.WriteLine(response.StatusCode); + Console.WriteLine(response.Headers.ToString()); + Console.WriteLine("\n\nPress any key to exit."); + Console.ReadLine(); + } + + private class ExampleTemplateData + { + [JsonProperty("subject")] + public string Subject { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("location")] + public Location Location { get; set; } + } + + private class Location + { + [JsonProperty("city")] + public string City { get; set; } + + [JsonProperty("country")] + public string Country { get; set; } + } + } +} +``` + +Methods also exist on `MailHelper` to create dynamic template emails: +* `CreateSingleTemplateEmail` +* `CreateSingleTemplateEmailToMultipleRecipients` +* `CreateMultipleTemplateEmailsToMultipleRecipients` + +## Without Mail Helper Class + +```csharp +using Newtonsoft.Json; +using System.Threading.Tasks; +using System; +using SendGrid; + +namespace Example +{ + internal class Example + { + private static void Main() + { + Execute().Wait(); + } + + static async Task Execute() + { + var apiKey = Environment.GetEnvironmentVariable("NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY"); + var client = new SendGridClient(apiKey); + + string data = @"{ + 'personalizations': [ + { + 'to': [ + { + 'email': 'test@example.com' + } + ], + 'dynamic_template_data': { + 'subject': 'Hi!', + 'name': 'Example User', + 'location': { + 'city': 'Birmingham', + 'country': 'United Kingdom' + } + } + } + ], + 'from': { + 'email': 'test@example.com' + }, + 'template_id': 'd-d42b0eea09964d1ab957c18986c01828' + }"; + var json = JsonConvert.DeserializeObject(data); + var response = await client.RequestAsync(method: SendGridClient.Method.POST, + requestBody: json.ToString(), + urlPath: "mail/send"); + Console.WriteLine(response.StatusCode); + Console.WriteLine(response.Headers.ToString()); + Console.WriteLine("\n\nPress any key to exit."); + Console.ReadLine(); + } + } +} +``` + + +# _Legacy_ Transactional Templates + +For this example, we assume you have created a [legacy transactional 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): @@ -507,7 +685,7 @@ I hope you are having a great day in -city- :) ``` -## With Mail Helper Class +## Legacy Template With Mail Helper Class ```csharp using SendGrid; @@ -546,7 +724,7 @@ namespace Example } ``` -## Without Mail Helper Class +## Legacy Template Without Mail Helper Class ```csharp using Newtonsoft.Json; @@ -707,4 +885,4 @@ namespace Example { } } -``` \ No newline at end of file +``` diff --git a/src/SendGrid/Helpers/Mail/MailHelper.cs b/src/SendGrid/Helpers/Mail/MailHelper.cs index 81b1009e0..ec4ec158c 100644 --- a/src/SendGrid/Helpers/Mail/MailHelper.cs +++ b/src/SendGrid/Helpers/Mail/MailHelper.cs @@ -1,193 +1,302 @@ -// -// Copyright (c) SendGrid. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Collections.Generic; -using System.Text.RegularExpressions; - -namespace SendGrid.Helpers.Mail -{ - /// - /// Simplified email sending for common use cases - /// - public class MailHelper - { - private const string NameGroup = "name"; - private const string EmailGroup = "email"; - private static readonly Regex Rfc2822Regex = new Regex( - $@"(?:(?<{NameGroup}>)(?<{EmailGroup}>[^\<]*@.*[^\>])|(?<{NameGroup}>[^\<]*)\<(?<{EmailGroup}>.*@.*)\>)", - RegexOptions.ECMAScript); - - /// - /// Send a single simple email - /// - /// An email object that may contain the recipient’s name, but must always contain the sender’s email. - /// An email object that may contain the recipient’s name, but must always contain the recipient’s email. - /// The subject of your email. This may be overridden by SetGlobalSubject(). - /// The text/plain content of the email body. - /// The text/html content of the email body. - /// A SendGridMessage object. - public static SendGridMessage CreateSingleEmail( - EmailAddress from, - EmailAddress to, - string subject, - string plainTextContent, - string htmlContent) - { - var msg = new SendGridMessage(); - msg.SetFrom(from); - msg.SetSubject(subject); - if (!string.IsNullOrEmpty(plainTextContent)) - { - msg.AddContent(MimeType.Text, plainTextContent); - } - - if (!string.IsNullOrEmpty(htmlContent)) - { - msg.AddContent(MimeType.Html, htmlContent); - } - - msg.AddTo(to); - return msg; - } - - /// - /// Send a single simple email to multiple recipients - /// - /// An email object that may contain the recipient’s name, but must always contain the sender’s email. - /// A list of email objects that may contain the recipient’s name, but must always contain the recipient’s email. - /// The subject of your email. This may be overridden by SetGlobalSubject(). - /// The text/plain content of the email body. - /// The text/html content of the email body. - /// A SendGridMessage object. - public static SendGridMessage CreateSingleEmailToMultipleRecipients( - EmailAddress from, - List tos, - string subject, - string plainTextContent, - string htmlContent) - { - var msg = new SendGridMessage(); - msg.SetFrom(from); - msg.SetGlobalSubject(subject); - if (!string.IsNullOrEmpty(plainTextContent)) - { - msg.AddContent(MimeType.Text, plainTextContent); - } - - if (!string.IsNullOrEmpty(htmlContent)) - { - msg.AddContent(MimeType.Html, htmlContent); - } - - for (var i = 0; i < tos.Count; i++) - { - msg.AddTo(tos[i], i); - } - - return msg; - } - - /// - /// Send multiple emails to multiple recipients. - /// - /// An email object that may contain the recipient’s name, but must always contain the sender’s email. - /// A list of email objects that may contain the recipient’s name, but must always contain the recipient’s email. - /// The subject of your email. This may be overridden by SetGlobalSubject(). - /// The text/plain content of the email body. - /// The text/html content of the email body. - /// Substitution key/values to customize the content for each email. - /// A SendGridMessage object. - public static SendGridMessage CreateMultipleEmailsToMultipleRecipients( - EmailAddress from, - List tos, - List subjects, - string plainTextContent, - string htmlContent, - List> substitutions) - { - var msg = new SendGridMessage(); - msg.SetFrom(from); - if (!string.IsNullOrEmpty(plainTextContent)) - { - msg.AddContent(MimeType.Text, plainTextContent); - } - - if (!string.IsNullOrEmpty(htmlContent)) - { - msg.AddContent(MimeType.Html, htmlContent); - } - - for (var i = 0; i < tos.Count; i++) - { - msg.AddTo(tos[i], i); - msg.SetSubject(subjects[i], i); - msg.AddSubstitutions(substitutions[i], i); - } - - return msg; - } - - /// - /// Uncomplex conversion of a "]]> to EmailAddress - /// - /// "email@email.com" or "]]> string - /// EmailsAddress Object - public static EmailAddress StringToEmailAddress(string rfc2822Email) - { - var match = Rfc2822Regex.Match(rfc2822Email); - if (!match.Success) - { - return new EmailAddress(rfc2822Email); - } - - var email = match.Groups[EmailGroup].Value.Trim(); - var name = match.Groups[NameGroup].Value.Trim(); - return new EmailAddress(email, name); - } - - /// - /// Send a single simple email to multiple recipients with option for displaying all the recipients present in "To" section of email - /// - /// An email object that may contain the recipient’s name, but must always contain the sender’s email. - /// A list of email objects that may contain the recipient’s name, but must always contain the recipient’s email. - /// The subject of your email. This may be overridden by SetGlobalSubject(). - /// The text/plain content of the email body. - /// The text/html content of the email body. - /// Displays all the recipients present in the "To" section of email.The default value is false - /// A SendGridMessage object. - public static SendGridMessage CreateSingleEmailToMultipleRecipients( - EmailAddress from, - List tos, - string subject, - string plainTextContent, - string htmlContent, - bool showAllRecipients = false) - { - var msg = new SendGridMessage(); - if (showAllRecipients) - { - msg.SetFrom(from); - msg.SetGlobalSubject(subject); - if (!string.IsNullOrEmpty(plainTextContent)) - { - msg.AddContent(MimeType.Text, plainTextContent); - } - - if (!string.IsNullOrEmpty(htmlContent)) - { - msg.AddContent(MimeType.Html, htmlContent); - } - - msg.AddTos(tos); - } - else - { - msg = CreateSingleEmailToMultipleRecipients(from, tos, subject, plainTextContent, htmlContent); - } - - return msg; - } - } -} +// +// Copyright (c) SendGrid. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace SendGrid.Helpers.Mail +{ + /// + /// Simplified email sending for common use cases + /// + public class MailHelper + { + private const string NameGroup = "name"; + private const string EmailGroup = "email"; + private static readonly Regex Rfc2822Regex = new Regex( + $@"(?:(?<{NameGroup}>)(?<{EmailGroup}>[^\<]*@.*[^\>])|(?<{NameGroup}>[^\<]*)\<(?<{EmailGroup}>.*@.*)\>)", + RegexOptions.ECMAScript); + + /// + /// Send a single simple email + /// + /// An email object that may contain the recipient’s name, but must always contain the sender’s email. + /// An email object that may contain the recipient’s name, but must always contain the recipient’s email. + /// The subject of your email. This may be overridden by SetGlobalSubject(). + /// The text/plain content of the email body. + /// The text/html content of the email body. + /// A SendGridMessage object. + public static SendGridMessage CreateSingleEmail( + EmailAddress from, + EmailAddress to, + string subject, + string plainTextContent, + string htmlContent) + { + var msg = new SendGridMessage(); + msg.SetFrom(from); + msg.SetSubject(subject); + if (!string.IsNullOrEmpty(plainTextContent)) + { + msg.AddContent(MimeType.Text, plainTextContent); + } + + if (!string.IsNullOrEmpty(htmlContent)) + { + msg.AddContent(MimeType.Html, htmlContent); + } + + msg.AddTo(to); + return msg; + } + + /// + /// Send a single dynamic template email + /// + /// An email object that may contain the recipient’s name, but must always contain the sender’s email. + /// An email object that may contain the recipient’s name, but must always contain the recipient’s email. + /// The ID of the template. + /// The data with which to populate the dynamic template. + /// A SendGridMessage object. + public static SendGridMessage CreateSingleTemplateEmail( + EmailAddress from, + EmailAddress to, + string templateId, + object dynamicTemplateData) + { + if (string.IsNullOrWhiteSpace(templateId)) + { + throw new ArgumentException($"{nameof(templateId)} is required when creating a dynamic template email.", nameof(templateId)); + } + + var msg = new SendGridMessage(); + msg.SetFrom(from); + msg.AddTo(to); + msg.TemplateId = templateId; + + if (dynamicTemplateData != null) + { + msg.SetTemplateData(dynamicTemplateData); + } + + return msg; + } + + /// + /// Send a single simple email to multiple recipients + /// + /// An email object that may contain the recipient’s name, but must always contain the sender’s email. + /// A list of email objects that may contain the recipient’s name, but must always contain the recipient’s email. + /// The subject of your email. This may be overridden by SetGlobalSubject(). + /// The text/plain content of the email body. + /// The text/html content of the email body. + /// A SendGridMessage object. + public static SendGridMessage CreateSingleEmailToMultipleRecipients( + EmailAddress from, + List tos, + string subject, + string plainTextContent, + string htmlContent) + { + var msg = new SendGridMessage(); + msg.SetFrom(from); + msg.SetGlobalSubject(subject); + if (!string.IsNullOrEmpty(plainTextContent)) + { + msg.AddContent(MimeType.Text, plainTextContent); + } + + if (!string.IsNullOrEmpty(htmlContent)) + { + msg.AddContent(MimeType.Html, htmlContent); + } + + for (var i = 0; i < tos.Count; i++) + { + msg.AddTo(tos[i], i); + } + + return msg; + } + + /// + /// Send a single simple email to multiple recipients + /// + /// An email object that may contain the recipient’s name, but must always contain the sender’s email. + /// A list of email objects that may contain the recipient’s name, but must always contain the recipient’s email. + /// The ID of the template. + /// The data with which to populate the dynamic template. + /// A SendGridMessage object. + public static SendGridMessage CreateSingleTemplateEmailToMultipleRecipients( + EmailAddress from, + List tos, + string templateId, + object dynamicTemplateData) + { + if (string.IsNullOrWhiteSpace(templateId)) + { + throw new ArgumentException($"{nameof(templateId)} is required when creating a dynamic template email.", nameof(templateId)); + } + + var msg = new SendGridMessage(); + msg.SetFrom(from); + msg.TemplateId = templateId; + + var setDynamicTemplateDataValues = dynamicTemplateData != null; + + for (var i = 0; i < tos.Count; i++) + { + msg.AddTo(tos[i], i); + + if (setDynamicTemplateDataValues) + { + msg.SetTemplateData(dynamicTemplateData, i); + } + } + + return msg; + } + + /// + /// Send multiple emails to multiple recipients. + /// + /// An email object that may contain the recipient’s name, but must always contain the sender’s email. + /// A list of email objects that may contain the recipient’s name, but must always contain the recipient’s email. + /// The subject of your email. This may be overridden by SetGlobalSubject(). + /// The text/plain content of the email body. + /// The text/html content of the email body. + /// Substitution key/values to customize the content for each email. + /// A SendGridMessage object. + public static SendGridMessage CreateMultipleEmailsToMultipleRecipients( + EmailAddress from, + List tos, + List subjects, + string plainTextContent, + string htmlContent, + List> substitutions) + { + var msg = new SendGridMessage(); + msg.SetFrom(from); + if (!string.IsNullOrEmpty(plainTextContent)) + { + msg.AddContent(MimeType.Text, plainTextContent); + } + + if (!string.IsNullOrEmpty(htmlContent)) + { + msg.AddContent(MimeType.Html, htmlContent); + } + + for (var i = 0; i < tos.Count; i++) + { + msg.AddTo(tos[i], i); + msg.SetSubject(subjects[i], i); + msg.AddSubstitutions(substitutions[i], i); + } + + return msg; + } + + /// + /// Send multiple emails to multiple recipients. + /// + /// An email object that may contain the recipient’s name, but must always contain the sender’s email. + /// A list of email objects that may contain the recipient’s name, but must always contain the recipient’s email. + /// The ID of the template. + /// The data with which to populate the dynamic template. + /// A SendGridMessage object. + public static SendGridMessage CreateMultipleTemplateEmailsToMultipleRecipients( + EmailAddress from, + List tos, + string templateId, + List dynamicTemplateData) + { + if (string.IsNullOrWhiteSpace(templateId)) + { + throw new ArgumentException($"{nameof(templateId)} is required when creating a dynamic template email.", nameof(templateId)); + } + + var msg = new SendGridMessage(); + msg.SetFrom(from); + msg.TemplateId = templateId; + + var setDynamicTemplateDataValues = dynamicTemplateData != null; + + for (var i = 0; i < tos.Count; i++) + { + msg.AddTo(tos[i], i); + + if (setDynamicTemplateDataValues) + { + msg.SetTemplateData(dynamicTemplateData[i], i); + } + } + + return msg; + } + + /// + /// Uncomplex conversion of a "]]> to EmailAddress + /// + /// "email@email.com" or "]]> string + /// EmailsAddress Object + public static EmailAddress StringToEmailAddress(string rfc2822Email) + { + var match = Rfc2822Regex.Match(rfc2822Email); + if (!match.Success) + { + return new EmailAddress(rfc2822Email); + } + + var email = match.Groups[EmailGroup].Value.Trim(); + var name = match.Groups[NameGroup].Value.Trim(); + return new EmailAddress(email, name); + } + + /// + /// Send a single simple email to multiple recipients with option for displaying all the recipients present in "To" section of email + /// + /// An email object that may contain the recipient’s name, but must always contain the sender’s email. + /// A list of email objects that may contain the recipient’s name, but must always contain the recipient’s email. + /// The subject of your email. This may be overridden by SetGlobalSubject(). + /// The text/plain content of the email body. + /// The text/html content of the email body. + /// Displays all the recipients present in the "To" section of email.The default value is false + /// A SendGridMessage object. + public static SendGridMessage CreateSingleEmailToMultipleRecipients( + EmailAddress from, + List tos, + string subject, + string plainTextContent, + string htmlContent, + bool showAllRecipients = false) + { + var msg = new SendGridMessage(); + if (showAllRecipients) + { + msg.SetFrom(from); + msg.SetGlobalSubject(subject); + if (!string.IsNullOrEmpty(plainTextContent)) + { + msg.AddContent(MimeType.Text, plainTextContent); + } + + if (!string.IsNullOrEmpty(htmlContent)) + { + msg.AddContent(MimeType.Html, htmlContent); + } + + msg.AddTos(tos); + } + else + { + msg = CreateSingleEmailToMultipleRecipients(from, tos, subject, plainTextContent, htmlContent); + } + + return msg; + } + } +} diff --git a/src/SendGrid/Helpers/Mail/Model/Personalization.cs b/src/SendGrid/Helpers/Mail/Model/Personalization.cs index 29705ec90..f4c1f659a 100644 --- a/src/SendGrid/Helpers/Mail/Model/Personalization.cs +++ b/src/SendGrid/Helpers/Mail/Model/Personalization.cs @@ -63,5 +63,11 @@ public class Personalization /// [JsonProperty(PropertyName = "send_at")] public long? SendAt { get; set; } + + /// + /// Gets or sets the template data object following the pattern "template data key":"template data value". All are assumed to be strings. These key value pairs will apply to the content of your template email, in addition to the subject and reply-to parameters. + /// + [JsonProperty(PropertyName = "dynamic_template_data", IsReference = false)] + public object TemplateData { get; set; } } } diff --git a/src/SendGrid/Helpers/Mail/SendGridMessage.cs b/src/SendGrid/Helpers/Mail/SendGridMessage.cs index dd19a2ded..c9a385446 100644 --- a/src/SendGrid/Helpers/Mail/SendGridMessage.cs +++ b/src/SendGrid/Helpers/Mail/SendGridMessage.cs @@ -756,6 +756,57 @@ public void AddSubstitutions(Dictionary substitutions, int perso return; } + /// + /// Add dynamic template data to the email. + /// + /// A Template Data object. + /// Specify the index of the Personalization object where you want to add the substitutions. + /// A personalization object to append to the message. + public void SetTemplateData(object dynamicTemplateData, int personalizationIndex = 0, Personalization personalization = null) + { + if (personalization != null) + { + personalization.TemplateData = dynamicTemplateData; + if (this.Personalizations == null) + { + this.Personalizations = new List(); + this.Personalizations.Add(personalization); + } + else + { + this.Personalizations.Add(personalization); + } + + return; + } + + if (this.Personalizations != null) + { + if (this.Personalizations[personalizationIndex] == null) + { + var p = new Personalization(); + this.Personalizations.Insert(personalizationIndex, p); + } + + if (this.Personalizations[personalizationIndex].TemplateData == null) + { + this.Personalizations[personalizationIndex].TemplateData = new Dictionary(); + } + + this.Personalizations[personalizationIndex].TemplateData = dynamicTemplateData; + return; + } + + this.Personalizations = new List() + { + new Personalization() + { + TemplateData = dynamicTemplateData + } + }; + return; + } + /// /// Add a custom argument to the email. /// diff --git a/tests/SendGrid.Tests/Helpers/Mail/MailHelperTests.cs b/tests/SendGrid.Tests/Helpers/Mail/MailHelperTests.cs new file mode 100644 index 000000000..7f616180b --- /dev/null +++ b/tests/SendGrid.Tests/Helpers/Mail/MailHelperTests.cs @@ -0,0 +1,105 @@ +using SendGrid.Helpers.Mail; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace SendGrid.Tests.Helpers.Mail +{ + public class MailHelperTests + { + [Theory] + [InlineData("Name Of A Person+", "send@grid.com", "Name Of A Person+ < send@grid.com > ")] + [InlineData("", "send@grid.com", " send@grid.com ")] + [InlineData(null, "notAValidEmail", "notAValidEmail")] + public void TestStringToEmail(string expectedName, string expectedEmail, string rf2822Email) + { + var address = MailHelper.StringToEmailAddress(rf2822Email); + Assert.Equal(expectedEmail, address.Email); + Assert.Equal(expectedName, address.Name); + } + + [Fact] + public void TestCreateSingleTemplateEmail() + { + var from = new EmailAddress("from@email.com", "FromName"); + var to = new EmailAddress("to@email.com"); + var templateId = "d-template1"; + var dynamicTemplateData = new Dictionary + { + { "key1", "value1" } + }; + + var sendGridMessage = MailHelper.CreateSingleTemplateEmail( + from, + to, + templateId, + dynamicTemplateData); + + Assert.Equal(from, sendGridMessage.From); + Assert.Equal(to, sendGridMessage.Personalizations.Single().Tos.Single()); + Assert.Equal(templateId, sendGridMessage.TemplateId); + Assert.Equal(dynamicTemplateData, sendGridMessage.Personalizations.Single().TemplateData); + } + + [Fact] + public void TestCreateSingleTemplateEmailToMultipleRecipients() + { + var from = new EmailAddress("from@email.com", "FromName"); + var tos = new List + { + new EmailAddress("to1@email.com"), + new EmailAddress("to2@email.com") + }; + + var templateId = "d-template2"; + var dynamicTemplateData = new Dictionary + { + { "key1", "value1" } + }; + + var sendGridMessage = MailHelper.CreateSingleTemplateEmailToMultipleRecipients( + from, + tos, + templateId, + dynamicTemplateData); + + Assert.Equal(from, sendGridMessage.From); + Assert.Equal(tos[0], sendGridMessage.Personalizations.ElementAt(0).Tos.Single()); + Assert.Equal(tos[1], sendGridMessage.Personalizations.ElementAt(1).Tos.Single()); + Assert.Equal(templateId, sendGridMessage.TemplateId); + Assert.Equal(dynamicTemplateData, sendGridMessage.Personalizations.ElementAt(0).TemplateData); + Assert.Equal(dynamicTemplateData, sendGridMessage.Personalizations.ElementAt(1).TemplateData); + } + + [Fact] + public void TestCreateMultipleTemplateEmailsToMultipleRecipients() + { + var from = new EmailAddress("from@email.com", "FromName"); + var tos = new List + { + new EmailAddress("to1@email.com"), + new EmailAddress("to2@email.com") + }; + + var templateId = "d-template2"; + var dynamicTemplateData = new List + { + new { key1 = "value1" }, + new { key2 = "value2" } + }; + + var sendGridMessage = MailHelper.CreateMultipleTemplateEmailsToMultipleRecipients( + from, + tos, + templateId, + dynamicTemplateData); + + Assert.Equal(from, sendGridMessage.From); + Assert.Equal(tos[0], sendGridMessage.Personalizations.ElementAt(0).Tos.Single()); + Assert.Equal(tos[1], sendGridMessage.Personalizations.ElementAt(1).Tos.Single()); + Assert.Equal(templateId, sendGridMessage.TemplateId); + Assert.Equal(dynamicTemplateData[0], sendGridMessage.Personalizations.ElementAt(0).TemplateData); + Assert.Equal(dynamicTemplateData[1], sendGridMessage.Personalizations.ElementAt(1).TemplateData); + } + } +} diff --git a/tests/SendGrid.Tests/Integration.cs b/tests/SendGrid.Tests/Integration.cs index 582c61a0e..7a972dd4d 100644 --- a/tests/SendGrid.Tests/Integration.cs +++ b/tests/SendGrid.Tests/Integration.cs @@ -1658,6 +1658,135 @@ public void TestAddSubstitutions() Assert.True(msg.Serialize() == "{\"personalizations\":[{\"substitutions\":{\"-sub28-\":\"Substituted Value 28\",\"-sub29-\":\"Substituted Value 29\",\"-sub32-\":\"Substituted Value 32\",\"-sub33-\":\"Substituted Value 33\"}},{\"substitutions\":{\"-sub30-\":\"Substituted Value 30\",\"-sub31-\":\"Substituted Value 31\"}}]}"); } + [Fact] + public void TestSetTemplateData() + { + // Personalization not passed in, Personalization does not exist + var msg = new SendGridMessage(); + var dynamicTemplateData1 = new + { + key12 = "Dynamic Template Data Value 12", + key13 = "Dynamic Template Data Value 13" + }; + msg.SetTemplateData(dynamicTemplateData1); + Assert.True(msg.Serialize() == "{\"personalizations\":[{\"dynamic_template_data\":{\"key12\":\"Dynamic Template Data Value 12\",\"key13\":\"Dynamic Template Data Value 13\"}}]}"); + + // Personalization passed in, no Personalizations + msg = new SendGridMessage(); + var dynamicTemplateData2 = new + { + key14 = "Dynamic Template Data Value 14", + key15 = "Dynamic Template Data Value 15" + }; + var personalization = new Personalization() + { + TemplateData = dynamicTemplateData2 + }; + var dynamicTemplateData3 = new + { + key16 = "Dynamic Template Data Value 16", + key17 = "Dynamic Template Data Value 17" + }; + msg.SetTemplateData(dynamicTemplateData3, 0, personalization); + Assert.True(msg.Serialize() == "{\"personalizations\":[{\"dynamic_template_data\":{\"key16\":\"Dynamic Template Data Value 16\",\"key17\":\"Dynamic Template Data Value 17\"}}]}"); + + // Personalization passed in, Personalization exists + msg = new SendGridMessage(); + var dynamicTemplateData4 = new + { + key18 = "Dynamic Template Data Value 18", + key19 = "Dynamic Template Data Value 19" + }; + msg.Personalizations = new List() { + new Personalization() { + TemplateData = dynamicTemplateData4 + } + }; + var dynamicTemplateData5 = new + { + key20 = "Dynamic Template Data Value 20", + key21 = "Dynamic Template Data Value 21" + }; + personalization = new Personalization() + { + TemplateData = dynamicTemplateData5 + }; + var dynamicTemplateData6 = new + { + key22 = "Dynamic Template Data Value 22", + key23 = "Dynamic Template Data Value 23" + }; + msg.SetTemplateData(dynamicTemplateData6, 1, personalization); + Assert.True(msg.Serialize() == "{\"personalizations\":[{\"dynamic_template_data\":{\"key18\":\"Dynamic Template Data Value 18\",\"key19\":\"Dynamic Template Data Value 19\"}},{\"dynamic_template_data\":{\"key22\":\"Dynamic Template Data Value 22\",\"key23\":\"Dynamic Template Data Value 23\"}}]}"); + + // Personalization not passed in Personalization exists + msg = new SendGridMessage(); + var dynamicTemplateData7 = new + { + key24 = "Dynamic Template Data Value 24", + key25 = "Dynamic Template Data Value 25" + }; + msg.Personalizations = new List() { + new Personalization() { + TemplateData = dynamicTemplateData7 + } + }; + var dynamicTemplateData8 = new + { + key26 = "Dynamic Template Data Value 26", + key27 = "Dynamic Template Data Value 27" + }; + msg.SetTemplateData(dynamicTemplateData8); + Assert.True(msg.Serialize() == "{\"personalizations\":[{\"dynamic_template_data\":{\"key26\":\"Dynamic Template Data Value 26\",\"key27\":\"Dynamic Template Data Value 27\"}}]}"); + + // Personalization not passed in Personalizations exists + msg = new SendGridMessage(); + var dynamicTemplateData9 = new + { + key28 = "Dynamic Template Data Value 28", + key29 = "Dynamic Template Data Value 29" + }; + msg.Personalizations = new List() { + new Personalization() { + TemplateData = dynamicTemplateData9 + } + }; + var dynamicTemplateData10 = new + { + key30 = "Dynamic Template Data Value 30", + key31 = "Dynamic Template Data Value 31" + }; + personalization = new Personalization() + { + TemplateData = dynamicTemplateData10 + }; + msg.Personalizations.Add(personalization); + var dynamicTemplateData11 = new + { + key32 = "Dynamic Template Data Value 32", + key33 = "Dynamic Template Data Value 33" + }; + msg.SetTemplateData(dynamicTemplateData11); + Assert.True(msg.Serialize() == "{\"personalizations\":[{\"dynamic_template_data\":{\"key32\":\"Dynamic Template Data Value 32\",\"key33\":\"Dynamic Template Data Value 33\"}},{\"dynamic_template_data\":{\"key30\":\"Dynamic Template Data Value 30\",\"key31\":\"Dynamic Template Data Value 31\"}}]}"); + + // Complex dynamic template data + msg = new SendGridMessage(); + var dynamicTemplateData12 = new + { + array = new List + { + "Dynamic Template Data Array Value 1", + "Dynamic Template Data Array Value 2" + }, + innerObject = new + { + innerObjectKey1 = "Dynamic Template Data Deep Object Value 1" + } + }; + msg.SetTemplateData(dynamicTemplateData12); + Assert.True(msg.Serialize() == "{\"personalizations\":[{\"dynamic_template_data\":{\"array\":[\"Dynamic Template Data Array Value 1\",\"Dynamic Template Data Array Value 2\"],\"innerObject\":{\"innerObjectKey1\":\"Dynamic Template Data Deep Object Value 1\"}}}]}"); + } + [Fact] public void TestAddCustomArg() { @@ -6068,18 +6197,4 @@ public override HttpResponseMessage Send(HttpRequestMessage request) throw new TimeoutException(exceptionMessage); } } - - public class MailHelperTests - { - [Theory] - [InlineData("Name Of A Person+", "send@grid.com", "Name Of A Person+ < send@grid.com > ")] - [InlineData("", "send@grid.com", " send@grid.com ")] - [InlineData(null, "notAValidEmail", "notAValidEmail")] - public void TestStringToEmail(string expectedName, string expectedEmail, string rf2822Email) - { - var address = MailHelper.StringToEmailAddress(rf2822Email); - Assert.Equal(expectedEmail, address.Email); - Assert.Equal(expectedName, address.Name); - } - } } diff --git a/tests/SendGrid.Tests/SendGrid.Tests.csproj b/tests/SendGrid.Tests/SendGrid.Tests.csproj index bb33bee10..6ba268cc7 100644 --- a/tests/SendGrid.Tests/SendGrid.Tests.csproj +++ b/tests/SendGrid.Tests/SendGrid.Tests.csproj @@ -1,31 +1,31 @@ - - - - netcoreapp1.0 - SendGrid.Tests - SendGrid.Tests - true - 1.0.4 - false - false - false - - - - - - - - - - - - - - - - - - - - + + + + netcoreapp1.0 + SendGrid.Tests + SendGrid.Tests + true + 1.0.4 + false + false + false + + + + + + + + + + + + + + + + + + + + diff --git a/tests/SendGrid.Tests/TemplateDataSerialisationTests.cs b/tests/SendGrid.Tests/TemplateDataSerialisationTests.cs new file mode 100644 index 000000000..83137c4d1 --- /dev/null +++ b/tests/SendGrid.Tests/TemplateDataSerialisationTests.cs @@ -0,0 +1,40 @@ +using Newtonsoft.Json; +using SendGrid.Helpers.Mail; +using Xunit; + +namespace SendGrid.Tests +{ + public class TemplateDataSerialisationTests + { + [Fact] + public void TestSetTemplateDataWorksWithSpecifiedJsonPropertyNames() + { + var msg = new SendGridMessage(); + + var dynamicTemplateData = new TestTemplateData + { + MyCamelCaseProperty = "camelCase", + MyKebabCaseProperty = "kebab-case", + MyPascalCaseProperty = "PascalCase", + MySnakeCaseProperty = "snake_case", + }; + + msg.SetTemplateData(dynamicTemplateData); + Assert.Equal("{\"personalizations\":[{\"dynamic_template_data\":{\"myCamelCaseProperty\":\"camelCase\",\"my-kebab-case-property\":\"kebab-case\",\"MyPascalCaseProperty\":\"PascalCase\",\"my_snake_case_property\":\"snake_case\"}}]}", msg.Serialize()); + } + + private class TestTemplateData + { + [JsonProperty("myCamelCaseProperty")] + public string MyCamelCaseProperty { get; set; } + + [JsonProperty("my-kebab-case-property")] + public string MyKebabCaseProperty { get; set; } + + public string MyPascalCaseProperty { get; set; } + + [JsonProperty("my_snake_case_property")] + public string MySnakeCaseProperty { get; set; } + } + } +}