Senden von Raw-E-Mails mit der Amazon-SES-API - Amazon Simple Email Service

Senden von Raw-E-Mails mit der Amazon-SES-API

Sie können die Amazon SES SendRawEmail-Operation verwenden, um hochgradig angepasste Nachrichten an die Empfänger zu senden.

Dieser Abschnitt enthält Verfahren zum Erstellen und Senden von Raw-E-Mail mit der Amazon-SES-API.

Über E-Mail-Header-Felder

Simple Mail Transfer Protocol (SMTP) gibt an, wie E-Mail-Nachrichten gesendet werden sollen, indem der E-Mail-Umschlag und einigen seiner Parameter definiert werden. Es geht dabei aber nicht um den Inhalt der Nachricht. Stattdessen definiert das Internet-Nachrichtenformat (RFC 5322), wie die Nachricht aufgebaut werden soll.

Mit der Spezifikation für das Internet-Nachrichtenformat besteht jede E-Mail-Nachricht aus einem Header und einem Text. Der Header besteht aus Metadaten der Nachrichten und der Körper enthält die Nachricht selbst. Weitere Informationen über E-Mail-Header und -Texte finden Sie unter E-Mail-Format und Amazon SES.

Verwenden von MIME

Das SMTP-Protokoll war ursprünglich zum Senden von E-Mail-Nachrichten konzipiert, die nur 7-Bit-ASCII-Zeichen enthielten. Aufgrund dieser Spezifikation ist SMTP für Nicht-ASCII-Textcodierungen (z. B. Unicode), binäre Inhalte oder Anlagen unzureichend. Der Multipurpose Internet Mail Extensions-Standard (MIME) wurde entwickelt, um den Versand vieler anderer Arten von Inhalten über SMTP zu ermöglichen.

Der MIME-Standard funktioniert, indem er den Nachrichtentext in mehrere Teile unterteilt und dann angibt, wie mit den einzelnen Teilen zu verfahren ist. Beispielsweise kann ein Teil eines E-Mail-Nachrichtentext Klartext sein, während ein anderer HTML sein kann. Darüber hinaus lässt MIME zu, dass E-Mail-Nachrichten eine oder mehrere Anlagen enthalten. Die Empfänger der Nachricht können die Anlagen innerhalb ihrer E-Mail-Clients anzeigen oder die Anlagen speichern.

Der E-Mail-Header und die Inhalte werden durch eine Leerzeile getrennt. Jeder Teil der E-Mail wird durch einen Rahmen getrennt, eine Zeichenfolge, die den Anfang und das Ende jedes Teils markiert.

Die mehrteilige Nachricht im folgenden Beispiel enthält einen Text- und einen HTML-Teil sowie einen Anhang. Der Anhang sollte, wie in diesem Beispiel gezeigt, direkt unter den Anhangsüberschriften platziert werden und wird meistens in base64 codiert.

From: "Sender Name" <sender@example.com> To: recipient@example.com Subject: Customer service contact info Content-Type: multipart/mixed; boundary="a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a" --a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a Content-Type: multipart/alternative; boundary="sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a" --sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Please see the attached file for a list of customers to contact. --sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a Content-Type: text/html; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable <html> <head></head> <body> <h1>Hello!</h1> <p>Please see the attached file for a list of customers to contact.</p> </body> </html> --sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a-- --a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a Content-Type: text/plain; name="customers.txt" Content-Description: customers.txt Content-Disposition: attachment;filename="customers.txt"; creation-date="Sat, 05 Aug 2017 19:35:36 GMT"; Content-Transfer-Encoding: base64 SUQsRmlyc3ROYW1lLExhc3ROYW1lLENvdW50cnkKMzQ4LEpvaG4sU3RpbGVzLENhbmFkYQo5MjM4 OSxKaWUsTGl1LENoaW5hCjczNCxTaGlybGV5LFJvZHJpZ3VleixVbml0ZWQgU3RhdGVzCjI4OTMs QW5heWEsSXllbmdhcixJbmRpYQ== --a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--

Der Inhaltstyp für die Nachricht ist multipart/mixed. Dieser gibt an, dass die Nachricht viele Teile hat (in diesem Beispiel einen Text und eine Anlage), und der empfangende Client muss jedes Teil getrennt handhaben.

