SendGrid Receiver on AWS

Page content

SendGrid の Incoming Webhook 経由でメールを受け取るシステムをサーバーレスアーキテクチャで作りました。

目的

  • 簡易なメール受信機
  • 削除されてもいいやつを受ける
    • もしくは待避機能をつける
  • 通知はslack
  • 詳細の閲覧は html
  • 送信・返信・転送は特にしない
    • どうしてもしたければ 別のメーラー からでも送信元いじって送ればいい

採用した技術・ツール

  • SendGrid Incoming Webhook
  • Amazon API Gatewawy
  • AWS Lambda
  • AWS Lambda@Edge (optional)
  • Amazon S3 bucket
  • Amazon CloudFront
  • slack
  • serverless framework

詳細

ノウハウなど

成果物

github で公開: https://github.com/take4mats/sendgrid-receiver-aws

構成

  • SendGrid Incoming Webhook
    • SendGrid can POST received email to specified API
  • Amazon API Gatewawy
  • AWS Lambda
  • Amazon S3 bucket (email objects converted to html)
  • Amazon CloudFront
    • optional: Lambda@Edge で認証など

Tips

実際の構築を経てハマったこと、工夫したところ

multipart/form-data のパース

メールの Content-Type は multipart/form-data となっており、 boundary の記号で本文を区切ってパースしないといけない独特な形式なので、加工には手間がいりそう。 頑張ってライブラリを探したらちゃんと先人が作ってくれていて、どうやらちゃんと扱えそうだ。

sls deploy 時に必要な外部ライブラリも一緒にデプロイ

Lambda のランタイムを python 3.6 にすることはあっても、外部ライブラリをあれこれ入れるのは始めてだったので、うまく serverless framework で管理してやりたいということで、初チャレンジだった。

  • まず、 npm モジュール serverless-python-requirements をインストールする

    npm install --save serverless-python-requirements
    
  • 続いて、 serverless.yml に追記. pluginscustom のところに書きます。

    plugins:
      # ...
      - serverless-python-requirements  # allow pip
      # ...
    custom:
      # ...
      pythonRequirements:
        dockerizePip: true
      # ...
    
  • 参考: Serverless Frameworkを使ってAWS Lambdaにdeployできる環境を作る

S3 に置いた html ファイルの content-type がおかしい

どうも index.html ファイルへのリンクを押すとブラウザからダウンロードされてしまっておかしいなぁと思ったら、 Content-Type: binary/octet-stream となっていた!(確認方法: S3 bucket で対象ファイルのメタデータを見る or curl 等でダウンロードしたときの html ヘッダを見る)

参考: S3に置いたhtmlファイルがブラウザダウンロードされてしまう時

Todo

2019/06/15時点でとりあえず簡潔に html でためて slack 通知もして、は動くようになったが、他にも色々

  • 一覧ページを静的 html+js+css くらいで作成 (vue.js 勉強がてら?)
    • 場合によってはデータベース使って管理(一覧化のためにメタデータのみか、重厚にメッセージ本体もか)
  • 削除をしやすく
    • 閲覧中に削除
    • 一覧から選んで削除
    • 場合によっては古いものは自動で削除
  • 認証の見直し?

その他

(ボツ) Linux サーバでチュートリアル

SendGrid 公式のチュートリアルで Incoming Webhook に馴染んでおこう、ということで一番最初に試してみた構成。 Incoming Webhook を受けられる デモアプリを使って受信し、 slack にメールを転送するところまで。

やったこと

  • slack
    • webhook の token 取得しておく
  • sendgrid-inbox
    • git clone (sendgrid-demobox)
    • rename it to sendgrid-inbox
    • Gemfile 編集, slack-incoming-webhook を追加など
    • bundle install –path=.bundle
    • src/slack.rb 作成
    • .env に色々書く. domain, user/passwd, slack webhook
    • bundle exec rackup
  • development
    • install ngrok (see my github account for more details)
    • run ngrok: ngrok http 9292
    • SendGrid の webコンソールから incoming webhookの登録
    • ドメイン管理
      • test.georgeorge.com の MX レコードを追加
    • コレで動く!
    • 色々動作確認していじったら、 git commit, git push -> 自分のrepository へ
  • production
    • アプリ
      • repository から git clone
      • bundle install
      • rackup -p 9292 -h 0.0.0.0
    • SendGrid の webコンソールから incoming webhookの登録
      • georgeorge.com –> https://id:pw@おれのさば:9292/receive
    • ドメイン管理
      • georgeorge.com の MX レコードを追加
    • コレで動く!