0

我正在尝试通过适用于 .Net 的 AWS-SDK使用AmazonSimpleEmailService客户端来发送SendBulkTempatedEmailRequest。我已经实现了一个专门的处理程序来实际构建请求并进行SendBulkTemplatedEmailAsync调用。它没有按我的预期工作。我认为请求对象如何序列化并传递给 API 存在错误。

这是一些示例代码:

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; }
    }
  }
}

SourceArn的属性被故意省略。根据SES 文档,开发工具包将 Amazon SES API 的低级功能与高级数据类型和函数调用封装在一起,为您处理细节。当我查看用于发送批量电子邮件的 API 文档时,ARN 属性都列出为不需要的。当我查看一些CLI 示例时,它是相同的。当我查看SDK for .Net v3的文档时,它是模棱两可的(未标记为必需或可选)。TemplateArnReturnPathArn

因为 SDK 应该包装 API 的低级功能,所以我不认为 ARN 值是必需的(API 和 CLI 都不需要它们)。但是,当我尝试实际使用在代码片段中创建的请求对象时,我收到一条错误消息,提示InvalidTemplateData.

如果我将请求对象序列化为 JSON,然后从字符串中删除 3 个 ARN 字段,我可以使用 API 或 CLI 成功发送消息。

除了没有为 ARN 指定值之外,我还尝试过(对于所有 3 个 ARN 值):

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

我还尝试过将对象与初始化属性分开显式更新:
var request = new SendBulkTemplatedEmailRequest();,然后单独填充属性。

如果我不初始化 ARN 值,则在调用 send 方法时会收到有关NoneTypeStringType的错误。我尝试的字符串初始化变化导致InvalidTemplateData错误。

请注意,我确实知道 Source 和 ReturnPath 的 ARN 值。我没有我们使用的模板的 ARN 值。假设使用 CLI,当您创建模板时,您应该收到包含模板 ARN 的响应。创建模板时,CLI 没有响应,但每次尝试时都会创建它。当describe-template您指定 SES 时,CLI 命令无效,如果我未指定工作区(无论您如何称呼 SES 空间)值,则会以错误响应。

有人对如何解决这个问题有建议吗?

4

1 回答 1

1

从提供的代码中很难说出您传递给 API 的内容。

这就是我发送批量电子邮件的方式:

SES 配置

  • 创建一个模板(取自AWS SES文档)并将其保存到文件中 -my-template.json
{
  "Template": {
    "TemplateName": "my-template",
    "SubjectPart": "Greetings, {{name}}!",
    "HtmlPart": "<h1>Hello {{name}},</h1><p>Your favorite animal is {{favoriteanimal}}.</p>",
    "TextPart": "Dear {{name}},\r\nYour favorite animal is {{favoriteanimal}}."
  }
}
  • 通过 CLI 创建模板 aws ses create-template --cli-input-json file://my-template.json

SES .NET SDK API

async Task SendAsync(string[] receivers)
{
    var destinations = receivers
        .Select(receiver => new BulkEmailDestination
        {
            Destination = new Destination(new List<string> { receiver }),
            ReplacementTemplateData = ToJson(receiver, "Doggy")
        })
        .ToList();
    
    var bulkTemplate = new SendBulkTemplatedEmailRequest
    {
        Source = "your-email@gmail.com", // your email you bulk send from
        Template = "my-template",        // your template name
        DefaultTemplateData = ToJson("<not set>", "<not set>"),
        Destinations = destinations
    };
    await _client.SendBulkTemplatedEmailAsync(bulkTemplate);
}

// Create replacement data by serializing Dictionary
string ToJson(string name, string favoriteanimal)
    => JsonSerializer.Serialize(new Dictionary<string, string>
    {
        { "name", name },
        { "favoriteanimal", favoriteanimal }
    });
于 2020-10-13T08:32:49.810 回答