API Gateway&Lambda&DynamoDBデプロイエラー集


エラー集

SlackBoltを使用して作成したSlackBotを、API GatewayとLambdaでデプロイした際に、かなりエラーと出会いました。今後開発される方(と自分)の参考になればと思い、開発中に出会ったエラー集まとめました。

Slack上でAPIを登録する際にURLが正しくないとエラーが起きる

index.js
var body = JSON.parse(event.body);
if (body.type == 'url_verification') {
    const res = { challenge: body.challenge }
    return {statusCode: 200, body: JSON.stringify(res) }
  }

SlackAPIリファレンス

APIを叩いた後にエラーが起きる

"errorMessage": "No token and no authorize options provided. Apps used in one workspace should be initialized with a token. Apps used in many workspaces should be initialized with a authorize.",

APIGatewayのログをcloud watchに出力する際のエラー

解決策はこれっぽいぞ
API Gateway API をトラブルシューティングするために CloudWatch ログを有効化するにはどうすればよいですか?

無限ループする

人気者みたいに通知止まらない。
秒間2通くらいメッセージ飛んでくる...

原因は凡ミスで、SlackAPIのInteractive Componentsの設定でメッセージが投稿されたらLambdaをキックするイベントを登録していたため、メッセージが投稿されるたびにlambdaが叩かれめちゃくちゃメッセージが届く仕様になってしまっていた。。

API GatewayからLambdaを叩く際のエラー

400_client_error でエラーが起きている

パラメータを整形する方法は2つある。
1. API Gatewayの統合リクエストでマッピングテンプレートを作成する
https://maitakeramen.hatenablog.com/entry/2019/02/22/105438
2. API Gatewayの統合リクエストでLambda プロキシ統合の使用にチェックする
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html

今回は2の方法でエラーを解消。

APIGatewayから送信された値を整形する&パラメータデコードする

CloudWatchLog
(54b5c973-9a0e-4109-8082-6dffa303f3d8) Method request body before transformations: payload=%7B%22type%22%3A%22message_action%22%2C%22token~~~~~~`block_id%22%3A%221o [TRUNCATED]

どうやらパラメータの値が整っていないらしい。
ログから確認すると、パラメータに不要なpayload=' がついていたり、オブジェクトではなかったりでパラメータが取り出せない問題がありました。

ここまでくるのに、めちゃくちゃ時間が掛かりました。
何と言っても、LambdaとAPIGatewayのデバッグに時間かかりすぎて...

パラメータを整えて、オブジェクトに変換します

index.js
  const body_split = event.body.split('payload=').join('');
  const event_body = decodeURIComponent(body_split);
  var obj = JSON.parse(event_body);

特定の文字列を削除する方法
正規表現を使わない場合は、以下のようにsplitとjoinを組み合わせる方法があります。
splitを実行してaで区切った配列に変換し、joinで配列を全て結合することにより、区切り文字のaが削除されるという方法です。

参考例
var str = 'abcabc';
console.log(str.split('a').join('')); // "bcbc"

-----------------
// jsonぽい形のデータをオブジェクト化する
var date ='{"ts":+"1573443403.004500",+"title":+"テストテスト",+"channel":+"QWERTY~~"}'
var body_split = date.split('+').join('');
var date = (new Function("return " + body_split))();
console.log(date);


JSONらしき文字列をオブジェクトに変換するJavaScript

Lambda実行時刻が、UTCになってしまう問題

Lambdaコンソール上の環境変数の設定をしよう。
process.env.TZ = "Asia/Tokyo";
LambdaのNode.js v8.10でタイムゾーンを指定してもDateがUTCになる問題

DynamoDBに空欄は保存できないエラー

DynamoDBに空欄は保存できないため、ValidationExceptionエラーがでてしまう。
ValidationException: ExpressionAttributeValues contains invalid value: One or more parameter values were invalid: An AttributeValue may not contain an empty string for key
以下のサイトを参考にして、空欄許可のオプションを追加することで、nullとしてDBに保存される。
DynamoDB は空の値を登録できないけど DynamoDB document client のコンストラクタにオプションを渡すだけで空の値を NULL 型には変換できるよ?

まとめ

1つのエラーを解消したと思ったら、割とすぐに次のエラーに出会って心折れそうになったので、
😉とか😘とかでエラーメッセージをポップにしてみました。

今回のエラーをメモ程度にまとめておいたことで、割と自分に救われました。
誰かの何かの参考になれば幸いです!

もし何か修正箇所があれば、教えていただけると助かります。

今回の実装で参考にしたサイト