Amazon SES API v2를 사용하여 원시 이메일 보내기 - Amazon Simple Email Service

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Amazon SES API v2를 사용하여 원시 이메일 보내기

Amazon SES API v2 SendEmail 작업을 지정된 콘텐츠 유형과 함께 사용하면 원시 이메일 형식을 사용하여 수신자에게 사용자 지정된 메시지를 보낼 수 있습니다. raw

이메일 헤더 필드 정보

Simple Mail Transfer Protocol (SMTP) 은 메일 봉투와 일부 매개 변수를 정의하여 이메일 메시지를 보내는 방법을 지정하지만 메시지 내용과는 관련이 없습니다. 대신 인터넷 메시지 형식 (RFC5322) 은 메시지 구성 방법을 정의합니다.

인터넷 메시지 형식 지정을 사용할 경우 모든 이메일 메시지는 헤더와 본문으로 구성됩니다. 헤더는 메시지 메타데이터로 구성되며, 본문에는 메시지 자체가 포함됩니다. 이메일 헤더와 본문에 대한 자세한 내용은 Amazon SES의 이메일 형식 단원을 참조하세요.

사용 MIME

이 SMTP 프로토콜은 원래 7비트 ASCII 문자만 포함된 이메일 메시지를 보내도록 설계되었습니다. 이 사양으로는 ASCII 텍스트가 아닌 인코딩 (예: 유니코드), 바이너리 콘텐츠 또는 첨부 파일로는 SMTP 충분하지 않습니다. 다목적 인터넷 메일 확장 표준 (MIME) 은 를 사용하여 다른 많은 종류의 콘텐츠를 보낼 수 있도록 개발되었습니다. SMTP

MIME표준은 메시지 본문을 여러 부분으로 나눈 다음 각 부분에서 수행할 작업을 지정하는 방식으로 작동합니다. 예를 들어 전자 메일 메시지 본문의 한 부분은 일반 텍스트이고 다른 부분은 일반 텍스트일 수 HTML 있습니다. 또한 전자 메일 메시지에 첨부 파일을 하나 이상 포함할 MIME 수 있습니다. 메시지 수신자는 이메일 클라이언트에서 첨부 파일을 보거나 첨부 파일을 저장할 수 있습니다.

메시지 헤더와 콘텐츠는 빈 줄로 분리됩니다. 이메일의 각 부분은 각 부분의 시작과 종료를 나타내는 문자열인 경계로 분리됩니다.

다음 예제의 멀티파트 메시지에는 텍스트와 HTML 부분, 첨부 파일이 포함되어 있습니다. 첨부 파일은 첨부 파일 헤더 바로 아래에 위치해야 하며 대부분 이 예제와 같이 base64로 인코딩됩니다.

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

이 메시지의 콘텐츠 유형은 multipart/mixed로, 이는 메시지에 여러 부분(이 예제에서는 본문과 첨부 파일)이 있고 수신 클라이언트가 각 부분을 개별적으로 처리해야 함을 나타냅니다.

본문 섹션 내에서 중첩된 두 번째 부분은 multipart/alternative 콘텐츠 유형을 사용합니다. 이 콘텐츠 유형은 각 부분에 동일한 콘텐츠의 대체 버전 (이 경우 텍스트 버전과 HTML 버전) 이 포함되어 있음을 나타냅니다. 수신자의 이메일 클라이언트가 HTML 콘텐츠를 표시할 수 있는 경우 메시지 본문의 HTML 버전이 표시됩니다. 수신자의 이메일 클라이언트가 HTML 콘텐츠를 표시할 수 없는 경우 메시지 본문의 일반 텍스트 버전이 표시됩니다.

두 메시지 버전에는 첨부 파일도 포함됩니다(이 경우 일부 고객 이름이 포함된 짧은 텍스트 파일).

이 예제에서처럼 다른 부분에 부분을 중첩하는 경우 중첩된 부분은 부모 부분의 boundary 매개 변수와 다른 boundary 매개 변수를 사용해야 합니다. MIME 이러한 경계는 고유한 문자열이어야 합니다. MIME부품 간 경계를 정의하려면 하이픈 두 개 (--) 를 입력하고 그 뒤에 경계 문자열을 입력합니다. MIME부품 끝에 경계 문자열의 처음과 끝에 하이픈 두 개를 배치합니다.

참고

메시지는 500개를 MIME 초과할 수 없습니다.

MIME인코딩

이전 시스템과의 호환성을 유지하기 위해 Amazon은 SES 2821에 RFC 정의된 7비트 ASCII 제한을 SMTP 준수합니다. ASCII-문자가 아닌 콘텐츠를 전송하려면 해당 문자를 7비트 문자를 사용하는 형식으로 인코딩해야 합니다. ASCII

이메일 주소

이메일 주소 문자열은 7비트여야 합니다. ASCII 주소의 도메인 부분에 유니코드 문자가 포함된 이메일 주소와 메시지를 주고받으려면 퓨니코드를 사용하여 도메인을 인코딩해야 합니다. 이메일 주소의 로컬 부분(@ 기호 앞부분)은 물론 "대화명"에도 퓨니코드를 사용할 수 없습니다. “Friendly From” 이름에 유니코드 문자를 사용하려면 에 설명된 대로 인코딩된 MIME 단어 구문을 사용하여 “friendly from” 이름을 인코딩해야 합니다. Amazon SES API v2를 사용하여 원시 이메일 보내기 퓨니코드에 대한 자세한 내용은 3492를 참조하십시오. RFC

