はじめに
今回は AWS SES を試します。
メールを受信し、Webページ上で確認できる機能を作ります。
SESの機能を利用するにあたりリージョンの制限があった為、バージニア北部(us-east-1)リージョンで作成しました。
[Lambda関数・SAMテンプレート]
(https://github.com/tanaka-takurou/serverless-ses-page-go)
準備
[AWS SESの資料]
Amazon Simple Email Service 開発者ガイド
作業手順の概略
- ドメイン登録
- ドメイン検証
- サーバーレスアプリケーションのデプロイ (今回作成した AWS SAM テンプレートはこちら)
- 管理コンソールのRule Sets設定画面からRule Set の アクティベート
AWS SAM テンプレート作成
AWS SAM テンプレートで API-Gateway , Lambda, AWS SES, DynamoDB, S3 の設定をします。
[参考資料]
AWS SAM テンプレートを作成する
AWS SESの設定は以下の部分
ReceiptRuleSet:
Type: AWS::SES::ReceiptRuleSet
Properties:
RuleSetName: !Ref ReceiptRuleSetName
ReceiptRule1:
Type: AWS::SES::ReceiptRule
Properties:
RuleSetName: !Ref ReceiptRuleSetName
Rule:
Name: !Ref ReceiptRuleName1
Enabled: true
ScanEnabled: true
TlsPolicy: !Ref TlsPolicy
Actions:
- S3Action:
BucketName: !Ref EmailBucket
ReceiptRule2:
Type: AWS::SES::ReceiptRule
Properties:
RuleSetName: !Ref ReceiptRuleSetName
After: !Ref ReceiptRule1
Rule:
Name: !Ref ReceiptRuleName2
Enabled: true
ScanEnabled: true
TlsPolicy: !Ref TlsPolicy
Actions:
- LambdaAction:
FunctionArn: !GetAtt ReceiptFunction.Arn
※ メールを受信した際に、S3に保存しLambda関数を呼び出す設定にしました。
Lambda関数作成
※ Lambda関数は aws-lambda-go を利用しました。
SESからメールデータを受け取り、DynamoDBに件名などのデータを入力する処理
func HandleRequest(ctx context.Context, sesEvent events.SimpleEmailEvent) error {
for _, record := range sesEvent.Records {
ses := record.SES
err := putMailInfo(ctx, ses.Mail.CommonHeaders.To[0], ses.Mail.CommonHeaders.Date, ses.Mail.MessageID, ses.Mail.CommonHeaders.From[0], ses.Mail.CommonHeaders.Subject)
if err != nil {
log.Println(err)
log.Printf("CommonHeaders %+v", ses.Mail.CommonHeaders)
}
}
return nil
}
func putMailInfo(ctx context.Context, to string, date string, file string, from string, subject string) error {
item := MailInfoData {
To: to,
Date: date,
File: file,
From: from,
Subject: subject,
}
av, err := attributevalue.MarshalMap(item)
if err != nil {
return err
}
err = put(ctx, os.Getenv("TABLE_NAME"), av)
if err != nil {
return err
}
return nil
}
S3からメールデータを取得し、メール本文を抜き出す処理
func getMailBody(ctx context.Context, objectKey string)(string, error) {
if len(objectKey) == 0 {
return "", fmt.Errorf("Error: %s", "No ObjectKey.")
}
if s3Client == nil {
s3Client = s3.NewFromConfig(getConfig(ctx))
}
input := &s3.GetObjectInput{
Bucket: aws.String(os.Getenv("BUCKET_NAME")),
Key: aws.String(objectKey),
}
res, err := s3Client.GetObject(ctx, input)
if err != nil {
return "", err
}
rc := res.Body
defer rc.Close()
tmpData, err := ioutil.ReadAll(rc)
if err != nil {
log.Println(err)
return "", err
}
if len(string(tmpData)) < 1 {
return "", fmt.Errorf("Error: %s", "Empty Mail Body.")
}
strNormalized := regexp.MustCompile("\r\n").ReplaceAllString(string(tmpData), "\n")
rawMailLines := regexp.MustCompile(`\n\s*\n`).Split(strNormalized, -1)
if len(rawMailLines) < 2 {
return "", fmt.Errorf("Error: %s", "Empty Mail Body.")
}
return rawMailLines[1], nil
}
終わりに
AWS SES でメールを受信できるよう設定し、Webページ上からメールを確認出来るようにしました。
AWS SES を利用しメールの送信も行える為、今後試そうと思います。
参考資料
Amazon SESでRule Setが動作しない(送信側で「Requested action not taken: mailbox unavailable」となる)