Отправить вложения с Amazon-SES - PullRequest
21 голосов
/ 19 июля 2011

Я ищу работающий пример C # для отправки вложений с Amazon-SES.

После прочтения этого Amazon-SES теперь поддерживает отправку вложений. Я искал пример C #, ноне смог найти.

Ответы [ 7 ]

17 голосов
/ 07 января 2016

Я думаю, что использование AWS SDK для .NET и MimeKit - очень простое и чистое решение.Вы можете отправлять электронные письма с вложениями через SES API (вместо SMTP).

Вы можете написать MimeMessage непосредственно в MemoryStream и затем использовать его с SES SendRawEmail:

using Amazon.SimpleEmail;
using Amazon.SimpleEmail.Model;
using Amazon;
using Amazon.Runtime;
using MimeKit;

private static BodyBuilder GetMessageBody()
{
    var body = new BodyBuilder()
    {
        HtmlBody = @"<p>Amazon SES Test body</p>",
        TextBody = "Amazon SES Test body",
    };
    body.Attachments.Add(@"c:\attachment.txt");
    return body;
}

private static MimeMessage GetMessage()
{
    var message = new MimeMessage();
    message.From.Add(new MailboxAddress("Foo Bar", "foo@bar.com"));
    message.To.Add(new MailboxAddress(string.Empty, "foobar@example.com"));
    message.Subject = "Amazon SES Test";
    message.Body = GetMessageBody().ToMessageBody();
    return message;
}

private static MemoryStream GetMessageStream()
{
    var stream = new MemoryStream();
    GetMessage().WriteTo(stream);
    return stream;
}

private void SendEmails()
{
    var credentals = new BasicAWSCredentials("<aws-access-key>", "<aws-secret-key>");

    using (var client = new AmazonSimpleEmailServiceClient(credentals, RegionEndpoint.EUWest1))
    {
        var sendRequest = new SendRawEmailRequest { RawMessage = new RawMessage(GetMessageStream()) };
        try
        {
            var response = client.SendRawEmail(sendRequest);
            Console.WriteLine("The email was sent successfully.");
        }
        catch (Exception e)
        {
            Console.WriteLine("The email was not sent.");
            Console.WriteLine("Error message: " + e.Message);
        }
    }
}
8 голосов
/ 08 марта 2012
public Boolean SendRawEmail(String from, String to, String cc, String Subject, String text, String html, String replyTo, string attachPath)
    {
        AlternateView plainView = AlternateView.CreateAlternateViewFromString(text, Encoding.UTF8, "text/plain");
        AlternateView htmlView = AlternateView.CreateAlternateViewFromString(html, Encoding.UTF8, "text/html");

        MailMessage mailMessage = new MailMessage();

        mailMessage.From = new MailAddress(from);

        List<String> toAddresses = to.Replace(", ", ",").Split(',').ToList();

        foreach (String toAddress in toAddresses)
        {
            mailMessage.To.Add(new MailAddress(toAddress));
        }

        List<String> ccAddresses = cc.Replace(", ", ",").Split(',').Where(y => y != "").ToList();

        foreach (String ccAddress in ccAddresses)
        {
            mailMessage.CC.Add(new MailAddress(ccAddress));
        }

        mailMessage.Subject = Subject;
        mailMessage.SubjectEncoding = Encoding.UTF8;

        if (replyTo != null)
        {
            mailMessage.ReplyToList.Add(new MailAddress(replyTo));
        }

        if (text != null)
        {
            mailMessage.AlternateViews.Add(plainView);
        }

        if (html != null)
        {
            mailMessage.AlternateViews.Add(htmlView);
        }

        if (attachPath.Trim() != "")
        {
            if (System.IO.File.Exists(attachPath))
            {
                System.Net.Mail.Attachment objAttach = new System.Net.Mail.Attachment(attachPath);
                objAttach.ContentType = new ContentType("application/octet-stream"); 
                System.Net.Mime.ContentDisposition disposition = objAttach.ContentDisposition;
                disposition.DispositionType = "attachment";
                disposition.CreationDate = System.IO.File.GetCreationTime(attachPath);
                disposition.ModificationDate = System.IO.File.GetLastWriteTime(attachPath);
                disposition.ReadDate = System.IO.File.GetLastAccessTime(attachPath);
                mailMessage.Attachments.Add(objAttach);
            }
        }

        RawMessage rawMessage = new RawMessage();

        using (MemoryStream memoryStream = ConvertMailMessageToMemoryStream(mailMessage))
        {
            rawMessage.WithData(memoryStream);
        }

        SendRawEmailRequest request = new SendRawEmailRequest();
        request.WithRawMessage(rawMessage);

        request.WithDestinations(toAddresses);
        request.WithSource(from);

        AmazonSimpleEmailService ses = AWSClientFactory.CreateAmazonSimpleEmailServiceClient(ConfigurationManager.AppSettings.Get("AccessKeyId"), ConfigurationManager.AppSettings.Get("SecretKeyId"));

        try
        {
            SendRawEmailResponse response = ses.SendRawEmail(request);
            SendRawEmailResult result = response.SendRawEmailResult;
            return true;
        }
        catch (AmazonSimpleEmailServiceException ex)
        {
            return false;
        }
    }
    public static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message)
    {
        Assembly assembly = typeof(SmtpClient).Assembly;
        Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
        MemoryStream fileStream = new MemoryStream();
        ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);
        object mailWriter = mailWriterContructor.Invoke(new object[] { fileStream });
        MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);
        sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true }, null);
        MethodInfo closeMethod = mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic);
        closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null);
        return fileStream;
    }

