재우니의 블로그


ASP.NET MVC 에서 AWS SES 의 BOUNCE 응답값 HEADERS 안의 BODY 파싱하기

POST / HTTP/1.1

x-amz-sns-message-type: Notification x-amz-sns-message-id: 22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324 x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96 Content-Length: 773 Content-Type: text/plain; charset=UTF-8 Host: example.com Connection: Keep-Alive User-Agent: Amazon Simple Notification Service Agent { "Type" : "Notification", "MessageId" : "22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324", "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic", "Subject" : "My First Message", "Message" : "Hello world!", "Timestamp" : "2012-05-02T00:54:06.655Z", "SignatureVersion" : "1", "Signature" : "EXAMPLEw6JRNwm1LFQL4ICB0bnXrdB8ClRMTQFGBqwLpGbM78tJ4etTwC5zU7O3tS6tGpey3ejedNdOJ+1fkIp9F2/LmNVKb5aFlYq+9rk9ZiPph5YlLmWsDcyC5T+Sy9/umic5S0UQc2PEtgdpVBahwNOdMW4JPwk0kAJJztnc=", "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem", "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96" }


MODEL 을 위의 JSON 형태로 구성합니다.

public class BouncedEntity
{
public string Type { get; set; }
public string MessageId { get; set; }
public string Token { get; set; }
public string TopicArn { get; set; }
public string Message { get; set; }
public string SubscribeURL { get; set; }
public DateTime Timestamp { get; set; }
public string SignatureVersion { get; set; }
public string Signature { get; set; }
public string SigningCertURL { get; set; }
}


이제 CONTROLLER 에서 HEADER 값을 가져오는 구문이며, BODY 의 JSON 은 MODEL 에 담습니다.

담을때 JsonConvert.DeserializeObject<BouncedEntity>(jsonData); 구문으로 간단히 담을 수 있습니다. 다중 값이면 제네릭 LIST<> 를 기술하여 사용하시면 됩니다.

var xmessageType = Request.Headers["x-amz-sns-message-type"];
var xmessageid = Request.Headers["x-amz-sns-message-id"];
var xtopicarn = Request.Headers["x-amz-sns-topic-arn"];
var xsubscriptionarn = Request.Headers["x-amz-sns-subscription-arn"];

Request.InputStream.Seek(0, SeekOrigin.Begin);
string jsonData = new StreamReader(Request.InputStream).ReadToEnd();

var modelBounced = JsonConvert.DeserializeObject<BouncedEntity>(jsonData);



전체 소스


using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
using (StreamReader r = new StreamReader(@"D:\SampleSource\ConsoleApp1\ConsoleApp1\notice.json"))
{
string jsonString = r.ReadToEnd();
var modelMain = JsonConvert.DeserializeObject<RootMain>(jsonString);

Console.WriteLine(modelMain.Type);
Console.WriteLine(modelMain.MessageId);
Console.WriteLine(modelMain.Token);
Console.WriteLine(modelMain.TopicArn);
//Console.WriteLine(modelMain.Message);
Console.WriteLine(modelMain.SubscribeURL);
Console.WriteLine(modelMain.SignatureVersion);
Console.WriteLine(modelMain.Signature);
Console.WriteLine(modelMain.SigningCertURL);
Console.WriteLine(modelMain.UnsubscribeURL);


if (modelMain.Type == "Notification")
{
var modelBounced = JsonConvert.DeserializeObject<RootMessageJson>(modelMain.Message);

Console.WriteLine(modelBounced.notificationType); //Bounce

if (modelBounced.bounce.bouncedRecipients.Count() > 0)
{
Console.WriteLine(modelBounced.bounce.bouncedRecipients[0].action); //failed
Console.WriteLine(modelBounced.bounce.bouncedRecipients[0].diagnosticCode); //smtp; 505 this account is unknown user~
Console.WriteLine(modelBounced.bounce.bouncedRecipients[0].emailAddress); //xxxxx@univ.me
Console.WriteLine(modelBounced.bounce.bouncedRecipients[0].status); //5.3.0
}

Console.WriteLine(modelBounced.mail.messageId);
Console.WriteLine(modelBounced.mail.sendingAccountId);
Console.WriteLine(modelBounced.mail.source);
Console.WriteLine(modelBounced.mail.sourceArn);
Console.WriteLine(modelBounced.mail.sourceIp);
Console.WriteLine(modelBounced.mail.timestamp);

Console.WriteLine(modelBounced.mail.commonHeaders.subject);
}
}


Console.ReadKey();
}



}

public class RootMain
{
public string Type { get; set; } = "";
public string MessageId { get; set; } = "";
public string Token { get; set; } = "";
public string TopicArn { get; set; } = "";
public string Message { get; set; } = "";
public string SubscribeURL { get; set; } = "";
public DateTime Timestamp { get; set; }
public string SignatureVersion { get; set; } = "";
public string Signature { get; set; } = "";
public string SigningCertURL { get; set; } = "";
public string UnsubscribeURL { get; set; } = "";

}

/// <summary>
/// TYPE 이 Notification 경우, Message 의 json 값 object 할당하기
/// </summary>
public class RootMessageJson
{
public string notificationType { get; set; } = "";
public Bounced bounce { get; set; }
public Mail mail { get; set; }
}

public class BouncedRecipient
{
public string emailAddress { get; set; } = "";
public string action { get; set; } = "";
public string status { get; set; } = "";
public string diagnosticCode { get; set; } = "";
}

public class Bounced
{
public string bounceType { get; set; } = "";
public string bounceSubType { get; set; } = "";
public List<BouncedRecipient> bouncedRecipients { get; set; }
public DateTime timestamp { get; set; }
public string feedbackId { get; set; } = "";
public string remoteMtaIp { get; set; } = "";
public string reportingMTA { get; set; } = "";
}

public class Header
{
public string name { get; set; } = "";
public string value { get; set; } = "";
}

public class CommonHeaders
{
public List<string> from { get; set; }
public List<string> to { get; set; }
public string subject { get; set; } = "";
}

public class Mail
{
public DateTime timestamp { get; set; }
public string source { get; set; } = "";
public string sourceArn { get; set; } = "";
public string sourceIp { get; set; } = "";
public string sendingAccountId { get; set; } = "";
public string messageId { get; set; } = "";
public List<string> destination { get; set; }
public bool headersTruncated { get; set; }
public List<Header> headers { get; set; }
public CommonHeaders commonHeaders { get; set; }
}

}