LoginSignup
8
9

More than 3 years have passed since last update.

SESとPythonでメールの送信者が文字化けしないようにする

Last updated at Posted at 2019-07-24

Pythonを使ってSESでメールを送る際、送信者(From)に日本語を使うと文字化けします。

https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-using-sdk-python.html

↑の公式サンプルコードをもとにメールを送信してみます。

文字化けするパターン

まずは何も考えず、そのまま宛先に日本語をセットしたパターンです。

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@gmail.com>"

# Replace recipient@example.com with a "To" address. If your account 
# is still in the sandbox, this address must be verified.
RECIPIENT = "fuga@gmail.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@gmail.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@gmail.com" <fuga@gmail.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@gmail.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@gmail.com"

# Replace recipient@example.com with a "To" address. If your account 
# is still in the sandbox, this address must be verified.
RECIPIENT = "fuga@gmail.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@gmail.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@gmail.com" <fuga@gmail.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のエンコードが変わり、メーラでも日本語が化けずに表示されます。

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9