2020年12月14日
プログラミング
SendGridのEvent Webhookについて調査してみた


目次
はじめに
今日は新しい技術にチャレンジし続けるpalanのアドベントカレンダーDay「14」です!
昨日は「デザインの方向性を決めるムードボードの作り方とコツ」のお話でした。
今回は弊社でも使用することのあるメール配信サービスのSendGridのEvent Webhookについてご紹介いたします。
SendGridについて
SendGridとは?
SendGridはクラウドベースのメール配信サービスです。
railsチュートリアルにも使われていたり、これまた有名なPaaSのHerokuとも容易に連携できるので
railsエンジニアであれば知らない人はほぼいないのではないでしょうか!
クラウドなのでメールサーバの構築も不要かつアカウントを作成するだけですぐに利用できるとても便利なサービスです。
Railsへの導入方法
Railsアプリへの実装方法は以下になります!今回は既に導入済みの前提で進めていきます。
Event Webhookについて
Event Webhookとは
SendGridのEvent Webhookは、SendGridを経由してメールを送信するとイベントが発生されます。
代表的な例で言えば、delivered(配信)、open(メールの開封)、click(クリック)deferred(遅延)などがあります。
これらのイベントを、指定したURLにPOSTすることがで、メール配信の成功率や、メールのクリック数・開封率、届かなかったメールの特定など様々な分析が可能になります。
また、メールごとにカテゴリーなどを設定できるので、送ったメールごとにより細かい分析ができるようになります。
SendGridは登録した後UI画面でも上記のデータは確認できるのですが、最高7日までしか保存ができないようです。
しかし、Event Webhookを使えば全てのデータを保存・加工することが可能になります。
詳細は以下をご確認ください。
Event Webhookについて
Event Webhookで取得できるイベント
イベントにはタイプがあり、タイプによって取得できるパラメータが異なります。
以下はこちらのページより抜粋したイベントの情報です。
https://SendGrid.kke.co.jp/docs/API_Reference/Webhooks/event.html#-Event-Types
また、sg_event_idとsg_message_idはSendGrid側から付与されるUUIDです。
エンゲージ系イベント
引数 | 説明 |
---|---|
event | bounce、deferred、delivered、dropped、processed のなかのどれか |
宛先のメールアドレス | |
timestamp | UNIXタイムスタンプ |
smtp-id | システムに付与されるメッセージID |
ip | イベント発生元のIPアドレス |
tls | メール送信のTLS使用有無 |
cert_err | 受信タイミングでの認証エラー有無 |
公式テストデータのサンプル
{
"email"=>"example@test.com",
"timestamp"=>1607866697,
"smtp-id"=>"<14c5d75ce93.dfd.64b469@ismtpd-555>",
"event"=>"open",
"category"=>["cat facts"],
"sg_event_id"=>"Yy_t6KnYuDsbs_OAjoWUIg==",
"sg_message_id"=>"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0",
"useragent"=>"Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
"ip"=>"255.255.255.255"
}
上記のopenやclickはSendGridUIのSetting>Trackingから設定できます。
配信系イベント
引数 | 説明 |
---|---|
event | bounce、deferred、delivered、dropped、processed のなかのどれか |
宛先のメールアドレス | |
timestamp | UNIXタイムスタンプ |
smtp-id | システムに付与されるメッセージID |
ip | イベント発生元のIPアドレス |
tls | メール送信のTLS使用有無 |
cert_err | 受信タイミングでの認証エラー有無 |
公式テストデータのサンプル
{
"email"=>"example@test.com",
"timestamp"=>1607866697,
"smtp-id"=>"<14c5d75ce93.dfd.64b469@ismtpd-555>",
"event"=>"processed",
"category"=>["cat facts"],
"sg_event_id"=>"TW9yi7dcF1WJ-y3oTKkbaw==",
"sg_message_id"=>"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0"
}
Event Webhookのテスト
Webhookのテスト方法について
Sedgridの公式ブログでも紹介されている、webhook.site を使用し、まずはWebhookのテストを行います。
ステップ1
Webhook.site で受信用のユニークなURLが発行されるのでコピーして、
SendGrid UI画面からSettings > Mail Settings にアクセスし、Event Notificationをクリックします。
ステップ2
編集ボタンを押下し、先ほどのURLを貼り付け、Test Your Integrationをクリックします。
ステップ3
Webhook.site の画面にtestデータが返ってきていたら成功です!
テストデータの詳細は以下になります。
Event Webhook Reference
Event WebhookデータをDBに保存する(local環境)
実際にテストデータをDBに保存、表示してみる
上記でwebhookが動くことを確認したので、今度は実際にDBにデータを保存し、表示させるところまでテストしたいと思います。
以下、SendGridの公式ブログにngrokを使ってWebhookのテストの方法が書かれています。
以下のサンプルコートはSinatraになっているため、railsで実装していきます。
Sinatraとngrokを使ってWebhookのテストを楽にする方法
環境
今回試した環境は以下になります。
環境
- Ruby: 2.6.6
- Rails: 6.0.3
- MySQL: 5.7
- Docker
ステップ1
rails newでアプリを作成した後、ローカルサーバーを立ち上げている状態でngrokを使用しURLを発行します。
発行したURLを先ほどのSettings > Mail SettingsのURLに以下の形式でセットします。
※urlの/hooks以下はこれから作成するcontollerのメソッド名なので、特に指定はありません。
https://xxxxxxxxxx.ngrok.io/hooks/sendgrid_callback
この状態でTest Your Integrationを押下するとルーティングエラーは起きますがpostはされていることがわかります。
ステップ2
Webhookを受け取る用のコントローラーを作成し、routeを設定します。
下記contollerでcreate処理を実装する前にputs request_payload
で先ほどのテストデータが受け取れていることと受け取っている内容を確認します。
今回は「email, event, timestamp, category」の4つをDBに保存したいと思います。
app/controllers/hooks_controller.rb
class HooksController < ActionController::Base
skip_before_action :verify_authenticity_token
def sendgrid_callback
head :no_content #最初にレスポンスを返す
request.body.rewind
request_payload = JSON.parse(request.body.read)
# puts request_payload(データが受け取れていることを確認する)
request_payload.map { |item|
EmailEvent.create!(
email: item["email"],
event: item["event"],
datetime: Time.at(item["timestamp"]).to_datetime,
category: item["category"][0] #カテゴリーは複数選択できるが、今回は1つという想定で実装する
)
}
end
end
config/route.rb
scope "/hooks", :controller => :hooks do
post :sendgrid_callback
end
ステップ3
次に、受け取ったデータを保存・表示するためにscaffoldを行います。
rails g scaffold EmailEvent email:string event:string category:string datetime:datetime
ステップ4
再度Settings > Mail Settingsにアクセスし、Test Your Integrationを実行します。
すると、DBにデータが作成されました。
ステップ5
http://localhost:3000/email_events
にアクセスすると、先ほど登録したデータが表示されていることがわかります!
公式ライブラリ
公式ライブラリについて
実はSendGridが公式で便利なライブラリを出しており、その中にwebhookを扱うためのものがいくつかございます。
* EventKit by SendGrid – Event Webhookでイベントを受信して保存するサンプルアプリケーション
* gridhook / Lee Jarvis – Event WebhookからのインバウンドバッチをハンドリングするRuby Gem
* griddler / Thoughtbot – SendGridのParse APIのエンドポイントを提供するRailsエンジン
* Pokey by Chuck Callebs – QAおよび開発環境でイベントをシミュレートするRuby Gem
EventKitはデプロイすれば各イベントを独自のダッシュボードで確認できてとても便利そうなのですが、
railsのバージョンなどが古いため、各自でアップグレードして使用する必要がありそうです。
インストール方法はこちら
まとめ
本日はSendGridのEvent Webhookについて紹介しました。
自分がwebhookの開発をほぼしたことがなかったため、最初は難しそうな印象を持っていましたが思ったより簡単に実装することができました。
ただ、実際運用するにあたってセキュリティやパフォーマンス、サーバーへの負荷がどのくらいになるかなどまだまだ考慮しなくてはいけないことも多そうだと感じたので、引き続きベストな方法を調査していけたらと思いました!
最後まで読んでいただきありがとうございます。
Ruby on Railsのお仕事に関するご相談
Bageleeの運営会社、palanではRuby on Railsに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。
この記事は
参考になりましたか?
1
0
関連記事

