【Google Apps Script】onOpen時に「Spreadsheet.openByIdを呼び出す権限がありません」となり、メニューが追加されない
はじまり




事象
今回、直面したエラーはこんな感じのものです。
HtmlService()を使って、スプレッドシートを開いた時にメニューが表示されるかと思いきや、全く表示されてこない・・・

スクリプト編集画面で、こんな感じにGoogle Workspaceのサービスを叩いてみてもダメ・・・。
function authGoogleWorkspace(){ let ss = SpreadsheetApp.getActiveSheet(); let drive = DriveApp.getRootFolder(); let fetch = UrlFetchApp.fetch("https://www.google.com/?hl=ja");}原因
本当に意味がわからない!! そう悩んでいた時にこの記事を発見。

どうやら、onOpenやonEditなどの自動実行トリガーは権限が最低らしい。士農工商で言ったら、えた・ひにんだ。
なので、少し強い権限が必要な機能を利用するためには、onOpenではないトリガーからスクリプトを実行しなければならないっぽい。

まあ、僕が初めてこの事象と遭遇したのは、onOpenで使用するアプリ上でSpreadsheetApp.openById()を使ったからなのですが、onOpenで実際に実行される処理内でSpreadsheetApp.openById()が実行されているかどうかは関係なさそう。
僕の場合は、SpreadsheetApp.openById()がonOpenと関係ない関数に入っているだけでちゃんと動きませんでした。
なので、SpreadsheetApp.openById()を使うアプリでは、onOpenはトリガーを作成する処理だけを入れようと思ったわけです。
調査
僕は、onOpen関数に以下のような処理を入れました。
onOpenでエラーになるので、そしたらonEditイベントハンドラを追加。そのonEditイベントでイベントハンドラを削除。(まあ、onEditもSimple Triggerなので権限弱そうだけど・・・)
function onOpen(){ try{ let ui = SpreadsheetApp.getUi(); const statement = ui.prompt(message).getResponseText();
let menuName = "フォルダ作成処理"; let objActions = [ {name: "作業ページ一覧表示処理", functionName: "displayListOfPagesToWork"} , {name: "Display Thumbnails.", functionName: "displayThumbnails"} ];
// これがメニューを追加する関数。 onOpenToAddSpreadsheetMenu(menuName, objActions);
}catch(e){ SpreadsheetApp.getUi().alert("onOpen failed. " + e); // Browser.msgBox("onOpen failed. " + e); createTrigger(); }}
function createTrigger(){ let sheet = SpreadsheetApp.getActiveSpreadsheet(); try{ ScriptApp.newTrigger("doOnOpen") .forSpreadsheet(sheet) .onEdit() .create(); }catch(e){ SpreadsheetApp.getUi().alert("Initialization failed. " + e); }}
function doOnOpen(){ onOpen(); let triggers = ScriptApp.getProjectTriggers(); for(let i = 0; i < triggers.length; i++){ if(triggers[i].getEventType() === ScriptApp.EventType.ON_EDIT){ ScriptApp.deleteTrigger(triggers[i]); } }}そして、結果的には失敗。
トリガーは追加されていませんでした。

次に、まずスクリプトが実行されているかどうかを検証。 スクリプトが走るなら、スプレッドシートを開いた時にダイアログが表示されるはず。
function onOpen(){ try{ // この2行を追加。 let ui = SpreadsheetApp.getUi(); const statement = ui.prompt(message).getResponseText();
let menuName = "フォルダ作成処理"; let objActions = [ {name: "作業ページ一覧表示処理", functionName: "displayListOfPagesToWork"} , {name: "Display Thumbnails.", functionName: "displayThumbnails"} ]; onOpenToAddSpreadsheetMenu(menuName, objActions); }catch(e){ SpreadsheetApp.getUi().alert("onOpen failed. " + e); createTrigger(); }}実行してみると、ダイアログは表示されませんでした・・・
僕が遭遇しているSpreadsheetApp.openById()の権限エラーは、自作の別ライブラリにある処理で引っかかっているようなので、そこの静的解析中にエラーになっているのかもしれない。
一応、解決
なので、スクリプト自体が実行されていないとなると、
- アプリのコンソール画面内でトリガー設定をするか
- スプレッドシートの中にスクリプトを実行するボタンを作るか
この2つしか方法はなさそうだったので、後者のボタンを設置する方法にしました。
やむを得ませんでした・・・無念・・・(まあ、こんな不具合に何時間も使ってられません。)

onOpen関数をinitialize関数に名前を変更して、ボタンに割り当てました。
initialize()を実行することで、自作のメニューは追加されるようになりました。
おしまい



以上になります!
記事を共有
この記事が役に立ったなら、ぜひ他の人と共有してください!