大量 or 同時に届くWebhookをサーバーレスで手軽に確認する
最初にまとめ
- 取りこぼしてもよいので手軽に確認する
- 一斉にこないが大量に届く
- GoogleAppScript
- 確実に手軽に確認する
- Firebase Realtime Database
- 未確認だけど手軽かも
- ngrok
ニーズ
- GoogleAppScript
- Firebase Realtime Database
- ngrok
通知用途で大量に通知されるWebhookがpublicなネットワークを通って漏れなく届くか、内容が問題ないか、確認する必要があった。
ただ、いちいちサーバー立てて・・・というのはめんどくさいのでサーバーレスでできないかも検討した。
受け取るWebhookの内容
下記のようなbodyが通知されるとする。
{ "foo": "aaaa", "bar": 1111, "maybeFoo": "AAAA" }
{ "foo": "bbbb", "bar": 2222, "maybeBar": "BBBB" }
maybeFooとmaybeBarはOptional。
webhook.site
お手軽簡単。
URLにアクセスするだけでWebhook受け取りのためのURLが発行され、通知の内容を表示するViewer付き。
ただし、しばらく使ってると通知が届かなくなったり、同時に受け取ったWebhookを取りこぼすことがあるので、漏れなく届くかどうかの確認には使えなかった。
GoogleAppScript
Webhookは単なるPOSTリクエストなので、もしかしたらGASであれば取りこぼし無くいけるかも。
しかも、スプレッドシートと連携してるし、データ整理もしやすいかも。
と思いチャレンジ。
単純なPOSTリクエストの受け取り
まずは単純にPOSTリクエストを受け取って、Jsonをparseして、該当の値をシートに保存する。
function doPost(e) {
if (e == null || e.postData == null || e.postData.contents == null) {
return;
}
doSomething(e.postData.contents);
return "OK";
}
function doSomething(contents) {
var reqBody = JSON.parse(contents);
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var values = [];
for (i in headers) {
var header = headers[i];
var val = "";
switch(header) {
case "Date":
val = new Date();
break;
case "foo":
val = reqBody["foo"];
break;
case "bar":
val = reqBody["bar"];
break;
case "maybeFoo":
if (reqBody["maybeFoo"] != undefined) {
val = reqBody["maybeFoo"];
}
break;
case "maybeBar":
if (reqBody["maybeBar"] != undefined) {
val = reqBody["maybeBar"];
}
break;
}
values.push(val);
}
sheet.appendRow(values);
}
結果としては、ほどほどに受け取れたが、やはり大量に同時に送ると取りこぼしが発生する。
非同期でキャッシュしながら受け取る
下記記事を見つけたので、そのままパクらせていただきました。
Webhookで起動したGAS(Google AppsScript)の応答を非同期処理で高速化する
doSomething(a)
の代わりに、addJobQueue(a)
を呼び出して、
addJobQueue(a, b)
とtimeDrivenFunction()
を少し簡略化して下記のようにしてみた。
function addJobQueue(contents) {
cache = CacheService.getScriptCache();
var data = cache.get("key");
if (data == null) {
data = [];
} else {
data = data.split(';');
}
data.push(contents);
cache.put("key", data.join(';'), 60*5);
return;
}
function timeDrivenFunction() {
cache = CacheService.getScriptCache();
var data = cache.get("key");
cache.remove("key");
if (data == null) {
return;
} else {
data = data.split(';');
}
for (var i = 0; i < data.length; i++) {
doSomething(data[i]);
}
return;
}
これを非同期実行して、テスト!
結果としては、先程よりも漏れなく受け取れるようになったが、やはり受け取り漏れが発生した。
これがGASの限界か・・・!!!
ngrok
手段を探しているうちにngrokを見つけたが、セキュリティ的に社内から使うのが少し怖かったので却下。
Firebase Realtime Database
またまた調べているうちに、どうやらRealtime Databaseは直接RESTを叩くことで、リクエスト内容を直接保存することができるらしい。
ということで下記を参考にチャレンジ!1
Firebase Realtime Database を Rest API と Golang でいじってみる
Firebaseコンソールから新しいプロジェクトを作って、Database -> Realtime Database
からRESTのエンドポイントとなるURLをコピー。
ここからリクエスト用URLを作成。例えばこんな感じ。
https://test-app-75f30.firebaseio.com/message.json?auth=ここをsecretにする
大量送信 and 同時送信でも耐えうるので、問題なし!
気をつけることは、使いすぎると料金がかかってしまいそうなので、テストが終わったらWebhookの通知先を変えたり、定期的にデータを削除したりしておく。
続き
-
もしかしたら方法として古い可能性があることと、シークレットを使ってるのでセキュリティ的に注意したほうがいいかも。 ↩
Author And Source
この問題について(大量 or 同時に届くWebhookをサーバーレスで手軽に確認する), 我々は、より多くの情報をここで見つけました https://qiita.com/niso1985/items/356a8aee5496aea37975著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .