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

이 가이드는 의 기존 콘솔을 반영합니다Amazon SES. 용 새 콘솔에 대한 자세한 내용은 Amazon SES 새 Amazon Simple Email Service 개발자 안내서를 참조하십시오.

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

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

Amazon SES SendRawEmail 작업을 사용하여 수신자에게 세부적으로 사용자 지정된 메시지를 보낼 수 있습니다.

이 단원에는 Amazon SES API를 사용하여 원시 이메일을 작성하고 보내는 절차가 나와 있습니다.

이메일 헤더 필드 정보

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 부분이 포함되어 있습니다. 또한 첨부 파일도 포함되어 있습니다.

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 인코딩

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

이메일 주소

메시지 봉투에서 사용되는 이메일 주소를 인코딩하려면 퓨니코드 인코딩을 사용하십시오.

예를 들어,예제.com에서 을(를) 확인하십시오., 주소의 로컬 부분(@ 기호 앞 부분)에서 Punycode 인코딩을 사용합니다. 그 결과, 인코딩된 주소는 xn--cpqy30b@example.com입니다.

참고

이 규칙은 메시지 헤더가 아닌 메시지 봉투에 지정하는 이메일 주소에만 적용됩니다. 사용자가 SendRawEmail API,Source 그리고 Destinations 매개변수는 각각 봉투 발송자와 수신자를 정의합니다.

퓨니코드 인코딩에 대한 자세한 내용은 RFC 3492를 참조하십시오.

이메일 헤더

메시지 헤더를 인코딩하려면 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 메시지 부분에 배치됩니다.

  • 콘텐츠 유형: 첨부 파일의 파일 유형. 다음은 일반적인 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: attachment입니다.

  • 콘텐츠 전송 인코딩: 첨부 파일을 인코딩하는 데 사용된 스키마입니다. 첨부 파일의 경우 이 값은 거의 항상 base64입니다.

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

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

Amazon SES API는 사용자가 지정하는 형식으로 이메일 메시지를 작성하고 전송할 수 있는 SendRawEmail 작업을 제공합니다. SendRawEmail에 대한 전체 설명을 보려면 Amazon Simple Email Service API Reference를 참조하십시오.

참고

SendRawEmail을 여러 번 호출할 때 이메일 전송 속도를 향상하는 방법에 대한 팁은 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'])