JavaScript
GoogleAppsScript
gas
GoogleSpreadSheet

[GAS] 実行する権限がありません。についての対策まとめ

More than 1 year has passed since last update.

Google Apps Scriptでシンプルトリガーを使用したときに実行できない関数がありますが、
それについて調べたことまとめです。
自分が使いたかったのは他のスプレッドシートを開く SpreadsheetApp.openById()

原因

onEditやonOpen等は記述するだけで実行されるシンプルトリガーという便利なものなんですけど、
これで実行された場合は権限が最低らしく、セキュリティで実行できる関数に制限があるとのこと。
なので onEditから他ファイルにアクセスする関数等は実行できない。

対策

プロジェクトのトリガー を設定する。

シンプルトリガーでは動かなくても個別設定したトリガーでは動作するので、登録しちゃおうということ。

編集→現在のプロジェクトのトリガー から登録すればOK
※ onEdit等シンプルトリガー名のままだと2回実行されるようになるので注意。

しかし、トリガーはスプレッドシートをコピーするといなくなるので、
毎日コピーして行う業務だったりのときに凄く手間です。
なので今回の対策として以下2つめ

トリガービルダーを使う

今のままだと、 スプレッドシートをコピーした際に、
スクリプトを開いて、トリガーを設定して……。なんて面倒臭いことをやらなければならず、
しかも誰にも使えるとは言えない状況なので、それの対策で、初期化処理を作ります。

Script Servicesにトリガービルダーがあるのでそれを使った初期化ボタンを作成。

Class SpreadsheetTriggerBuilder
Class Trigger

onEdit

//初期化処理
function init()
{
  Logger.log('init: START');

  //現在の設定されているトリガーを種痘
  triggers = ScriptApp.getProjectTriggers();

  for (var i = 0; i < triggers.length; i++) {
   if (triggers[i].getHandlerFunction() == 'actionOnEdit') {
     Logger.log('init: トリガー登録済');
     Browser.msgBox('初期化は既に実行されました。');
     return 0;
   }
  }

  Logger.log('init: run');
  var sheet = SpreadsheetApp.getActive();
  try{
    //トリガーの設定をスクリプトで
    ScriptApp.newTrigger('actionOnEdit')
    .forSpreadsheet(sheet)
    .onEdit()
    .create();
  }catch(e){
    Browser.msgBox('初期化に失敗しました。' + e);
  }

  Logger.log('init: End');
  Browser.msgBox('初期化が完了しました。');
}

//onEditで実行したい処理
function actionOnEdit()
{
  var spreadsheet = SpreadsheetApp.openById({ID});
  ...
}

あとはスプレッドシート上に 図形を描画→スクリプトの割当をして、最初に使うときに押してもらえばOK
一手間いるけど、許容範囲だと思う。

もう少し調べればonEdit()とかからスクリプト内で認証を経由して実行できるようにとかできるのかもしれないけど、
見つからなかったので今のところこれが一番手間いらずかな。

参考

[GAS]実行に失敗: その操作を実行する権限がありません。に悩んだこと
GAS 「実行する権限がありません」にハマりました