API GatewayとLambdaとSESでメールを送信するAPIを作る
Amazon Simple Email Service (Amazon SES)は、メール送受信のためのサービスです。
余談ですが、SESと聞くと(System Engineering Service)の方を連想しがち。
かくゆう私もかつてはSESでドナドナされてました(遠い目)。
さて、今回はLambdaとAPI Gatewayと組み合わせてメールを送信するAPIを作ってみます。
構成図にするとこんな感じ、シンプルですが立派なサーバレスです(ふんす!)。
サンドボックスモードのまま使うなら、送受信に使用するメールアドレスを事前に登録しておきましょう。
メールアドレスを登録すると、そのアドレスに認証リンク付きのメールが届くので、リンクを踏むと認証が完了します。
SESを使うには、Lambdaのロールに「AmazonSESFullAccess」のポリシーを割り当てます。
ここでは、呼び出しのパスを
「Lambda プロキシ統合の使用」をオンにするとより詳細なリクエストの内容がevent変数に格納されます。
今回は「Lambda プロキシ統合の使用」をオンにした状態のリクエストを受けられるようにLambda関数を作っているので、オンにします。
先ほど作ったLambda関数を設定します。
モデルを作成して、メソッドに割り当て、リクエストの検証を設定することで、パラメータが不正の場合400エラーを返してくれるようになります。
Lambda関数側でのリクエストパラメータのバリデーションチェックを簡略化することができます。
API Gatewayは開発、本番など環境を分けられるよう、ステージという単位でデプロイできるようになっています。
ステージを作成すると、エンドポイントとなるURLが得られるのでAPIにリクエストを行うことができます。
リクエストが成功し、メールも届きました。
通常なら、こういったことがやりたければメールサーバーとAPIサーバーを建てなければいけないところが、AWSのサーバーレスアーキテクチャを使えば、Lambda関数を記述して設定を行うだけで済んでしまいました。
余談ですが、SESと聞くと(System Engineering Service)の方を連想しがち。
かくゆう私もかつてはSESでドナドナされてました(遠い目)。
さて、今回はLambdaとAPI Gatewayと組み合わせてメールを送信するAPIを作ってみます。
構成図にするとこんな感じ、シンプルですが立派なサーバレスです(ふんす!)。
目次
SESを準備する
SESはデフォルトだとサンドボックスモードという事前に認証したメールアドレスしか送受信できないモードになっています。サンドボックスモードのまま使うなら、送受信に使用するメールアドレスを事前に登録しておきましょう。
メールアドレスを登録すると、そのアドレスに認証リンク付きのメールが届くので、リンクを踏むと認証が完了します。
Lambda関数を準備する
Lambda関数は公式ドキュメントを参考にPythonを使って記述します。SESを使うには、Lambdaのロールに「AmazonSESFullAccess」のポリシーを割り当てます。
import json import logging import boto3 from botocore.exceptions import ClientError logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): logger.info(event) body = json.loads(event['body']) SENDER = body['sender'] RECIPIENT = body['recipient'] AWS_REGION = "us-east-1" SUBJECT = "Amazon SES Test (SDK for Python)" BODY_TEXT = ("Amazon SES Test (Python)\r\n" "This email was sent with Amazon SES using the " "AWS SDK for Python (Boto)." ) BODY_HTML = """<html> <head></head> <body> <h1>Amazon SES Test (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> """ CHARSET = "UTF-8" 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': { 'Html': { 'Charset': CHARSET, 'Data': BODY_HTML, }, 'Text': { 'Charset': CHARSET, 'Data': BODY_TEXT, }, }, 'Subject': { 'Charset': CHARSET, 'Data': SUBJECT, }, }, Source=SENDER, ) except ClientError as e: return { 'isBase64Encoded': False, 'statusCode': 500, 'headers': {}, 'body': '{"message": "' + e.response['Error']['Message'] + '"}' } else: return { 'isBase64Encoded': False, 'statusCode': 200, 'headers': {}, 'body': '{"message": "Email sent! Message ID:' + response['MessageId'] + '"}' }送信元と送信先のメールアドレスをリクエストパラメータで渡せるようにしています。
API Gatewayを設定する
先ほど作ったLambda関数をAPIとしてコールできるよう、API Gatewayを設定していきます。リソースの作成
APIとしてのリソースを定義します。ここでは、呼び出しのパスを
/ses/send
としています。メソッドの作成
リソースに割り当てるhttpsメソッドとメソッドによって呼び出されれるものを定義します。「Lambda プロキシ統合の使用」をオンにするとより詳細なリクエストの内容がevent変数に格納されます。
今回は「Lambda プロキシ統合の使用」をオンにした状態のリクエストを受けられるようにLambda関数を作っているので、オンにします。
先ほど作ったLambda関数を設定します。
モデルの作成
モデルというリクエスト・レスポンスのスキーマ定義を作成できます。{ "$schema": "https://json-schema.org/draft-04/schema#", "title": "SesSendReqest", "type" : "object", "required": ["sender", "recipient"], "properties" : { "sender" : { "type" : "string" }, "recipient" : { "type" : "string" } } }
モデルを作成して、メソッドに割り当て、リクエストの検証を設定することで、パラメータが不正の場合400エラーを返してくれるようになります。
Lambda関数側でのリクエストパラメータのバリデーションチェックを簡略化することができます。
APIのデプロイ
設定が完了したらAPIをデプロイします。API Gatewayは開発、本番など環境を分けられるよう、ステージという単位でデプロイできるようになっています。
ステージを作成すると、エンドポイントとなるURLが得られるのでAPIにリクエストを行うことができます。
APIにリクエストを行う
それではPostmanを使ってリクエストを行ってみます。リクエストが成功し、メールも届きました。
通常なら、こういったことがやりたければメールサーバーとAPIサーバーを建てなければいけないところが、AWSのサーバーレスアーキテクチャを使えば、Lambda関数を記述して設定を行うだけで済んでしまいました。
ディスカッション
コメント一覧
まだ、コメントがありません