Pythonを使ってSESでメールを送る際、送信者(From)に日本語を使うと文字化けします。
↑の公式サンプルコードをもとにメールを送信してみます。
文字化けするパターン
まずは何も考えず、そのまま宛先に日本語をセットしたパターンです。
ses_send.py
import boto3
from botocore.exceptions import ClientError
# Replace sender@example.com with your "From" address.
# This address must be verified with Amazon SES.
SENDER = "テスト <hoge+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 = "fuga@example.com"
# If necessary, replace us-west-2 with the AWS Region you're using for Amazon SES.
AWS_REGION = "us-east-1"
# The subject line for the email.
SUBJECT = "Amazon SES テスト (SDK for Python)"
# The email body for recipients with non-HTML email clients.
BODY_TEXT = ("Amazon SES テスト (Python)\r\n"
"This email was sent with Amazon SES using the "
"AWS SDK for Python (Boto)."
)
# The HTML body of the email.
BODY_HTML = """<html>
<head></head>
<body>
<h1>Amazon SES テスト (SDK for Python)</h1>
<p>This email was sent with
<a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
<a href='https://aws.amazon.com/sdk-for-python/'>
AWS SDK for Python (Boto)</a>.</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)
# Try to send the email.
try:
#Provide the contents of the email.
response = client.send_email(
Destination={
'ToAddresses': [
RECIPIENT,
],
},
Message={
'Body': {
'Text': {
'Charset': CHARSET,
'Data': BODY_TEXT,
},
},
'Subject': {
'Charset': CHARSET,
'Data': SUBJECT,
},
},
Source=SENDER
)
# 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'])
実行します。
>python ses_send.py
Email sent! Message ID:
0100016c23fd79b6-efee9a81-212b-4c27-a5b7-81249789bdb0-000000
受信したメール。
MIME-Version: 1.0
Date: Wed, 24 Jul 2019 21:38:32 +0900
From: =?utf-8?Q?=C6=B9=EF=BF=BD?= <hoge+sender@example.com>
Subject: =?utf-8?Q?Amazon_SES_=E3=83=86=E3=82=B9=E3=83=88_(SDK_for_Python)?=
Thread-Topic:
=?utf-8?Q?Amazon_SES_=E3=83=86=E3=82=B9=E3=83=88_(SDK_for_Python)?=
To: "fuga@example.com" <fuga@example.com>
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"
Amazon SES =E3=83=86=E3=82=B9=E3=83=88 (Python)
This email was sent with Amazon SES using the AWS SDK for Python (Boto).
同じテストという文言がFromの部分だけエンコードが違っています。
これは、テスト <hoge+sender@example.com>
という文字列全体にマルチバイトを考慮しないエンコードがかかることで引き起こされる現象です。
このためメーラーで開いたときに送信者だけが化けてしまいます。
文字化けしないパターン
Fromにセットするときに、送信者とメールアドレスを分けてエンコードがすると文字化けしません。
先ほどのスクリプトに手を加えます。
ses_send.py
import boto3
from botocore.exceptions import ClientError
from email.header import Header # eemail.headerをインポート
# Replace sender@example.com with your "From" address.
# This address must be verified with Amazon SES.
# 送信者の名前とアドレスに変数を分ける
SENDER_NAME = "テスト"
SENDER_ADDR = "hoge+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 = "fuga@example.com"
# If necessary, replace us-west-2 with the AWS Region you're using for Amazon SES.
AWS_REGION = "us-east-1"
# The subject line for the email.
SUBJECT = "Amazon SES テスト (SDK for Python)"
# The email body for recipients with non-HTML email clients.
BODY_TEXT = ("Amazon SES テスト (Python)\r\n"
"This email was sent with Amazon SES using the "
"AWS SDK for Python (Boto)."
)
# The HTML body of the email.
BODY_HTML = """<html>
<head></head>
<body>
<h1>Amazon SES テスト (SDK for Python)</h1>
<p>This email was sent with
<a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
<a href='https://aws.amazon.com/sdk-for-python/'>
AWS SDK for Python (Boto)</a>.</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)
# Try to send the email.
try:
#Provide the contents of the email.
response = client.send_email(
Destination={
'ToAddresses': [
RECIPIENT,
],
},
Message={
'Body': {
'Text': {
'Charset': CHARSET,
'Data': BODY_TEXT,
},
},
'Subject': {
'Charset': CHARSET,
'Data': SUBJECT,
},
},
# Header関数を使いISO-2022-JPにエンコード
Source='%s <%s>'%(Header(SENDER_NAME.encode('iso-2022-jp'),'iso-2022-jp').encode(),SENDER_ADDR)
)
# 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'])
これで実行します。
>python ses_send.py
Email sent! Message ID:
0100016c241237ba-ca70ada5-4add-4641-8f97-dfaf904f8de7-000000
受信したメール。
MIME-Version: 1.0
Date: Wed, 24 Jul 2019 22:01:11 +0900
From: =?utf-8?Q?=E3=83=86=E3=82=B9=E3=83=88?= <hoge+sender@example.com>
Subject: =?utf-8?Q?Amazon_SES_=E3=83=86=E3=82=B9=E3=83=88_(SDK_for_Python)?=
Thread-Topic:
=?utf-8?Q?Amazon_SES_=E3=83=86=E3=82=B9=E3=83=88_(SDK_for_Python)?=
To: "fuga@example.com" <fuga@example.com>
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"
Amazon SES =E3=83=86=E3=82=B9=E3=83=88 (Python)
This email was sent with Amazon SES using the AWS SDK for Python (Boto).
先ほどとFromのエンコードが変わり、メーラでも日本語が化けずに表示されます。