Search code examples
c#.netamazon-web-servicesaws-cliaws-sdk-net

How do I correctly use the SendBulkTemplatedEmailRequest from SES in the AWS-SDK-NET?


I am attempting to use the AmazonSimpleEmailService client via the AWS-SDK for .Net, to send a SendBulkTempatedEmailRequest. I have implemented a dedicated handler for actually building the request and making the SendBulkTemplatedEmailAsync call. It is not working as I expect. I think there is a bug with how the request object is serialized and passed to the API.

Here is some sample code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Amazon.SimpleEmail;
using Amazon.SimpleEmail.Model;
using Newtonsoft.Json;

namespace Sample.AWS.SES
{
  public class SendEmailService
  {   
    private readonly IAmazonSimpleEmailService _sesClient;

    public SendEmailService(IAmazonSimpleEmailService sesClient)
    {
      _sesClient = sesClient;
    }

    public async Task<string> SendBulkEmailAsync(SesOrderCreatedBulkTemplate data)
    {
      var result = string.Empty;
      var request = new SendBulkTemplatedEmailRequest
      {
        Template = data.Template,
        ConfigurationSetName = data.ConfigurationSet,
        DefaultTemplateData = JsonConvert.SerializeObject(data.DefaultTemplateData),
        Source = data.Source,
        Destinations = data.Destinations
          .Select(d => new BulkEmailDestination
          {
            Destination = new Destination
            {
              ToAddresses = d.ToAddresses.ToList(),
            },
            ReplacementTemplateData = string.Empty
          })
          .ToList(),
        ReplyToAddresses = data.ReplyToAddresses.ToList()
      };

      try
      {
        var resp = await _sesClient.SendBulkTemplatedEmailAsync(request);
      }
      catch (Exception ex)
      {
        var msgEx = new Exception("Error sending message to SES.", ex);
        throw msgEx;
      }
      return result;
    }

    public class SesOrderCreatedBulkTemplate
    {
      public string Source { get; set; }
      public string Template { get; set; }
      public string ConfigurationSet { get; set; }
      public IEnumerable<Destination> Destinations { get; set; }
      public MyTemplateData DefaultTemplateData { get; set; }
      public IEnumerable<string> ReplyToAddresses { get; set; }
      public string ReturnPath { get; set; } = string.Empty;
    }

    public class DestinationObj
    {
      public IEnumerable<string> ToAddresses { get; set; }
      public MyTemplateData ReplacementTemplateData { get; set; }

      public DestinationObj() {}
    }

    public class MyTemplateData
    {
      public List<Person> Tenants { get; set; }
    }

    public class Person
    {
      public string PersonName { get; set; }
      public List<object> PersonData { get; set; }
    }
  }
}

The properties for SourceArn, TemplateArn and ReturnPathArn are omitted on purpose. According the SES documentation, the SDK wraps the low-level functionality of the Amazon SES API with higher-level data types and function calls that take care of the details for you. When I view the API documentation for sending bulk email, the ARN properties are all list as not required. When I look at the some CLI examples, it is the same. When I look at the documentation for the SDK for .Net v3, it is ambiguous (not marked as required or optional).

Because the SDK supposed to wrap the low-level functionality of the API, I do not believe the ARN values are required (neither the API nor the CLI require them). However, when I attempt to actually use the request object created in the code snippet, I get an error that says InvalidTemplateData.

If I serialize the request object to JSON, then remove the 3 ARN fields from the string, I can use either the API or the CLI to successfully send the message.

In addition to not specifying a value for the ARN's, I have tried (for all 3 ARN values):

specificArn = string.empty; specificArn = new {}; specificArn = "";

I have also tried explicitly newing-up the object separate from initializing the properties:
var request = new SendBulkTemplatedEmailRequest();, and then individually populating the properties.

If I don't initialize the ARN values, I get an error about NoneType vs StringType when the send method is called. The variations on string initialization that I tried result in InvalidTemplateData errors.

Note, I do know ARN values for Source and ReturnPath. I do not have an ARN value for the template we use. Supposedly, using the CLI, when you create a template you should receive a response back that includes the ARN for the template. I get no response from the CLI when I create a template, but it does get created every time I try. The describe-template CLI command is not valid when you specify SES and responds with an error if I don't specify the workspace (whatever you call the SES space) value.

Does anyone have a suggestion on how to solve this?


Solution

  • In the end, I was able to verify with AWS that there was a bug in the SDK for .Net. I switched to using the API instead of the SDK for our solution.