CA MOBILE TECH BLOG

株式会社シーエー・モバイルのエンジニア・デザイナーの活動を綴るブログです

株式会社シーエー・モバイルの技術広報による、
技術に特化したブログです。
エンジニアとデザイナーの活動や思想を綴ってゆきます。

【 AWS移管物語-中- 】サービス移管プロジェクトで SendGrid を導入したお話

f:id:cam-engineer:20180222153409p:plain

目次

1. はじめに

こんにちは。久しぶりにエンジニアブログに投稿します。D.N です。

少し前に約2ヶ月間でサービスの移管を行うというプロジェクトに配属になりまして、そのなかで自分は主にメール関連のシステム移管に携わりました。 一口にメール関連といっても、移管対象としては、以下のように複数ありました。

  • メール送信サーバ
  • メール受信トリガーバッチ
  • メール配信サービス管理システム
  • メルマガ配信ASP

......

そのなかで、今回はメール送信サーバやメール受信トリガーバッチのために、メール配信サービスの SendGrid を導入したお話を紹介させていただきます。

2. 背景

今回のプロジェクトは、オンプレのサービスを AWS へ移管するということでスタートしたのですが、移管前のシステムでは、SMTPサーバとして、sendmail を使用しているようでした。 移管に際しては、そっくりそのまま移管前のシステム構成に準拠するのではなく、長期的な運用保守コストを下げたり、利便性の向上を図ることを目的として、メール配信サービスの SendGrid を導入することに決めました。

3. SendGrid とは

概要

SendGrid とはクラウド型メール配信サービスです。利用可能な機能として以下のようなものがあります。

  • リレーサーバとして利用可能
  • WEB API を利用したメール送信
  • メール受信をフックしてメールの内容を POST する機能
  • 様々な機能を API 経由で操作可能
  • メルマガの一括大量配信
  • 開封、クリックなどのイベント分析

ほかにも様々な機能がありますので、費用感含め気になる方は、サービスのサイトをご参照ください。

sendgrid.com

日本代理店はこちら。 sendgrid.kke.co.jp

4. 導入

SendGrid を利用するにあたって、導入する箇所としては大きく2点ありました。

  1. アラートメールや空メール等の通知処理
  2. メール受信をトリガーとするバッチ

4.1. アラートメールや空メール等の通知処理

移管前のシステムは、社内共通の SMTP サーバへリレーし、送信する方式のようでしたが、今回の移管においては それらのメール送信処理を、「SendGrid で発行する API キーを使用し、WEB API を利用する形でメール送信する処理方式」に変更しました。 既存システムの変更箇所が多く、実装の手間はありましたが、これにより MTA ソフトウェアを準備せずにスケーラブルなメール送信環境が導入できました。

※WEB API を利用するにあたっては、プログラミング言語ごとにライブラリが提供されており、C#, Go, Java, NodeJS, PHP, Python, Ruby がサポートされています。

そのほか、移管対象機能の中には、ユーザに対してサービス登録を促す空メールを送信するという機能も存在しており、 この部分については、メールの到達率が大切な部分になりますので、SPF/DKIM の設定が必要になってきます。

通常、自前でメールサーバを用意する場合は TXT レコードにこれらの設定を行う必要がありますが、 SendGrid では Domain Whitelabel という機能があり、この機能を利用することで、独自ドメインを利用した SPF/DKIM の設定が可能となります。

※DNS 設定を行う必要があることに変わりはありませんが、既存の DNS 設定に影響を与えず、CNAME の設定を追加すればよいため、管理がしやすくなるかと思います。

簡単に設定の流れを説明すると、次のようになります。 まずはじめに SendGrid の管理画面にて利用予定独自ドメインのサブドメインを登録し、3つの CNAME を発行します。 発行された CNAME を DNS に登録することによって SPF/DKIM が独自ドメインに変更されるようになります。

4.2. メール受信をトリガーとするバッチ

