Envio de e-mail bruto usando a API v2 do Amazon SES - Amazon Simple Email Service

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Envio de e-mail bruto usando a API v2 do Amazon SES

Você pode usar a SendEmail operação da API v2 do Amazon SES com o tipo de conteúdo especificado raw para enviar mensagens personalizadas aos seus destinatários usando o formato de e-mail bruto.

Sobre campos do cabeçalho do e-mail

O SMTP (Simple Mail Transfer Protocol) especifica como as mensagens de e-mail devem ser enviadas ao definir o envelope de e-mail e alguns de seus parâmetros, mas não se preocupa com o conteúdo da mensagem. Em vez disso, o Internet Message Format (RFC 5322) define como a mensagem será construída.

Com a especificação do Internet Message Format, todas as mensagens de e-mail consistem em um cabeçalho e um corpo. O cabeçalho consiste em metadados de mensagem e o corpo contém a mensagem em si. Para obter mais informações sobre cabeçalhos e corpos de e-mail, consulte Formato de e-mail e Amazon SES.

Uso de MIME

O protocolo SMTP foi originalmente projetado para enviar mensagens de e-mail que continham apenas caracteres ASCII de 7 bits. Essa especificação torna o SMTP insuficiente para codificações de texto não ASCII (como Unicode), conteúdo binário ou anexos. O padrão MIME (Multipurpose Internet Mail Extensions) foi desenvolvido para possibilitar o envio de vários outros tipos de conteúdo usando SMTP.

O padrão MIME funciona ao dividir o corpo da mensagem em várias partes e especificar o que será feito com cada parte. Por exemplo, uma parte do corpo da mensagem do e-mail pode ser texto simples, enquanto outra pode ser HTML. Além disso, o MIME permite que mensagens de e-mail contenham um ou mais anexos. Os destinatários da mensagem podem visualizar os anexos de dentro de seus clientes de e-mail ou podem salvar os anexos.

O cabeçalho e o conteúdo da mensagem são separados por uma linha em branco. Cada parte do e-mail é separada por um limite, uma string de caracteres que indica o início e o fim de cada parte.

A mensagem de várias partes no exemplo a seguir contém uma parte em texto e uma parte em HTML, além de um anexo. O anexo deve ser colocado logo abaixo dos cabeçalhos do anexo e geralmente é codificado em base64, conforme mostrado neste exemplo.

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

O tipo de conteúdo para a mensagem é multipart/mixed, o que indica que a mensagem tem várias partes (neste exemplo, um corpo e um anexo) e o cliente do recebimento deve lidar com cada parte separadamente.

Aninhada dentro da seção do corpo está uma segunda parte que usa o tipo de conteúdo multipart/alternative. Esse tipo de conteúdo indica que cada parte contém versões alternativas do mesmo conteúdo (neste caso, uma versão em texto e uma versão HTML). Se o cliente de e-mail do destinatário puder exibir o conteúdo HTML, ele mostrará a versão HTML do corpo da mensagem. Se o cliente de e-mail do destinatário não puder exibir o conteúdo HTML, ele mostrará a versão de texto sem formatação do corpo da mensagem.

As duas versões da mensagem também contêm um anexo (neste caso, um arquivo de texto que contém alguns nomes de clientes).

Quando você aninha uma parte de MIME dentro de outra parte, como neste exemplo, a parte aninhada deve usar um parâmetro boundary diferente do parâmetro boundary na parte pai. Esses limites devem ser strings de caracteres exclusivas. Para definir um limite entre as partes MIME, digite dois hifens (--) seguidos pela string de limite. No final de uma parte MIME, coloque dois hifens no início e no final da string do limite.

nota

Uma mensagem não pode ter mais de 500 partes de MIME.

Codificação MIME

Para manter a compatibilidade com sistemas mais antigos, o Amazon SES respeita a limitação ASCII de 7 bits do SMTP, conforme definido na RFC 2821. Se você deseja enviar conteúdo que contém caracteres não ASCII, você deve codificar os caracteres em um formato que usa caracteres ASCII de 7 bits.

Endereços de e-mail

A string do endereço de e-mail deve ter o formato ASCII de 7 bits. Se você deseja enviar para ou de endereços de e-mail que contêm caracteres Unicode na parte de domínio de um endereço, você deve codificar o domínio usando Punycode. Punycode não é permitido na parte local do endereço de e-mail (na parte antes de @) nem no nome "amigável de". Se você quiser usar caracteres Unicode no nome "amigável de", deve codificá-lo usando a sintaxe de palavras codificadas por MIME, conforme descrito em Envio de e-mail bruto usando a API v2 do Amazon SES. Para obter mais informações sobre Punycode, consulte RFC 3492.