참고

이 규칙은 메시지 헤더가 아닌 메시지 봉투에 지정하는 이메일 주소에만 적용됩니다. Amazon SES API v2 SendEmail 작업을 사용하는 경우 SourceDestinations 매개 변수에 지정하는 주소가 봉투 발신자와 수신자를 각각 정의합니다.

이메일 헤더

메시지 헤더를 인코딩하려면 인코딩된 단어 구문을 사용합니다. MIME MIME인코딩된 단어 구문은 다음 형식을 사용합니다.

=?charset?encoding?encoded-text?=

encoding의 값은 Q 또는 B가 될 수 있습니다. 인코딩의 값이 Q이면 encoded-text 값은 Q 인코딩을 사용해야 합니다. 인코딩의 값이 B이면 encoded-text 값은 base64 인코딩을 사용해야 합니다.

예를 들어 이메일의 제목줄에 문자열 “Як ти поживаєш?”을 사용하려면 다음 인코딩 중 하나를 사용할 수 있습니다.

  • 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?=
  • Base64 인코딩

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

Q 인코딩에 대한 자세한 내용은 2047을 참조하십시오. RFC base64 인코딩에 대한 자세한 내용은 2045를 참조하십시오. RFC

메시지 본문

메시지의 본문을 인코딩하려면 QP(Quoted-Printable) 인코딩 또는 base64 인코딩을 사용할 수 있습니다. 그런 다음 Content-Transfer-Encoding 헤더를 사용하여 사용한 인코딩 체계를 나타냅니다.

예를 들어 메시지의 본문에 다음 텍스트가 포함되어 있다고 가정해보세요.

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

base64 인코딩을 사용하여 이 텍스트를 인코딩하려면 먼저 다음 헤더를 지정하세요.

Content-Transfer-Encoding: base64

그 다음, 이메일의 본문 섹션에 base64로 인코딩된 텍스트를 포함시키세요.

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

경우에 따라 SES Amazon을 통해 보내는 메시지에 8비트를 Content-Transfer-Encoding 사용할 수 있습니다. 하지만 SES Amazon에서 메시지를 변경해야 하는 경우 (예: 열기 및 클릭 추적 사용 시) 8비트로 인코딩된 콘텐츠가 수신자의 받은 편지함에 도착했을 때 제대로 표시되지 않을 수 있습니다. 따라서 항상 7비트가 아닌 콘텐츠를 인코딩해야 합니다. ASCII

첨부 파일

이메일에 파일을 첨부하려면 base64 인코딩을 사용하여 첨부 파일을 인코딩해야 합니다. 첨부 파일은 일반적으로 다음 헤더를 포함하는 전용 MIME 메시지 부분에 배치됩니다.

  • Content-Type – 첨부 파일의 유형입니다. 다음은 일반적인 MIME 콘텐츠 유형 선언의 예입니다.

    • 일반 텍스트 파일Content-Type: text/plain; name="sample.txt"

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

    • JPG이미지 — Content-Type: image/jpeg; name="photo.jpeg"

  • Content-Disposition – 수신자의 이메일 클라이언트가 콘텐츠를 처리하는 방법을 지정합니다. 첨부 파일의 경우 이 값은 Content-Disposition: attachment입니다.

  • Content-Transfer-Encoding – 첨부 파일을 인코딩하는 데 사용된 체계입니다. 첨부 파일의 경우 이 값은 거의 항상 base64입니다.

  • 인코딩된 첨부 파일 – 실제 첨부 파일을 인코딩하여 예제에서와 같이 첨부 파일 헤더 아래의 본문에 포함해야 합니다.

Amazon은 가장 일반적인 파일 유형을 SES 허용합니다. Amazon에서 허용하지 SES 않는 파일 유형 목록은 을 참조하십시오Amazon에서 SES 지원되지 않는 첨부 파일 유형.

Amazon SES API v2를 사용하여 원시 이메일 보내기

Amazon SES API v2는 콘텐츠 유형을 단순, 원시 또는 템플릿으로 설정할 때 지정한 형식으로 이메일 메시지를 작성하고 보낼 수 있는 SendEmail 작업을 제공합니다. 전체 설명은 을 참조하십시오. SendEmail 다음 예제에서는 원시 이메일 형식을 사용하여 메시지를 보낼 콘텐츠 유형을 지정합니다. raw

참고

SendEmail을(를) 여러 번 호출할 때 이메일 전송 속도를 향상하는 방법에 대한 팁은 Amazon SES 처리량 증가을(를) 참조하세요.

메시지 본문에는 적절한 헤더 필드 및 메시지 본문 인코딩과 함께 적절하게 서식 설정된 원시 이메일 메시지가 포함되어야 합니다. 애플리케이션 내에서 원시 메시지를 수동으로 작성할 수 있지만, 기존 메일 라이브러리를 사용하여 작성하면 훨씬 더 간편합니다.

Java

다음 코드 예제는 JavaMail라이브러리와 를 사용하여 원시 이메일을 작성하고 보내는 방법을 보여줍니다. AWS SDK for Java

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

다음 코드 예제는 Python email.mime 패키지와 AWS SDK for Python (Boto)을 사용하여 원시 이메일을 작성하고 전송하는 방법을 보여줍니다.

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