Verschachtelt in den Körperabschnitt ist eine zweite Komponente, die den multipart/alternative-Inhaltstyp verwendet. Dieser Inhaltstyp gibt an, dass jedes Teil alternative Versionen desselben Inhalts enthält (in diesem Fall eine Textversion und eine HTML-Version). Wenn der E-Mail-Client des Empfängers HTML-Inhalte anzeigen kann, dann zeigt er die HTML-Version des Textkörpers an. Wenn der E-Mail-Client des Empfängers keine HTML-Inhalte anzeigen kann, dann zeigt er die Klartextversion des Textkörpers an.

Beide Versionen der Nachricht enthalten außerdem eine Anlage (in diesem Fall eine kurze Textdatei mit einigen Kundennamen).

Wenn Sie einen MIME-Teil in einen anderen Teil verschachteln, wie in diesem Beispiel, muss das verschachtelte Teil einen boundary-Parameter verwenden, der sich vom boundary-Parameter im übergeordneten Teil unterscheidet. Diese Grenzen sollten eindeutige Zeichenfolgen sein. Zum Definieren einer Begrenzung zwischen MIME-Teilen geben Sie zwei Bindestriche (-) gefolgt von der Begrenzungszeichenfolge ein. Am Ende eines MIME-Teils platzieren Sie zwei Bindestriche am Anfang und am Ende der Begrenzungszeichenfolge.

MIME-Codierung

Um die Kompatibilität mit älteren Systemen zu wahren, beachtet Amazon SES die 7-Bit-ASCII-Beschränkung der SMTP-Definition in RFC 2821. Wenn Sie Inhalte senden möchten, die Nicht-ASCII-Zeichen enthalten, müssen Sie diese Zeichen in einem Format mit 7-Bit-ASCII-Zeichen formatieren.

E-Mail-Adressen

Um eine E-Mail-Adresse zu codieren, die im Umschlag der Nachricht verwendet wird, verwenden Sie Punycode-Codierung.

Um z. B. eine E-Mail an 张伟@example.com zu senden, verwenden Sie im lokalen Teil der Adresse (der Teil vor dem @-Zeichen) Punycode-Codierung. Die resultierende codierte Adresse lautet xn--cpqy30b@example.com.

Anmerkung

Diese Regel gilt nur für E-Mail-Adressen, die Sie im Umschlag der Nachricht angeben, nicht für die Nachrichten-Header. Wenn Sie die SendRawEmail-API verwenden, definieren die von Ihnen in den Parametern Source und Destinations angegebenen Adressen den Sender bzw. die Empfänger des Umschlags.

Weitere Informationen zur Punycode-Codierung finden Sie unter RFC 3492.

E-Mail-Header

Um eine Nachrichtenkopfzeile, oder einen Header, zu codieren, verwenden Sie MIME-codierte Wortsyntax. MIME-codierter Wortsyntax verwendet das folgende Format:

=?charset?encoding?encoded-text?=

Der Wert von encoding kann Q oder B sein. Wenn der Wert der Codierung Q ist, dann muss der Wert von encoded-text Q-Codierung verwenden. Wenn der Wert der Codierung B ist, dann muss der Wert von encoded-text base64-Codierung verwenden.

Zum Beispiel, wenn Sie die Zeichenfolge „Як ти поживаєш?“ verwenden möchten In der Betreffzeile einer E-Mail können Sie eine der folgenden Codierungen verwenden:

  • Q-Codierung

    =?utf-8?Q?=D0=AF=D0=BA_=D1=82=D0=B8_=D0=BF=D0=BE=D0=B6=D0=B8=D0=B2=D0=B0=D1=94=D1=88=3F?=
  • Base64-Codierung

    =?utf-8?B?0K/QuiDRgtC4INC/0L7QttC40LLQsNGU0Yg/?=

Weitere Informationen zur Q_Codierung finden Sie unter RFC 2047. Weitere Informationen zur base64-Codierung finden Sie unter RFC 2045.

Nachrichtentext