もう一つ、SendGrid を有効活用したところとしては、メール受信をトリガーとしてバッチ処理を実行する部分になります。 SendGrid には「Inbound Parse」という Webhook 機能があり、設定したドメイン宛に送信されたメールを SendGrid で受信した場合、 特定の URL へメールの内容を POST することができます。

※この機能を利用するためには、Domain Whitelabel が設定されている必要があります。

移管前のシステムでは、sendmail の aliases でメールの内容をパイプし、php のスクリプトに渡していましたが、 今回の移管においては、スクリプトはそのままの形で流用し、メール内容の受け渡し部分が変更になった形になります。

POST されるパラメータにおいて、メール本文は raw データとして受け取るか、パースされたものとして受け取るかの選択ができます。 以下は、raw データとして受け取る場合のパラメータになります。添付ファイルなどは、Email に含まれています。

  • dkim
  • Email
  • To
  • cc
  • From
  • Sender IP
  • Spam Report
  • Envelope
  • Subject
  • Spam_Score
  • Charsets
  • SPF

項目名からある程度意味合いは推測できるかと思いますが、詳細についてはこちらをご参照ください。

sendgrid.com

なお、SendGrid からの POST リクエストは、400系・500系の HTTP ステータスが返却された場合、 3日間に渡ってリトライを行うようですので、リトライをされたくない場合は、200系を返却する必要があります。

5. おまけ

SendGrid の Inbound Parse を使って機能開発を行う場合、SendGrid から POST リクエストしてもらうため、 外部からアクセス可能な WEB サーバが必要になります。

インクリメンタルに機能追加を行っていきたい場合にこのような制約は、開発のスピードを落とすことになりかねません。 そこで、ローカル環境に対してもアクセスをしてもらうためのツールとして、ngrok を使うとよいでしょう。

ngrok.com

ngrok は、ローカルのサーバに対して外部からアクセスできるようにトンネリングしてくれるツールです。

インストールして、以下のコマンドを叩けば、

ngrok http 3000

のようにコンソールに表示され、該当のURLでローカル環境にアクセスできるようになります。

Forwarding                    http://92832de0.ngrok.io -> localhost:3000
Forwarding                    https://92832de0.ngrok.io -> localhost:3000

サブドメインは起動ごとに変わるランダムな値ですので、このままだと不便なことがあります。 ※ちなみに、apahce などローカルの開発環境を再起動しても、ngrok は再起動しなくて大丈夫です。

サブドメインを固定したい場合、Sign up を行い、authtoken を手に入れ、

ngrok authtoken [トークン]
ngrok http -subdomain=hoge 3000

とすれば、http(s)://hoge.ngrok.io でアクセスできるようになります。 ※現在、Sign up は有料のようです。

ほかにも、-auth="username:password" のようにオプションをつければ、ベーシック認証をかけることもできます。

これで開発も捗りますね。

6. 注意点

SendGrid 経由で送受信したメールのイベントログを確認したい場合、ダッシュボードから Email Activity のメニューにて確認することができますが、 直近の7日間分のデータしか閲覧できないようです(それ以降のデータは削除されます)。 また、メール本文の内容も確認できませんので、詳細に長期間に渡って送受信のログを確認したいという場合は、「Event Webhook」の機能を使って、 ロギング用のサーバへ POST してもらうことで自前で管理する必要があるようです。

Event Webhook - ドキュメント | SendGrid

7. おわりに

今回、SendGrid を導入することで余計なサーバ管理工数を減らすことができました。 メールまわりは久々でしたが、DNS の設定含め、知見が増えたように思います(SendGrid に起因しない困難が多かったですが・・・)。 それ以外にも移管プロジェクト全体を通して、短期的なスケジュールの中でも技術的にチャレンジングな部分があり、大変勉強になりました。 引き続き、C.A.MOBILE TECH BLOG をよろしくお願い致します!