ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [구글 앱스 스크립트 기본 9] 설치 가능한 트리거를 이용해 정해진 시간에 스크립트 (함수) 실행시키기
    구글 시트&앱스스크립트&루커스튜디오/구글 앱스 스크립트 2023. 8. 17. 19:30

     

     

     

     

    글의 순서 

    더보기
    • 설치 가능한 트리거
    • 시간 기반 트리거를 이용해 정해진 시간에 스크립트(함수) 실행시키기

     

     

    설치 가능한 트리거

    구글이 지원하는 트리거 기능 중 간단한 트리거 외에도 설치 가능한 트리거도 있습니다. 설치가능한 트리거는 이름처럼 직접 사용자가 구글 앱스 스크립트 에디터에서 설치를 하거나, 트리거를 설치하는 코드를 앱스 스크립트에 삽입하여 실행할 수 있는 트리거입니다. 간단하게 미리 지정된 함수 이름으로 트리거를 호출할 수 있는 간단한 트리거는 간단한 만큼 많은 제약사항이 존재합니다. 하지만 설치 가능한 트리거는 몇 가지 제약사항이 있기는 하지만, 간단한 트리거와 비교해 보면 훨씬 더 유연하게 사용할 수 있습니다. 예를 들어, 접근 권한이 필요한 서비스들(예를 들면 스프레드시트 서비스 등)을 사용할 수 없는 간단한 트리거와는 달리, 설치 가능한 트리거는 이런 권한이 필요한 서비스들을 실행하는데도 사용할 수 있습니다. 

     

    설치가능한 트리거에는 두 종류의 트리거가 있습니다. 하나는 시간 기반 트리거이고, 다른 하나는 이벤트 기반 트리거입니다. 시간 기반 트리거는 일정 시간 간격으로 스크립트를 실행할 수 있게 해주는 트리거로, 가장 짧은 주기는 1 분마다이고, 가장 긴 주기는 1 달마다입니다. 단, 시간 기반 트리거는 주기는 설정할 수 있지만 정확히 언제 스크립트를 실행시키는지는 지정할 수 없습니다. 예를 들어, 매 1시간마다 스크립트가 실행되도록 시간 기반 트리거를 설정할 수는 있지만, 1시간 중 정확히 몇 분에 스크립트가 실행될지는 지정할 수 없습니다. 하지만, 만약 23분에 스크립트가 처음으로 실행되었다면 그다음부터는 매 시 23분에 스크립트가 실행됩니다. 이벤트 기반 트리거에는 여러 가지 종류가 있습니다. 파일을 열 때 실행되는 Open(열기) 트리거, 값이 수정될 때 실행되는 edit(수정) 트리거처럼 간단한 트리거에서 제공되는 것과 거의 비슷한 기능의 트리거와 더불어 구글 시트 파일에 새로운 시트를 추가한다던지 하는 파일의 구조가 변경될 때 실행되는 change(변경) 트리거, 구글 시트 파일에 연동된 구글 폼에서 답변이 제출될 때 실행되는 form submit(양식 제출) 트리거, 사용자의 캘린더 이벤트가 생성/변경/삭제/실행될 때 실행되는 calendar event(캘린더 이벤트) 트리거 등 설치 가능한 트리거에서만 사용할 수 있는 기능들도 있습니다. 설치 가능한 트리거에 대한 자세한 사항은 구글 앱스 스크립트 레퍼런스 파일을 참고하시는 걸 추천합니다. 

     

    이 글에서는 설치 가능한 트리거에서도 시간 기반 트리거를 사용하는 방법에 대해서 알아보겠습니다. 

     

     

    시간 기반 트리거를 이용해 정해진 시간에 스크립트(함수) 실행시키기

    가장 먼저 시간 기반 트리거에 할당할 스크립트를 작성해 보도록 하겠습니다. 오늘 작성해 볼 샘플 스크립트는 "A1" 셀의 값을 "C1"셀로 옮기는 스크립트입니다. "A1"셀의 값은 지금 날짜와 시간을 반환하는 구글 시트 함수인 NOW() 함수를 이용해 지금의 날짜와 시간을 넣도록 하겠습니다. 참고로 getValue 메서드는 특정 범위에 있는 함수를 가져오는 것이 아닌 그 함수의 실행 결과인 값을 가져옵니다. 따라서 NOW() 함수의 값은 계속 바뀌기 때문에 "A1"셀의 값은 계속 바뀌겠지만 그 값을 가져와 setValue 메서드를 통해 "C1"셀에 입력하게 되면 NOW() 함수 대신 그 스크립트가 실행된 시간에 보이던 값이 들어가게 됩니다. 예제 스크립트는 다음과 같습니다.

    function myFunction() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A1");
      var val = range1.getValue();
      var range2 = sheet.getRange("C1");
      range2.setValue(val)
    }

     

    앱스 스크립트에 구글 시트 파일에 대한 접근권한을 부여한 후 스크립트를 실행시켜 보면 "C1"셀에 NOW() 함수 대신 스크립트가 실행되던 때에 "A1"셀에 있던 날짜와 시간이 들어가 있습니다. 이 A1 셀을 보다 보면 한 가지 이상한 점을 발견할 수 있는데, 이 NOW() 함수가 현재 시간과 날짜를 표시해 주는 함수임에도, 시계 초침이 매초 움직이는 것처럼 시간이 계속 바뀌지 않는다는 점입니다. 이는 구글 시트 파일의 기본 설정은 이 NOW()를 구글 시트에 셀의 값을 변경하거나 하는 change(변경) 이벤트가 발생할 때 새로고침 하는 것으로 되어 있기 때문입니다. 이를 구글 시트 파일의 설정에 들어가 NOW() 함수뿐만 아니라 TODAY, RAND, RANDBETWEEN  함수의 새로고침 주기를 1분으로 변경해 주면 매분마다 "A1" 셀의 값을 바뀌는 것을 볼 수 있습니다.

     

     

    이제 이 myFunction 스크립트에 시간 기반 트리거를 설정해 매 1분마다 스크립트가 실행되도록 해보겠습니다. 먼저 구글 앱스 스크립트 에디터에 들어가 좌측의 메뉴에서 Triggers (트리거) 아이콘을 클릭합니다.

     

     

    Triggers (트리거) 아이콘을 누르면 설치되어 있는 트리거 목록이 나옵니다. 이 스크립트에는 트리거가 하나도 설치되어 있지 않기 때문에 어떤 트리거도 보이지 않습니다. 우측 하단에 있는 + Add Trigger 버튼을 눌러 트리거를 만드는 창을 실행합니다.

     

     

    트리거 추가 창은 왼쪽 부분과 오른쪽 부분으로 나뉩니다. 왼쪽 부분은 트리거를 설치하는데 필요한 옵션을 설정할 수 있고, 오른쪽 부분은 트리거 실행이 실패했을 때 구글 앱스 스크립트가 이메일로 알림을 주게 되는데, 이 알림 주기를 설정할 수 있는 창입니다. 왼쪽의 메뉴의 가장 위에서 우리가 실행할 스크립트인 myFunction을 선택합니다. 우리는 매분마다 실행되는 시간 기반 트리거를 설정하려고 하기 때문에 세 번째 옵션에서 기본으로 설정되어 있는 From spreadsheet에서 Time-driven으로 설정을 바꾸어 줍니다. 그 후에 Minutes timer 타입을 설정해 주고 마지막으로 Every minute으로 주기를 설정해 준 후 Save(저장) 버튼을 누르시면 됩니다.

     

     

    저장 버튼을 누르시게 되면 다시 한번 권한요청 팝업이 뜨게 됩니다. 트리거 없이 스크립트를 실행하는 경우에는 유저의 감독하에 스크립트를 실행하는 것이지만, 트리거를 설정해 스크립트를 실행하는 경우는 유저의 감독 없이 스크립트를 실행하기에 이와 관련된 권한을 부여해 주어야 하기 때문입니다. 

     

     

    권한 부여까지 완료하면 아까는 아무것도 없던 Triggers (트리거) 창에 새로운 트리거가 추가된 것을 볼 수 있습니다. 

     

     

    우리가 설정한 트리거는 매분 실행되기 때문에 1분 정도를 기다리면 첫 트리거가 발동되며 myFunction 스크립트가 실행됩니다. 스크립트의 실행 결과는 물론 구글 시트의 값이 변경된 것으로도 확인할 수 있겠지만, 구글 앱스 스크립트 에디터의 Executions (실행) 탭에서도 확인할 수 있습니다.

     

     

    실행 탭에서 확인할 수 있는 것처럼, 트리거를 설정한 이후 벌써 트리거가 세 번 발동해 스크립트가 세 번 실행된 것을 볼 수 있습니다. 위의 설치 가능한 트리거에서 언급했던 것처럼 우리는 매분 스크립트가 실행되도록 설정했지만 정확히 언제 실행되는지는 설정하지 않았기에 첫 트리거는 우리가 설정한 주기 이내에 무작위로 실행되게 됩니다. 아래의 이미지에서는 첫 스크립트가 55초에 실행된 것을 볼 수 있습니다. 그리고 그 이후부터는 1분 주기인 매 55초마다 스크립트가 실행된 것을 볼 수 있습니다. 간혹 여러 이유로 이 간격이 잠시 어긋날 수는 있지만, 아주 높은 확률로 이 주기는 일관되게 유지됩니다.

     

     

    이렇게 수동으로 직접 설치할 수도 있지만, 스크립트를 작성해 설치 가능한 트리거를 작성할 수도 있습니다. 이를 가능하게 해주는 구글 앱스 스크립트의 서비스는 Script Service (스크립트 서비스)입니다. 이 스크립트 서비스의 클래스 ScriptAppnewTrigger 메서드는 새로운 설치가능한 트리거를 설치합니다. 아까 우리가 만들었던 매분마다 실행되는 시간 기반 트리거를 작성하는 코드는 아래와 같습니다.

    function createTimeDrivenTriggers() {
      ScriptApp.newTrigger('myFunction')
          .timeBased()
          .everyMinutes(1)
          .create();
    }

     

    스크립트로 설치가능한 트리거를 설치하기 위해서는 newTrigger 메서드를 호출한 후  클래스 TriggerBuilder의 메서드들을 활용해 트리거를 설정한 후 클래스 FormTriggerBuilder의 메서드 create를 통해 새로운 트리거를 반환하는 방식입니다. 마치 이전 글에서 다루었던 맞춤 메뉴 항목을 만드는 것과 비슷한 원리입니다. 하지만 특별한 경우를 제외하고 스크립트로 설치 가능한 트리거를 작성하는 것을 추천하지는 않습니다. 첫째로, 스크립트를 통해 설치가능한 트리거를 설치하더라도 결국 앱스 스크립트 에디터의 Triggers(트리거) 항목에 추가됩니다. 즉, 설치하는 방법이 다를 뿐 결과는 동일하기에 대부분의 경우 굳이 스크립트로 설치 가능한 트리거를 설치할 필요는 없습니다. 둘째로, 스크립트로 설치 가능한 트리거를 설치하고 관리하는 경우 스크립트로는 이미 설치된 설치 가능한 트리거를 수정할 수 없습니다. 이 경우 기존 트리거를 삭제하고 새로 설치하는 방식으로 트리거를 수정해야 하는데 꽤 번거로운 작업입니다. 그래도 스크립트로 설치 가능한 트리거를 설치해보고 싶으시다면 한번 위의 코드를 이용해 트리거를 설치해 보시길 바랍니다. 위의 코드를 작성 후, 꼭 스크립트 에디터에서 createTimeDrivenTriggers 함수를 실행시켜야 트리거가 설치됩니다. 설치 후 Triggers(트리거) 항목에 가보면 트리거가 설치된 것을 볼 수 있습니다. 

    댓글

ⓒ 2018. Haedie's all rights reserved.