nota

Essa regra se aplica somente aos endereços de e-mail que você especifica no envelope da mensagem, não nos cabeçalhos das mensagens. Quando você usa a SendEmail operação da API v2 do Amazon SES, os endereços que você especifica nos Destinations parâmetros Source e definem o remetente e os destinatários do envelope, respectivamente.

Cabeçalhos de e-mail

Para codificar um cabeçalho de mensagem, use a sintaxe de palavras codificadas por MIME. A sintaxe de palavras codificadas por MIME usa o seguinte formato:

=?charset?encoding?encoded-text?=

O valor de encoding pode ser Q ou B. Se o valor da codificação for Q, o valor encoded-text deverá usar a codificação Q. Se o valor da codificação for B, o valor de encoded-text deverá usar a codificação base64.

Por exemplo, se você deseja usar a sequência "Як ти поживаєш?" na linha de assunto do e-mail, você pode usar uma das seguintes codificações:

  • Codificação Q

    =?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?=
  • Codificação base64

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

Para obter mais informações sobre a codificação Q, consulte a RFC 2047. Para obter mais informações sobre a codificação base64, consulte a RFC 2045.

Corpo da mensagem

Para codificar o corpo de uma mensagem, você pode usar a codificação imprimível citada ou a codificação base64. Em seguida, use o cabeçalho Content-Transfer-Encoding para indicar qual esquema de codificação você usou.

Por exemplo, suponha que o corpo da mensagem contém o seguinte texto:

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

Se você escolher codificar esse texto usando a codificação base64, primeiro especifique o seguinte cabeçalho:

Content-Transfer-Encoding: base64

Em seguida, na seção do corpo do e-mail, inclua o texto codificado em base64:

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

Em alguns casos, você pode usar Content-Transfer-Encoding de 8 bits em mensagens enviadas usando o Amazon SES. No entanto, se o Amazon SES tiver de fazer alguma alteração nas suas mensagens (por exemplo, quando você usa o rastreamento de abertura e clique), o conteúdo codificado de 8 bits pode não aparecer corretamente quando chega nas caixas de entrada dos destinatários. Por esse motivo, você deve sempre codificar o conteúdo que não seja ASCII de 7 bits.

Anexos de arquivo

Para anexar um arquivo a um email, você precisa codificar o anexo usando a codificação base64. Normalmente, os anexos são colocados em partes dedicadas da mensagem MIME, que incluem os seguintes cabeçalhos:

  • Content-Type: o tipo de arquivo do anexo. Veja a seguir exemplos de declarações comuns de Content-Type MIME:

    • Arquivo de texto sem formatação): Content-Type: text/plain; name="sample.txt"

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

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

  • Content-Disposition: especifica como o cliente de e-mail do destinatário deve lidar com o conteúdo. Para anexos, esse valor é Content-Disposition: attachment.

  • Content-Transfer-Encoding: o esquema usado para codificar o anexo. Para anexos de arquivo, esse valor é quase sempre base64.

  • O anexo codificado: você deve codificar o anexo real e incluí-lo no corpo abaixo dos cabeçalhos do anexo, conforme mostrado no exemplo.

O Amazon SES aceita a maioria dos tipos de arquivos comuns. Para obter uma lista de tipos de arquivo que o Amazon SES não aceita, consulte Tipos de anexo não suportados pelo Amazon SES.

Envio de e-mail bruto usando a API v2 do Amazon SES

A API v2 do Amazon SES fornece a SendEmail ação, que permite redigir e enviar uma mensagem de e-mail no formato que você especifica ao definir o tipo de conteúdo como simples, bruto ou modelo. Para obter uma descrição completa, consulte SendEmail. O exemplo a seguir especificará o tipo de conteúdo raw para enviar uma mensagem usando o formato de e-mail bruto.

nota

Para obter dicas sobre como aumentar a velocidade de envio de e-mail ao fazer várias chamadas para SendEmail, consulte Aumento da taxa de transferência com o Amazon SES.

O corpo da mensagem deve conter uma mensagem de e-mail bruto corretamente formatada, com a codificação adequada dos campos de cabeçalho e do corpo da mensagem. Embora seja possível construir a mensagem bruta manualmente dentro de uma aplicação, é muito mais fácil usar as bibliotecas de e-mail existentes.

Java

O exemplo de código a seguir mostra como usar a JavaMailbiblioteca e a AWS SDK for Javapara redigir e enviar um e-mail bruto.

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

O código de exemplo a seguir mostra como usar os pacotes Python email.mime e o AWS SDK for Python (Boto) para compor e enviar um e-mail bruto.

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'])