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関数を記述して設定を行うだけで済んでしまいました。