Um den Nachrichtentext zu codieren, können Sie Quoted-Printable-Codierung oder base64-Codierung verwenden. Verwenden Sie danach den Content-Transfer-Encoding-Header, um anzugeben, welche Codierungsschema Sie verwendet haben.

Angenommen, der Text Ihrer Nachricht enthält den folgenden Text:

१९७२ मे रे टॉमलिंसन ने पहला ई-मेल संदेश भेजा | रे टॉमलिंसन ने ही सर्वप्रथम @ चिन्ह का चयन किया और इन्ही को ईमेल का आविष्कारक माना जाता है

Wenn Sie diesen Text mit base64-Codierung codieren, geben Sie zuerst den folgenden Header ein:

Content-Transfer-Encoding: base64

Schließen Sie dann im Körperabschnitt der E-Mail den base64-codierten Text ein:

4KWn4KWv4KWt4KWoIOCkruClhyDgpLDgpYcg4KSf4KWJ4KSu4KSy4KS/4KSC4KS44KSoIOCkqOCl hyDgpKrgpLngpLLgpL4g4KSILeCkruClh+CksiDgpLjgpILgpKbgpYfgpLYg4KSt4KWH4KSc4KS+ IHwg4KSw4KWHIOCkn+ClieCkruCksuCkv+CkguCkuOCkqCDgpKjgpYcg4KS54KWAIOCkuOCksOCl jeCkteCkquCljeCksOCkpeCkriBAIOCkmuCkv+CkqOCljeCkuSDgpJXgpL4g4KSa4KSv4KSoIOCk leCkv+Ckr+CkviDgpJTgpLAg4KSH4KSo4KWN4KS54KWAIOCkleCliyDgpIjgpK7gpYfgpLIg4KSV 4KS+IOCkhuCkteCkv+Ckt+CljeCkleCkvuCksOCklSDgpK7gpL7gpKjgpL4g4KSc4KS+4KSk4KS+ IOCkueCliAo=
Anmerkung

In einigen Fällen können Sie in mit Amazon SES gesendeten Nachrichten das 8-Bit Content-Transfer-Encoding verwenden. Wenn Amazon SES jedoch Änderungen an Ihren Nachrichten vornehmen muss (wenn Sie z. B. Öffnungs- und Klicknachverfolgung verwenden), wird der 8-Bit-codierte Inhalt möglicherweise nicht richtig angezeigt, wenn er im Postfach der Empfänger eingeht. Aus diesem Grund sollten Sie Inhalte, die sich nicht im 7-Bit-ASCII-Format befinden, immer codieren.

Dateianhänge

Um eine Datei an eine E-Mail anfügen zu können, müssen Sie die Anlage mit base64-Codierung codieren. Anlagen werden in der Regel in dedizierten MIME-Nachrichtenteilen platziert. Dazu gehören die folgenden Header:

  • Inhaltstyp – der Dateityp der Anlage. Hier sind einige Beispiele für häufige MIME-Inhaltstyp-Deklarationen:

    • Reine Textdatei – Content-Type: text/plain; name="sample.txt"

    • Microsoft Word-Dokument – Content-Type: application/msword; name="document.docx"

    • JPG-Bild – Content-Type: image/jpeg; name="photo.jpeg"

  • Inhaltsanordnung – gibt an, wie der E-Mail-Client des Empfängers die Inhalte anordnen soll. Für Anlagen ist dieser Wert Content-Disposition: attachment.

  • Inhaltsübertragungscodierung – das Schema, das zum Codieren der Anlage verwendet wurde. Für Dateianlagen ist dieser Wert fast immer base64.

  • Der codierte Anhang – Sie müssen den eigentlichen Anhang, wie im Beispiel gezeigt, codieren und ihn in den Text unter den Anhangsüberschriften einfügen.

Amazon SES akzeptiert die gängigsten Dateitypen. Eine Liste der Dateitypen, die Amazon SES nicht akzeptiert, finden Sie unter Amazon SES nicht unterstützte Anhangstypen.

Senden von Raw-E-Mails mit der Amazon SES-API

Die Amazon-SES-API stellt die SendRawEmail-Aktion bereit, über die Sie eine E-Mail-Nachricht im angegebenen Format verfassen und senden können. Eine vollständige Beschreibung von SendRawEmail finden Sie unter der Amazon Simple Email Service API-Referenz.

