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

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

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

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

이메일 헤더 필드 정보

SMTP(Simple Mail Transfer Protocol)는 이메일 봉투와 몇 가지 해당 파라미터를 정의하여 이메일 메시지를 전송하는 방법을 지정하지만, 메시지 콘텐츠에는 관련되지 않습니다. 그 대신, 인터넷 메시지 형식(RFC 5322)이 메시지 작성 방법을 정의합니다.

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

MIME 사용

SMTP 프로토콜은 원래 7비트 ASCII 문자만 포함된 이메일 메시지를 전송하기 위해 설계되었습니다. 이 사양으로 인해 비 ASCII 텍스트 인코딩(예: 유니코드), 바이너리 콘텐츠 또는 첨부 파일에는 SMTP가 부족합니다. MIME(Multipurpose Internet Mail Extensions) 표준은 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 콘텐츠를 표시할 수 없으면 메시지 본문의 일반 텍스트 버전이 표시됩니다.

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

이 예제에서처럼 다른 부분 내에 MIME 부분을 중첩하는 경우, 중첩된 부분은 상위 부분의 boundary 파라미터와 다른 boundary 파라미터를 사용해야 합니다. 이러한 경계는 고유한 문자열이어야 합니다. MIME 부분 간에 경계를 정의하려면 하이픈 두 개(--) 뒤에 경계 문자열을 입력합니다 MIME 부분의 마지막에는 경계 문자열의 시작과 끝 모두에 하이픈 두 개를 넣습니다.

참고

메시지의 MIME 부분은 500개를 초과할 수 없습니다.

MIME 인코딩

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

이메일 주소

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

참고

이 규칙은 메시지 헤더가 아닌 메시지 봉투에 지정하는 이메일 주소에만 적용됩니다. 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 인코딩에 대한 자세한 내용은 RFC 2047을 참조하세요. base64 인코딩에 대한 자세한 내용은 RFC 2045를 참조하세요.

메시지 본문

메시지의 본문을 인코딩하려면 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=
참고

경우에 따라 Amazon SES를 사용하여 전송하는 메시지에 8비트 Content-Transfer-Encoding을(를) 사용할 수 있습니다. 그러나 Amazon SES가 메시지를 변경해야 하는 경우(예: 열기 및 클릭 추적을 사용하는 경우) 8비트로 인코딩된 콘텐츠가 수신자의 받은 편지함에 도착할 때 올바르게 표시되지 않을 수 있습니다. 이러한 이유로 7비트 ASCII가 아닌 콘텐츠는 항상 인코딩해야 합니다.

첨부 파일

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

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

    • 일반 텍스트 파일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'])