서비스
home

onOpen & 사용자함수의 권한 오류 원인

목적

onOpen 함수와 사용자 함수(Custom Function)을 사용할 때 권한 오류가 나는 원인을 살펴보고, 권한 오류를 발생시키지 않는 방법을 알아봅니다.

현상) 권한 오류

onOpen와 같은 Simple Trigger 함수를 사용해서 시트가 열릴 때 추가 메뉴를 생성하는 경우, 또는 사용자 함수 (Custom Function)을 사용하는 경우, 아래와 같이 권한 오류가 발생할 때가 있습니다.
Exception: DriveApp.getFolderById을() 호출할 수 없습니다. 다음 권한이 필요합니다. (https://www.googleapis.com/auth/drive.readonly || https://www.googleapis.com/auth/drive) at [unknown function]
JavaScript
복사
직접 스크립트를 실행해보면 권한 오류없이 정상 실행이 되곤해서, 무엇이 문제인지 확실히 알지 못할 때가 있습니다.
이와 같은 경우에 구글링을 하다보면 OAuth Scope를 설정해야 한다는 조언이 있는데, 해결책이 되지 못할 때가 있습니다. (또는 @NotOnlyCurrentDoc 를 사용하라는 조언도 찾을 수 있습니다.)
왜 문제가 해결되지 않을까요?

원인) 구글의 제약사항

원인은 구글에서 Simple Trigger와 사용자 함수에 제약사항을 두고 있기 때문입니다.
아래의 링크를 클릭해서 Simple Trigger의 제약사항들을 보실 수 있습니다.
제약 사항 목록 중, 해당 사항이 있는 것은 이 부분 입니다.
They cannot access services that require authorization. For example, a simple trigger cannot send an email because the Gmail service requires authorization, but a simple trigger can translate a phrase with the Language service, which is anonymous. (Simple Trigger 는 권한 확인 없이 자동으로 실행되기 때문에 권한 확인이 필요한 서비스를 이용할 수 없다는 내용)
사용자 함수의 경우에도 사용할 수 있는 서비스에 제약이 있는데, 구글에서 친절하게 알려주고 있습니다.
Unlike most other types of Apps Scripts, custom functions never ask users to authorize access to personal data. Consequently, they can only call services that do not have access to personal data, specifically the following:
If your custom function throws the error message You do not have permission to call X service., the service requires user authorization and thus cannot be used in a custom function.
(사용자 함수도 권한 요청을 하지 않기 때문에 개인정보가 관련된 권한 요청하는 함수는 실행할 수 없다는 내용)
예를 들어, MailApp 의 이메일 보내기 잔여 할당량을 보는 클래스를 사용자 함수로 만들어서 구글 시트에서 실행시키려고 하면, 오류가 나는 것을 확인할 수 있습니다.

해결책) 권한이 필요한 경우에는 사용자가 스크립트를 실행하게 만드세요.

스크립트를 위한 기본 변수들을 함수 { } 밖에 입력해두면 Global 하게 사용할 수 있는 장점이 있습니다.
하지만 onOpen 이 실행되는 경우, 이러한 Global 변수의 권한을 체크하게 되고, 오류를 발생시킵니다. 물론 오류가 나면, onOpen 은 성공적으로 실행되지 않습니다.
때문에 문제의 간단한 해결책은 Global 변수 중 getFolderById 와 같은 권한을 요청하는 클래스는 함수의 안으로 넣어야 합니다. 그렇지만, 그럼 코드를 중복으로 작성해야하는 문제가 생깁니다.
때문에, Installable Trigger를 사용하는 편이 낫습니다. Simple Trigger 와는 달리 권한을 좀 더 사용할 수 있습니다.
Installable triggers, however, offer more flexibility than simple triggers: they can call services that require authorization
트리거 추가에 수동으로 추가해보면 동일한 onOpen 함수가 오류없이 실행되는 것을 확인할 수 있습니다.

관련 포스팅