Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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のエンコードが変わり、メーラでも日本語が化けずに表示されます。

danishi
cloudpack
Amazon Web Services (AWS) の導入設計、環境構築、運用・保守をサポートするマネジドホスティングサービス
https://cloudpack.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away