[Boto3 Adv-Cal DAY7]SESで送信元メールアドレスをチェックしつつ指定メールアドレスへの送信を試してみた

[Boto3 Adv-Cal DAY7]SESで送信元メールアドレスをチェックしつつ指定メールアドレスへの送信を試してみた

boto3 で楽しむ AWS PythonLife 一人AdventCalendarです。

boto3のドキュメントを通して、サービス別にどういった事が出来るのかを理解したり、管理コンソールを通さずにTerminalだけで完結できるように検証していくことが目的になります。

7日目はAmazon SESで、チェックしたメールアドレスに対して送信するロジックに挑戦してみました。

目次

boto3を通してSESで出来ること

ドキュメントは下記リンク先です。

ざっくりと以下のことができます。

  • 送信元メールアドレスの精査
  • 特定のサービスで特定のイベントが発生した時にメールが送信される設定
  • 受信ルールの操作(作成・削除)
  • 各種メールの送信(バルク・検証済み・定型)

今回の操作

指定したメールアドレスを精査して、有効であればメールを送信します。

  1. 送信元メールに指定されたメールアドレスの精査
  2. メールアドレスの指定
  3. 指定されたメールアドレスへ送信
% pytho main.py
Input Profile name [default]>>

Input mail address >> XXXXXXXXXX@XXXXX.com

main.py

import boto3
import os
import re
import argparse

class SESSimpleSendWizard:
    _source_mail_address='source@example.com'
    _client_name = 'ses'
    _session = None
    _message = {
        'Message': {
            'Subject': {
                 'Data': 'test',
                 'Charset': 'utf8'
            },
            'Body': {
                'Text': {
                    'Data': 'test',
                    'Charset': 'utf8'
                }        
            }
        }
    }

    def __init__(self, profile_name):
        self._session = boto3.Session(profile_name=profile_name, region_name='us-east-1')
        if not self.is_enable_identitiy_source():
            self.validate_mail(self.source)

    @property
    def session(self):
        return self._session

    def get_client(self, client_name=None):
        if not client_name:
            client_name = self._client_name
        return self.session.client(client_name)

    @property
    def source(self):
        return self._source_mail_address

    @property
    def message(self):
        return self._message

    @property
    def client_name(self):
        return self._client_name

    def send_mail(self, to):
        params = { 
            'Source': self.source,
                'Destination':{
                'ToAddresses': [to]
            }
        }
        params.update(self.message)
        return self.get_client().send_email(**params)

    def validate_mail(self, mail_address):
        params = {
            'EmailAddress': mail_address
        }
        return self.get_client().verify_email_identity(**params)

    def is_enable_identitiy_source(self):
        sources = self.get_identity_sources()
        return self.source in sources['Identities']

    def get_identity_sources(self):
        params = {
            'IdentityType': 'EmailAddress'
        }
        return self.get_client().list_identities(**params)

    @classmethod 
    def prompt_mail_address(cls):
        address = None
        while True:
            address = input('\nInput mail address >>')
            if address and len(address) != 0:
                break
        return address

    @staticmethod
    def prompt():
        default_profile_name = 'default'
        profile_name = input('Input Profile name [{}]>> '.format(default_profile_name))
        if len(profile_name) == 0:
            profile_name = default_profile_name
        wizard = SESSimpleSendWizard(profile_name)

        mail_address = wizard.prompt_mail_address()
        result = wizard.send_mail(mail_address)

if __name__ == '__main__':
    SESSimpleSendWizard.prompt()

送信元メールアドレスの検証

ロジック中に埋め込み設定をしたメールアドレスへ、verify_email_identity()を通して

Amazon Web Services – Email Address Verification Request in region US East (N. Virginia)

の件名でメールが届きます。本文にあるhttps://email-verification...で始まるリンクを選択して検証を完了させます。

エンドポイント

接続先については、以下のAWSドキュメントを参照してください。

今回のロジックでは、プロファイル指定地にリージョンを**us-east-1**で上書きすることで対処しています。

まとめ

今回はサンドボックス上にて、特定のメールアドレスに向けた1通のみ送信での検証を行いました。併せて、利用可能リージョンや送信元メールアドレスの検証等、環境を問わないと思われる要チェックなポイントも複数挟んでみました。

本番環境での送信時には環境特有の前提等も絡んでくると思われるので、それらの検証も必要になると思われます。