대량 or 동시에 도착하는 Webhook을 서버리스로 간편하게 확인

먼저 정리


  • 흘려도 좋기 때문에 간편하게 확인한다
  • htps : // 우ぇb 호오 k. 해 /

  • 일제히 오지 않지만 대량으로 닿는다.
  • GoogleAppScript

  • 확실히 간편하게 확인하기
  • Firebase Realtime Database

  • 미확인이지만 간편할지도
  • ngrok


  • 필요



    통지 용도로 대량으로 통지되는 Webhook가 public인 네트워크를 통해 누출 없이 도착하는지, 내용이 문제가 없는지, 확인할 필요가 있었다.
    다만, 일일이 서버 세워・・・라고 하는 것은 귀찮아서 서버리스로 할 수 없을지도 검토했다.

    받는 Webhook 내용



    아래와 같은 body가 통지된다고 한다.{ "foo": "aaaa", "bar": 1111, "maybeFoo": "AAAA" }{ "foo": "bbbb", "bar": 2222, "maybeBar": "BBBB" }maybeFoo와 maybeBar는 Optional.

    웹 뺨 k. 하고



    간단하고 간단합니다.
    URL에 액세스하는 것만으로 Webhook 수신을 위한 URL이 발행되어 통지의 내용을 표시하는 Viewer 첨부.
    다만, 잠시 사용하고 있으면 통지가 닿지 않게 되거나, 동시에 받은 Webhook를 쏟아내는 일이 있기 때문에, 누설 없이 도착할지 어떨지의 확인에는 사용할 수 없었다.

    GoogleAppScript



    Webhook은 단순한 POST 요청이므로, 어쩌면 GAS라면 흘리지 않고 갈 수 있을지도.
    게다가 스프레드시트와 연계하고 있고, 데이터 정리도 하기 쉬울지도.
    라고 생각 도전.

    간단한 POST 요청 수신



    먼저 단순히 POST 요청을 받고 Json을 parse하고 해당 값을 시트에 저장한다.

    simpleWebhookLog.gs
    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() 를 조금 간략화해 아래와 같이 해 보았다.

    asyncWebhookLog.gs
    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にする
    이것으로 Webhook를 보내면・・・. 할 수 있었다! !


    대량 송신 and 동시 송신에서도 견딜 수 있으므로, 문제 없음!
    주의하는 것은, 너무 사용하면 요금이 걸려 버릴 것 같기 때문에, 테스트가 끝나면 Webhook의 통지처를 바꾸거나, 정기적으로 데이터를 삭제하거나 해 둔다.

    계속



    Elm에서 View를 작성해 보았습니다.



    어쩌면 방법으로 낡을 가능성이 있는 것과 시크릿을 사용하고 있으므로 보안적으로 주의하는 편이 좋을지도.

    좋은 웹페이지 즐겨찾기