Anmerkung

Tipps zur Erhöhung der E-Mail-Sendegeschwindigkeit bei mehreren SendRawEmail-Aufrufen finden Sie unter Erhöhen des Durchsatzes mit Amazon SES.

Der Nachrichtentext muss eine ordnungsgemäß formatierte Raw-E-Mail-Nachricht mit entsprechenden Header-Feldern und Nachrichtentext-Codierung enthalten. Obwohl es möglich ist, die unformatierte Nachricht manuell in einer Anwendung zu verfassen, ist es wesentlich einfacher, dies mithilfe von vorhandenen E-Mail-Bibliotheken zu tun.

Java

Das folgende Codebeispiel veranschaulicht, wie Sie mit der JavaMail-Bibliothek und dem AWS SDK for Java eine Raw-E-Mail erstellen und senden können.

package com.amazonaws.samples; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; import java.nio.ByteBuffer; import java.util.Properties; // JavaMail libraries. Download the JavaMail API // from https://javaee.github.io/javamail/ import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; // AWS SDK libraries. Download the AWS SDK for Java // from https://aws.amazon.com/sdk-for-java import com.amazonaws.regions.Regions; import com.amazonaws.services.simpleemail.AmazonSimpleEmailService; import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder; import com.amazonaws.services.simpleemail.model.RawMessage; import com.amazonaws.services.simpleemail.model.SendRawEmailRequest; public class AmazonSESSample { // Replace sender@example.com with your "From" address. // This address must be verified with Amazon SES. private static String SENDER = "Sender Name <sender@example.com>"; // Replace recipient@example.com with a "To" address. If your account // is still in the sandbox, this address must be verified. private static String RECIPIENT = "recipient@example.com"; // Specify a configuration set. If you do not want to use a configuration // set, comment the following variable, and the // ConfigurationSetName=CONFIGURATION_SET argument below. private static String CONFIGURATION_SET = "ConfigSet"; // The subject line for the email. private static String SUBJECT = "Customer service contact info"; // The full path to the file that will be attached to the email. // If you're using Windows, escape backslashes as shown in this variable. private static String ATTACHMENT = "C:\\Users\\sender\\customers-to-contact.xlsx"; // The email body for recipients with non-HTML email clients. private static String BODY_TEXT = "Hello,\r\n" + "Please see the attached file for a list " + "of customers to contact."; // The HTML body of the email. private static String BODY_HTML = "<html>" + "<head></head>" + "<body>" + "<h1>Hello!</h1>" + "<p>Please see the attached file for a " + "list of customers to contact.</p>" + "</body>" + "</html>"; public static void main(String[] args) throws AddressException, MessagingException, IOException { Session session = Session.getDefaultInstance(new Properties()); // Create a new MimeMessage object. MimeMessage message = new MimeMessage(session); // Add subject, from and to lines. message.setSubject(SUBJECT, "UTF-8"); message.setFrom(new InternetAddress(SENDER)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT)); // Create a multipart/alternative child container. MimeMultipart msg_body = new MimeMultipart("alternative"); // Create a wrapper for the HTML and text parts. MimeBodyPart wrap = new MimeBodyPart(); // Define the text part. MimeBodyPart textPart = new MimeBodyPart(); textPart.setContent(BODY_TEXT, "text/plain; charset=UTF-8"); // Define the HTML part. MimeBodyPart htmlPart = new MimeBodyPart(); htmlPart.setContent(BODY_HTML,"text/html; charset=UTF-8"); // Add the text and HTML parts to the child container. msg_body.addBodyPart(textPart); msg_body.addBodyPart(htmlPart); // Add the child container to the wrapper object. wrap.setContent(msg_body); // Create a multipart/mixed parent container. MimeMultipart msg = new MimeMultipart("mixed"); // Add the parent container to the message. message.setContent(msg); // Add the multipart/alternative part to the message. msg.addBodyPart(wrap); // Define the attachment MimeBodyPart att = new MimeBodyPart(); DataSource fds = new FileDataSource(ATTACHMENT); att.setDataHandler(new DataHandler(fds)); att.setFileName(fds.getName()); // Add the attachment to the message. msg.addBodyPart(att); // Try to send the email. try { System.out.println("Attempting to send an email through Amazon SES " +"using the AWS SDK for Java..."); // Instantiate an Amazon SES client, which will make the service // call with the supplied AWS credentials. AmazonSimpleEmailService client = AmazonSimpleEmailServiceClientBuilder.standard() // Replace US_WEST_2 with the AWS Region you're using for // Amazon SES. .withRegion(Regions.US_WEST_2).build(); // Print the raw email content on the console PrintStream out = System.out; message.writeTo(out); // Send the email. ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); message.writeTo(outputStream); RawMessage rawMessage = new RawMessage(ByteBuffer.wrap(outputStream.toByteArray())); SendRawEmailRequest rawEmailRequest = new SendRawEmailRequest(rawMessage) .withConfigurationSetName(CONFIGURATION_SET); client.sendRawEmail(rawEmailRequest); System.out.println("Email sent!"); // Display an error if something goes wrong. } catch (Exception ex) { System.out.println("Email Failed"); System.err.println("Error message: " + ex.getMessage()); ex.printStackTrace(); } } }
Python

