AWS SESでPythonからメール送信してみる
AWSのSES (Amazon Simple Email Service)を初めて使ってみました。
使い方は以下の公式ドキュメントがわかりやすかったです。
AWS SDK for Python (Boto) を使用して E メールを送信する - Amazon Simple Email Service
1. メールアドレス登録
メール送信時の差出人アドレスは事前にSESに登録して、メールアドレスの持ち主であることの確認をします。
SESのマネジメントコンソールから登録できます。
2. メール送信のPythonコード
import json import boto3 from botocore.exceptions import ClientError profile = "default" region = "ap-northeast-1" session = boto3.session.Session(profile_name = profile, region_name = region) client = session.client("ses") email_from = "Sample <sample@gmail.com>" email_to = "sample_to@gmail.com" charset = "UTF-8" subject = "Amazon SES Test (SDK for Python)" body_text = "Hello, SES!" body_html = """<html> <head></head> <body> <p>Hello, <a href='https://aws.amazon.com/ses/'>Amazon SES</a>!</p> </body> </html> """ try: res = client.send_email( Source = email_from, Destination = { "ToAddresses": [ email_to, ], }, Message = { "Body": { "Html": { "Charset": charset, "Data": body_html, }, "Text": { "Charset": charset, "Data": body_text, }, }, "Subject": { "Charset": charset, "Data": subject, }, }, ) except ClientError as e: print(e.response["Error"]["Message"]) else: print(json.dumps(res))
実行結果の例 (JSONをjqコマンドで整形してあります)
{ "MessageId": "0106017903be5694-75c47c76-09fb-4da8-a430-1178fb4c1c04-000000", "ResponseMetadata": { "RequestId": "fd839fd9-914b-46bd-bb72-403c3da12446", "HTTPStatusCode": 200, "HTTPHeaders": { "date": "Sat, 24 Apr 2021 11:57:56 GMT", "content-type": "text/xml", "content-length": "326", "connection": "keep-alive", "x-amzn-requestid": "fd839fd9-914b-46bd-bb72-403c3da12446" }, "RetryAttempts": 0 } }
3. 添付ファイル付きメール送信のPythonコード
ファイル添付も以下の公式ドキュメントがわかりやすかったです。
Amazon SES API を使用して raw E メールを送信する - Amazon Simple Email Service
Pythonの email.mime
というパッケージを使うのですが、このパッケージに関する公式ドキュメントはこちら。
email.mime: Creating email and MIME objects from scratch — Python 3.8.9 documentation
boto3の send_email
の代わりに send_raw_email
というメソッドを使います。 email.mime
でエンコードしたメール本文を send_raw_email
でメール送信します。
import json from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication import boto3 from botocore.exceptions import ClientError profile = "default" region = "ap-northeast-1" session = boto3.session.Session(profile_name = profile, region_name = region) client = session.client("ses") email_from = "Sample <sample@gmail.com>" email_to = "sample_to@gmail.com" charset = "UTF-8" subject = "Amazon SES Test (SDK for Python)" body_text = "Hello, SES!" body_html = """<html> <head></head> <body> <p>Hello, <a href='https://aws.amazon.com/ses/'>Amazon SES</a>!</p> </body> </html> """ msg = MIMEMultipart('mixed') msg['Subject'] = subject msg['From'] = email_from msg['To'] = email_to msg_body = MIMEMultipart('alternative') msg_body.attach(MIMEText(body_text.encode(charset), 'plain', charset)) msg_body.attach(MIMEText(body_html.encode(charset), 'html', charset)) msg.attach(msg_body) # ローカルにある sample.txt をファイル添付 attachment = MIMEApplication(open("sample.txt", 'rb').read()) attachment.add_header('Content-Disposition', 'attachment', filename = "sample.txt") msg.attach(attachment) print(msg.as_string()) try: res = client.send_raw_email( Source = email_from, Destinations = [email_to], RawMessage = { 'Data': msg.as_string(), }, ) except ClientError as e: print(e.response["Error"]["Message"]) else: print(json.dumps(res))
以下は、 email.mime
でエンコードした結果( msg.as_string()
の部分の出力)の例です。
Content-Type: multipart/mixed; boundary="===============1385664818049781378==" MIME-Version: 1.0 Subject: Amazon SES Test (SDK for Python) From: Sample <sample@gmail.com> To: sample_to@gmail.com --===============1385664818049781378== Content-Type: multipart/alternative; boundary="===============0301123813487367193==" MIME-Version: 1.0 --===============0301123813487367193== MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 SGVsbG8sIFNFUyE= --===============0301123813487367193== MIME-Version: 1.0 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: base64 PGh0bWw+CjxoZWFkPjwvaGVhZD4KPGJvZHk+CiAgPHA+SGVsbG8sIDxhIGhyZWY9J2h0dHBzOi8v YXdzLmFtYXpvbi5jb20vc2VzLyc+QW1hem9uIFNFUzwvYT4hPC9wPgo8L2JvZHk+CjwvaHRtbD4K --===============0301123813487367193==-- --===============1385664818049781378== Content-Type: application/octet-stream MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="sample.txt" SGVsbG8K --===============1385664818049781378==--