2021年12月23日
RailsアプリにGoogle Mapから緯度経度情報を取得する機能を追加する

2021年12月22日
RDBでセットメニューを表現する方法

2021年12月11日
Railsでツリー構造アプリを作ってみた

2021年12月10日
Dockerで作成したRailsアプリケーションをHerokuにデプロイする

2021年12月9日
モデルに書いていたメソッドをPOROに切り出してみた!

2021年12月7日
gem cancancanを使ってみた!
簡単に自分で作れるWebAR
「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。
palanARへ
palanでは一緒に働く仲間を募集しています
正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。
運営メンバー

Eishi Saito 総務
SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。
sasakki デザイナー
アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

やまかわたかし デザイナー
フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。
Sayaka Osanai デザイナー
Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた エンジニア
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

こぼり ともろう エンジニア
サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

ささい エンジニア
フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。

Damien
WebAR/VRの企画・開発をやっています。森に住んでいます。

ゲスト bagelee

かっきー

まりな

suzuki
miyagi

ogawa
雑食デザイナー。UI/UXデザインやコーディング、時々フロントエンドやってます。最近はARも。

いわもと
デザイナーをしています。 好きな食べ物はラーメンです。

taishi kobari
フロントエンドの開発を主に担当してます。Blitz.js好きです。

kubota shogo
サーバーサイドエンジニア。Ruby on Railsを使った開発を行いつつ月500kmほど走っています!
nishi tomoya

aihara
グラフィックデザイナーから、フロントエンドエンジニアになりました。最近はWebAR/VRの開発や、Blender、Unityを触っています。モノづくりとワンコが好きです。
nagao
SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

Kainuma
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

sugimoto
asama
ando
iwasawa ayane

oshimo
異業界からやってきたデザイナー。 palanARのUIをメインに担当してます。 これからたくさん吸収していきます!