サーバーレス 問い合わせフォーム AWS s3/lambda/cognito/ses/slack

目次

webサーバを使用せず、s3 でwebを公開してる際のお問い合わせフォームの実装方法です。



前提

※参考 yarn と parcel と riot を使って簡単な webサイトを作ってみた Webpack + Riot + Materializeで、Webサイト環境を作った話

処理の流れ

やること

s3にbucket作成

s3にフォームからupされる専用バケットを作成します。 一応指定のサイト以外からアップされないように「CORS設定」をしておく(本番反映後設定したほうがローカルでの開発中に楽)

アクセス権限 -> CORSの設定

<!-- Sample policy -->
<CORSConfiguration>
  <CORSRule>
    <AllowedOrigin>開発中は * 公開後 公開ドメインに変えた方がいい</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule>
</CORSConfiguration>

cognito設定

Cognitoについては下記を参考にすると理解できそうです。

https://dev.classmethod.jp/cloud/aws/what-is-the-cognito/

cognito IDプールを作成する

次の画面に進むみ、詳細を表示 キャプチャ jsコードを控えておく

ポリシーを作成し、ロールにアタッチする

作成されたcognitoのロールに対して、s3バケットへのファイルup権限を追加します。

作成されたポリシーをロールにアタッチする

※ IDプール作成時にポリシー詳細にて設定したほうが楽かも

※ この手順は、cognito IDプール作成じにポリシーの設定からやったほうが楽かもしれません。

一応、これでcognitoの準備はOKです。

slackの準備

とりあえずこちらの方法を参考にさせていただきました。

http://reiki4040.hatenablog.com/entry/2017/01/30/001634

webhookのURLだけ、コピーして控えておきます。

sesの準備

sesは、リージョンが限られているので、限られたリージョンの中から、選択する。

lambda設定

指定のS3バケットにデータがupされたら、upされたファイルの情報を元に、そのメールアドレスへ送付するし、管理側には、slackにて、通知する 最初に作成した、s3のバケットを使用します。

まずは、lambdaより、sesへのアクセスを行うのに、ロールの設定をします。

ロールを作成

lambda関数を作成

Awsコンソールより、Lambdaを選択し、関数の作成をクリック

これで関数の作成

トリガーの設定

左側のリストからトリガーを追加します。

フォーム実装

例では、roit.jsを使っていますが、必要に応じて変更して下さい。

$ yarn add aws-sdk

コード

// Amazon Cognito 認証情報プロバイダーを初期化します
AWS.config.region = 'us-west-2';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
  IdentityPoolId: 'xx-xxxx-xx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
});
submit (event) {
  event.preventDefault()

  let s3BucketName = "バケット名"

  let email = this.refs.email.value
  let name = this.refs.name.value
  let body = this.refs.message.value
  let submit = this.refs.submit
  submit.disabled = true

  let now = new Date();
  let obj = {"name":name, "email":email , "body":body, "date": now.toLocaleString()}
  let s3 = new AWS.S3({params: {Bucket: s3BucketName}});
  let blob = new Blob([JSON.stringify(obj, null, 2)], {type:'text/plain'});
  s3.putObject({Key: "uploads/" +now.getTime()+".txt", ContentType: "text/plain", Body: blob, ACL: "public-read"},
    function(err, data){
      if(data !== null){
        // 成功処理
      }
      else{
        // 失敗処理
      }
    }
  );
}

webに公開後

s3のバケットのCORSの設定で、ドメインを指定して、指定ドメイン以外からfileをアップできないようにしておきましょう。

まとめ

cognito のIDプールを使用して、s3へファイルアップ、lambda関数より検知して、sesとslackにメッセージを送信することができました。 ec2等webサーバーを使っていればサーバ側で処理をして実装可能ですが、サーバーレスにして、この方法でも簡単に実装でき、トータル的な料金も、全然安いです。 ちょっとしたwebサイトなら本当にwebサーバーは不要になってきましたね。

ご意見ご指摘があったらお願いします。

U-chan ( Nobuyuki Ukai )

学生時代は建築やデザインを専攻していたが、Yahoo!Japanにエンジニアとして運良く入社し、2年半で波情報を配信する波伝説に転職。3年後、Yahoo!時代の先輩の立ち上げたベンチャーに転職。数年後、伊豆下田に移住し、ゲストハウスを開業しながらリモートでエンジニアを続けたが、焼肉店の開業とともに株式会社UKAIを立ち上げ、法人成り。その後、カフェとゲストハウスをもう一軒開業し、現在は焼肉店、カフェ、ゲストハウス2件目を運営。今季は自社Webサイトの立ち上げ予定!

comments powered by Disqus