Das folgende Codebeispiel veranschaulicht, wie Sie mit Python email.mime-Paketen und dem AWS SDK for Python (Boto) eine Raw-E-Mail erstellen und senden können.

import os import boto3 from botocore.exceptions import ClientError from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication # Replace sender@example.com with your "From" address. # This address must be verified with Amazon SES. SENDER = "Sender Name <sender@example.com>" # Replace recipient@example.com with a "To" address. If your account # is still in the sandbox, this address must be verified. RECIPIENT = "recipient@example.com" # Specify a configuration set. If you do not want to use a configuration # set, comment the following variable, and the # ConfigurationSetName=CONFIGURATION_SET argument below. CONFIGURATION_SET = "ConfigSet" # If necessary, replace us-west-2 with the AWS Region you're using for Amazon SES. AWS_REGION = "us-west-2" # The subject line for the email. SUBJECT = "Customer service contact info" # The full path to the file that will be attached to the email. ATTACHMENT = "path/to/customers-to-contact.xlsx" # The email body for recipients with non-HTML email clients. BODY_TEXT = "Hello,\r\nPlease see the attached file for a list of customers to contact." # The HTML body of the email. BODY_HTML = """\ <html> <head></head> <body> <h1>Hello!</h1> <p>Please see the attached file for a list of customers to contact.</p> </body> </html> """ # The character encoding for the email. CHARSET = "utf-8" # Create a new SES resource and specify a region. client = boto3.client('ses',region_name=AWS_REGION) # Create a multipart/mixed parent container. msg = MIMEMultipart('mixed') # Add subject, from and to lines. msg['Subject'] = SUBJECT msg['From'] = SENDER msg['To'] = RECIPIENT # Create a multipart/alternative child container. msg_body = MIMEMultipart('alternative') # Encode the text and HTML content and set the character encoding. This step is # necessary if you're sending a message with characters outside the ASCII range. textpart = MIMEText(BODY_TEXT.encode(CHARSET), 'plain', CHARSET) htmlpart = MIMEText(BODY_HTML.encode(CHARSET), 'html', CHARSET) # Add the text and HTML parts to the child container. msg_body.attach(textpart) msg_body.attach(htmlpart) # Define the attachment part and encode it using MIMEApplication. att = MIMEApplication(open(ATTACHMENT, 'rb').read()) # Add a header to tell the email client to treat this part as an attachment, # and to give the attachment a name. att.add_header('Content-Disposition','attachment',filename=os.path.basename(ATTACHMENT)) # Attach the multipart/alternative child container to the multipart/mixed # parent container. msg.attach(msg_body) # Add the attachment to the parent container. msg.attach(att) #print(msg) try: #Provide the contents of the email. response = client.send_raw_email( Source=SENDER, Destinations=[ RECIPIENT ], RawMessage={ 'Data':msg.as_string(), }, ConfigurationSetName=CONFIGURATION_SET ) # Display an error if something goes wrong. except ClientError as e: print(e.response['Error']['Message']) else: print("Email sent! Message ID:"), print(response['MessageId'])