はじまり
はっ?
なんで、いつも通りスプレッドシートを開いて
onOpenでメニューが追加されないの!?
ああ〜、それは権限のエラーが出てるかもしれない・・・
権限?
じゃあ、今回はそのことについて触れてみよう
事象
今回、直面したエラーはこんな感じのものです。
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()
を実行することで、自作のメニューは追加されるようになりました。
おしまい
良かった・・・なんとかメニューが追加された・・・
機能ごとに必要な権限が違うとは思わなかったね・・・
知ったこっちゃない!
以上になります!
コメント