Обнаружено, что здесь

Обновление: подпись метода изменилась в .NET 4.5, что нарушает вышеперечисленное: Получение System.Net.Mail.MailMessage в качестве MemoryStream в .NET 4.5 beta

1 голос
/ 23 июня 2017

Это очень простая реализация с использованием MimeKit

using Amazon;
using Amazon.SimpleEmail;
using Amazon.SimpleEmail.Model;
using MimeKit;
using System.IO;

namespace SendEmailWithAttachments
{
 class Program
 {
    static void Main(string[] args)
    {
        //Remember to enter your (AWSAccessKeyID, AWSSecretAccessKey) if not using and IAM User with credentials assigned to your instance and your RegionEndpoint
        using (var client = new AmazonSimpleEmailServiceClient("YourAWSAccessKeyID", "YourAWSSecretAccessKey", RegionEndpoint.USEast1))
        using (var messageStream = new MemoryStream())
        {
            var message = new MimeMessage();
            var builder = new BodyBuilder() { TextBody = "Hello World" };

            message.From.Add(new MailboxAddress("FROMADDRESS@TEST.COM"));
            message.To.Add(new MailboxAddress("TOADDRESS@TEST.COM"));
            message.Subject = "Hello World";

            //I'm using the stream method, but you don't have to.
            using (FileStream stream = File.Open(@"Attachment1.pdf", FileMode.Open)) builder.Attachments.Add("Attachment1.pdf", stream);
            using (FileStream stream = File.Open(@"Attachment2.pdf", FileMode.Open)) builder.Attachments.Add("Attachment2.pdf", stream);

            message.Body = builder.ToMessageBody();
            message.WriteTo(messageStream);

            var request = new SendRawEmailRequest()
            {
                RawMessage = new RawMessage() { Data = messageStream }
            };

            client.SendRawEmail(request);
        }
    }
  }
}

У меня есть код в моем хранилище https://github.com/gianluis90/amazon-send-email

1 голос
/ 02 августа 2012

Также можно настроить IIS SMTP для ретрансляции через SES.

Вам необходимо установить stunnel и настроить его

Затем вы можете просто установить IIS SMTP Smart Host и некоторые другие параметры, и он будет передавать вашу электронную почту через SES.

Инструкции сверху, связанные суть:

Инструкции взяты из Документов Amazon и изменены по мере необходимости.

1. Установите stunnel :

  • Скачать с stunnel's страница загрузки
  • Запустите программу установки с параметрами по умолчанию, создайте самозаверяющий сертификат, ответив на вопросы
  • Откройте файл c:\program files (x86)\stunnel\stunnel.conf в блокноте
  • Очистить все настройки сервера (в разделе Example SSL server mode services строка client = yes не будет)
  • Создать новую конфигурацию клиента:

[SMTP-TLS-обертка]
принять = 127.0.0.1:2525
клиент = да
connect = email-smtp.us-east-1.amazonaws.com:465

  • Запустите stunnel.exe и убедитесь, что об ошибках не сообщается (у вас появится небольшой значок в системном окне)
  • Если это удастся, вы можете при желании установить как службу, запустив stunnel.exe -install в командной строке (обратите внимание, это устанавливает службу, но не запускает ее, поэтому запустите ее)
  • Проверьте соединение, в строке cmd запустите telnet localhost 2525, и вы увидите SMTP-ответ от сервера Amazon (если telnet не установлен, добавьте функцию в Диспетчер серверов / Функции / Добавить функцию )

2. Настроить IIS SMTP

  • Установить Smart Host как [127.0.0.1] (включая скобки)
  • В разделе Исходящие соединения установите для исходящего порта значение 2525 (например, файл stunnel.conf)
  • В разделе Outbound Security установите информацию об аутентификации для своих учетных данных SMTP Amazon, установите для нее обычную аутентификацию ( ПРИМЕЧАНИЕ: НЕ ПРОВЕРЯЙТЕ ПРОВЕРКУ TLS CHECKBOX)
0 голосов
/ 27 февраля 2012

Я думаю, вам нужно следовать инструкциям по этой ссылке . Amazon не позволяет добавлять вложения или другие более сложные типы сообщений (события iCalendar). По сути, вам нужно вручную обработать тело сообщения строками и манипуляциями.

В настоящее время я делаю это для электронных писем формата iCalendar в устаревшей системе. Это немного больно в заднице, но если вы читаете RFC 2822, он довольно ясно говорит вам, что это за формат. Особые вещи, на которые следует обратить внимание:

  • Base64 кодирование данных
  • MIME типы
  • Убедитесь, что ваши составные границы совпадают (и являются уникальными)
  • Придирчивые проблемы с количеством разрывов строк (\ n) после определенных строк

Желаем удачи. Я не знаю, есть ли открытая библиотека, которая будет делать такие вещи для вас в C #. Если вы можете найти тот, то попробуйте использовать его, потому что при работе с тонкостями RFC необходимо иметь медицинское уведомление о повышенном кровяном давлении и потере волос.

0 голосов
/ 08 сентября 2011

Мне также нужна помощь в этом, но до сих пор я обнаружил, что вам нужно отправить MIME-сообщение из нескольких частей с вложением, закодированным в base64.

0 голосов
/ 26 июля 2011

Я не уверен, что это то, что вы ищете, но это единственный ресурс, который мне удалось найти по этому вопросу. Мне бы тоже хотелось получить лучший ответ на этот вопрос.

http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/

В нем говорится, как его использовать, но очень загадочно, по крайней мере для меня.

Есть лучшие руководства?

...