jqコマンドでEvent Webhookのデータを抽出する
- 2020年10月23日
- by 菊田 洋一
- Category: 技術ネタ
SendGridのテクニカルサポートを担当している菊田(@kikutaro_)です。メールの送信ログを確認するとき、Event Webhookのイベントデータをみることがあると思いますが、皆さんはどうやって欲しいデータを抽出していますか?データベースに格納している場合はクエリが使えますが、ファイルの場合はどうでしょうか?
私は「jqコマンド」を使用しています。簡単に使える便利なツールなので、本日のブログでは私がよく使っているコマンドをご紹介します。
jqコマンドとは?
JSONのデータを操作するコマンドを集めたツールです。今回はブラウザ上でjqコマンドを試せる「jqplay」を使って紹介します。
https://jqplay.org/
使い方は簡単です。画面左下のパネルにJSONデータを入力して、その上のFilterにコマンドを書くと、画面右側に結果が表示されます。
jqplayで試したコマンドを手元のCUIで動かしたい方は画面中段の「Command Line」に表示された内容を実行してください。
まずは簡単な例として次のようなJSONデータを試してみましょう。
{ "name": "構造太郎","age": 30 }
JSONの欄にデータを入力したら、Filterに「.」(ドット)と入力してください。下図のように整形されたJSONがResultに表示されたらOKです。
「.」はIdentityと呼ばれるコマンドで、入力されたJSONデータをそのまま出力します。出力結果は上記のように改行やインデントが整形された形で表示されます。
続いて、Filterに「.name」と入力します。このように属性名を指定することで該当する値を取得できます。
今回のブログでは1つ1つのコマンドは解説しませんが、様々なものがあるのでドキュメントを参考に色々お試しください。
Event Webhookのデータ
SendGridのEvent Webhookでは配列形式で複数のイベントデータが送られてきます。今回は以下のJSONデータを例にします。
[{"email":"delivered@example.com","timestamp":1602644706,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"processed","category":["cat facts"],"sg_event_id":"W1IOUjqc58Fd65GY07YyXw==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0"}, {"email":"delivered@example.com","timestamp":1602644706,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"deferred","category":["cat facts"],"sg_event_id":"-lJEJFkhp3YNG55w2s98-w==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","response":"400 try again later","attempt":"5"}, {"email":"delivered@example.com","timestamp":1602644706,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"delivered","category":["cat facts"],"sg_event_id":"VFgu-PlnL_W3C2TUah6ilQ==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","response":"250 OK"}, {"email":"delivered@example.com","timestamp":1602644706,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"open","category":["cat facts"],"sg_event_id":"p1q0LNze5nuGZiJpf-MvjA==","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"}, {"email":"delivered@example.com","timestamp":1602644706,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"click","category":["cat facts"],"sg_event_id":"LRXv_i1kO25tvbEpCNtT_A==","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","url":"http://www.sendgrid.com/"}, {"email":"bounce@example.com","timestamp":1602651074,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"processed","category":["cat facts"],"sg_event_id":"W1IOUjqc58Fd65GY07YyXw==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0"}, {"email":"bounce@example.com","timestamp":1602651074,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"bounce","category":["cat facts"],"sg_event_id":"iNytgwmkdQ8VHxxUd7emeg==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","reason":"500 unknown recipient","status":"5.0.0"}]
イベントデータの操作方法
特定のメールアドレスのイベントを抽出する
一番よく使うのは該当するメールアドレスのイベント抽出です。
.[] | select(.email == "bounce@example.com")
Filterに上記を入力すると、該当する2件が表示されます。
コマンドの内容は次のとおりです。
- Event Webhookのデータは配列で括られているため、.[] で配列を取り除く
- パイプ(|)でコマンドをつなぐ
- selectを使って条件を満たすデータのみ抽出する
selectの条件はANDやORでつなげることができます。イベントが「bounce」のものをさらに抽出するには次のコマンドを入力します。
.[] | select(.email == "bounce@example.com" and .event == "bounce")
件数をカウントする
lengthを利用して、フィルタした結果の件数を数えます。
[.[] | select(.email == "bounce@example.com")] | length
時刻でソートする
時刻でソートする場合はsort_byを利用します。
昇順の場合
sort_by(.timestamp)
降順の場合
sort_by(.timestamp) | reverse
selectした結果を降順にする場合は次のように書きます。
[.[] | select(.email == "bounce@example.com")] | sort_by(.timestamp) | reverse
時刻をみやすくする
イベントデータの時刻はUNIXTIMEで表示されるため、strftimeでフォーマットするとわかりやすくなります。
.[] | .timestamp = (.timestamp | strftime("%Y-%m-%d %H:%M:%S"))
今回はデータの抽出をメインに書きましたが、抽出後の結果をさらに整形して出力することも可能なので、ぜひ色々とお試しください。