質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

Q&A

解決済

1回答

965閲覧

Amazon SESで、メール登録完了時に送信するlambdaでエラーが発生する。

MaeharaKenji

総合スコア86

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

0グッド

0クリップ

投稿2022/11/13 06:03

前提

現在、AWSのS3,SES,lambda,dynamodb等の活用方法を勉強しています。

AWS学習用の書籍に載っていたサンプルコードを参考にして、メールアドレスを登録したら、dynamodb に情報を登録し、同時に登録完了を通知する返信メールを送信するプログラムを作っています。

実現したいこと

AWS学習用の書籍を参考にメールアドレスを登録したら、dynamodbに情報を登録し、同時にAmazon SESで登録完了を通知する返信メールを送信するlambaを作成しました。

しかし、登録サイトに入力した氏名とメールアドレスの情報を入れて”登録”ボタンを押すと、dynamodbに登録はできているのに、エラーが発生し、画面に必ず”>内部エラーが発生しました。”というエラー発生時の表示が出ます。
成功した場合の”登録ありがとうございました。”のページは出てきません。
など、Amazon SESでのメール返信もできていません。

このようなエラーが発生した場合の対処方法を教えて下さい。

発生している問題・エラーメッセージ

A function update is still in progress so the invocation went to the previously deployed code and configuration. Test Event Name testRegist1028 Response { "statusCode": 200, "headers": { "content-type": "text/html" }, "body": "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"></head><body>内部エラーが発生しました。</body></html>" } Function Logs START RequestId: d0eb0df8-5f27-4d0e-aeb2-445089fd56df Version: $LATEST Traceback (most recent call last): File "/var/task/lambda_function.py", line 58, in lambda_handler username = param['username'][0] KeyError: 'username' END RequestId: d0eb0df8-5f27-4d0e-aeb2-445089fd56df REPORT RequestId: d0eb0df8-5f27-4d0e-aeb2-445089fd56df Duration: 2.35 ms Billed Duration: 3 ms Memory Size: 512 MB Max Memory Used: 69 MB Init Duration: 416.79 ms Request ID d0eb0df8-5f27-4d0e-aeb2-445089fd56df

lambdaのコード

python

1 2import json 3import boto3 4import urllib.parse 5import time 6import decimal 7 8# DynamoDB オブジェクト 9dynamodb = boto3.resource('dynamodb') 10 11# メール送信関数 12MAILFROM = 'example@example.com' 13 14def sendmail(to, subject, body): 15 client = boto3.client('ses', 'us-west-2') 16 17 response = client.send_mail( 18 Source=MAILFROM, 19 ReplyToAddresses=[MAILFROM], 20 Destination= { 21 'ToAddresses' : [ 22 to 23 ] 24 }, 25 Message={ 26 'Subject' : { 27 'Data' : subject, 28 'Charset' : 'UTF-8' 29 }, 30 'Body' : { 31 'Text' : { 32 'Data' : body, 33 'Charset' : 'UTF-8' 34 } 35 } 36 } 37 ) 38 39 40# 連番を更新して返す関数 41def next_seq(table, tablename): 42 response = table.update_item( 43 Key={ 44 'tablename' : tablename 45 }, 46 UpdateExpression="set seq = seq + :val", 47 ExpressionAttributeValues= { 48 ':val' : 1 49 }, 50 ReturnValues='UPDATED_NEW' 51 ) 52 return response['Attributes']['seq'] 53 54def lambda_handler(event, context): 55 try: 56 # フォームに入力されたデータを得る 57 param = urllib.parse.parse_qs(event['body']) 58 username = param['username'][0] 59 email = param['email'][0] 60 61 # クライアントのIPを得る 62 host = event['requestContext']['identity']['sourceIp'] 63 64 # シーケンスデータを得る 65 seqtable = dynamodb.Table('sequence') 66 nextseq = next_seq(seqtable, 'user') 67 68 69 # 現在のUNIXタイムスタンプを得る 70 now = time.time() 71 72 # 署名付きURLを作る 73 s3 = boto3.client('s3') 74 url = s3.generate_presigned_url( 75 ClientMethod = 'get_object', 76 Params = {'Bucket' : 'secretweb000', 'Key' : 'test.pdf'}, 77 ExpiresIn = 10, # 48 * 60 * 60, 78 HttpMethod = 'GET') 79 80 # userテーブルに登録する 81 usertable = dynamodb.Table("user") 82 usertable.put_item( 83 Item={ 84 'id' : nextseq, 85 'username' : username, 86 'email' : email, 87 'accepted_at' : decimal.Decimal(str(now)), 88 'host' : host, 89 'url' : url 90 } 91 ) 92 93 # メールを送信する 94 mailbody = """ 95 {0}様 96 97 ご登録ありがとうございました。 98 下記のURLからダウンロードできます。 99 100 {1} 101 """.format(username, url) 102 103 sendmail(email, "登録ありがとうございました", mailbody) 104 105 # 結果を返す 106 return { 107 'statusCode' : 200, 108 'headers' : { 109 'content-type' : 'text/html' 110 }, 111 'body' : '<!DOCTYPE html><html><meta charset="UTF-8"></head><body>登録ありがとうございました。</body></html>' 112 } 113 except: 114 import traceback 115 traceback.print_exc() 116 return { 117 'statusCode' : 200, 118 'headers' : { 119 'content-type' : 'text/html' 120 }, 121 'body' : '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body>内部エラーが発生しました。</body></html>' 122 } 123 124 125

S3に置いているメールアドレス登録ページ

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5</head> 6<body> 7 <form method="POST" action="https://*******.execute-api.us-west-2.amazonaws.com/prod/regist"> 8 氏名:<input type="text" name="username"><br> 9 メールアドレス:<input type="text" name="email"> 10 <input type="submit" value="登録"> 11 </form> 12</body> 13</html> 14

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

解決できました。
lambdaのテスト実行だと、
paramの中に何が入っているのか、printで確認したところ

python

1param = urllib.parse.parse_qs(event['body']) 2print(param)

結果が、
{}
このように表示され、何もデータが入っていないことに気づきました。
indexページにデータを入れていないから、確かにそうですね(^^;

そこで、index.htmlファイルのあるURLでデータを入力して、その結果をCloud watchで確認したところ、

CLOUD WATCHでの表示結果

json

1(省略) 2{'username': ['hogehoge'], 'email': ['hogehoge@hoge.com']} 3(省略)

このようにの受け渡しができていることを確認できました。

また、”登録ありがとうございました”の表示が出てこない原因は

AttributeError: 'SES' object has no attribute 'send_mail'

CLOUD WATCHに上記のような記述があり、
lambdaコードの下記のコードを変更することで、メール送信完了を確認できました。

python

1#response = client.send_mail( 間違い 2response = client.send_email(

投稿2022/11/14 05:53

編集2022/11/14 06:08
MaeharaKenji

総合スコア86

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問