SendGridのEvent Webhookを使ってイベントをElasticsearchにPOSTする

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

昨日に引き続きSendGridネタです。

SendGridにはWebhookという、イベントが発生した際に指定したURLに対しPOSTしてくれる、プッシュ通知の仕組みが用意されています。Webhookには以下の2つの種類があります。

  • Event Webhook ... 開封やバウンス、配信停止などのイベント(アカウントコンソールの[Email Activity]画面で表示されるもの)が発生した際に、そのイベント内容をPOSTする。
  • Inbound Parse Webhook ... メールを受信した際に、メールの内容をPOSTする。

そこで今回はEvent Webhookの仕組みを使って、イベントをAmazon EC2上にセットアップしたElasticsearchにPOSTしてみました。SendGridにはイベントの検索画面も統計画面も用意されていますが、Elasticsearchに入れる事でオリジナルな解析を行うことが出来ます。

やったこと

Elasticsearchのセットアップ

OSはAmazon Linux AMI 2014.03です。現時点で最新のElasticsearchをセットアップしました。

$ wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.1.1.noarch.rpm
$ sudo rpm -ivh elasticsearch-1.1.1.noarch.rpm
$ sudo /sbin/chkconfig --add elasticsearch
$ sudo service elasticsearch start

また動作確認用にelasticsearch-headプラグインも入れてます。

$ sudo /usr/share/elasticsearch/bin/plugin -install mobz/elasticsearch-head

POSTデータのパーサーを作る

Event Webhookでは複数のイベントが1回のPOSTで渡ってくるため、最初にSinatraを使ったRubyスクリプトで受け取り、1件毎のイベントに分解して、ElasticsearchにPOSTするようにしました。

$ sudo gem install sinatra --no-ri --no-rdoc
$ vi postwrapper.rb

#!/usr/bin/ruby

require 'sinatra'
require 'json'

set :environment, :production
set :port, 10080

post '/', provides: :json do
  params = JSON.parse(request.body.read)

  params.each do |param|
    data = JSON.generate(param).to_s
    data.gsub!('"','\"')
    f = `/usr/bin/curl -XPOST http://localhost:9200/sendgrid/webhook/ -d "#{data}"`
    f.each_line { |line| 
      body << line
    }
  end
  body
end

$ ./postwrapper.rb

SendGridでWebhookを有効にする

Webhookを有効にするには、SendGridのアカウントコンソールから[Apps]-[Show Disabled Apps]-[Event Notification]をEnableにします。

wh01

すると[Event Notification]が[Show Enabled Apps]に移るので、そこで"Settings"を左クリックします。

wh02

[Event Notification]画面では、[HTTP Post URL]に上記で設定したRubyスクリプトが動いているEC2のIPアドレスとポート番号(今回のスクリプトでは10080/tcpを使っています)を指定します。また通知対象のイベントは全てを対象としました。

wh03

[Event Notification]画面の[Test Your Integration]ボタンを押すとPOSTのテストが実行出来ます。実際にボタンを押してみて、以下のように正常にPOSTが出来ることを確認しておきます。

wh04

POSTテストを実行し、elasticsearch-headの画面から状態を確認すると、ちゃんとイベントデータが登録されていますね!

wh05

実行してみる

では実際にメールを送信してみます。昨日の記事で使ったスクリプトを使ってメールを送信すると...ちゃんとWebhookからイベントが通知され、Elasticsearchにデータが登録されていることが分かります!

wh06

イベントデータの内容は以下のような形になります。

wh07

まとめ

今回はWebhookからElasticsearchへのデータ投入を行いましたが、例えばBounceやSpam Report、Unsubscribeなどのイベントをフックしたらメール送信システムのアドレスリストをクリーニングするなど、様々な用途が考えられると思います。こういった周辺機能が充実しているのは良いですね!