GoogleスプレッドシートのonEditイベントでUrlFetchAppを使用するとエラーが発生する理由と解決方法

Google

Googleスプレッドシートを使って管理アプリを作成していると、外部APIを呼び出してデータを取得する機能を追加したくなることがあります。通常、PCのChromeブラウザからは問題なく動作しますが、スマートフォンアプリからはボタンクリックができず、不便を感じていました。

そのため、スマートフォンからでも動作するように、セルの変更イベント(onEdit)を使ってボタンクリックの代わりにAPIを呼び出す方法を考えました。しかし、以下のエラーメッセージが表示され、うまく実行できませんでした。

Specified permissions are not sufficient to call UrlFetchApp.fetch. 
Required permissions: https://www.googleapis.com/auth/script.external_request

この記事では、この問題の原因と解決方法を、同じエラーで悩んでいる方々のために分かりやすくまとめました。

発生したエラーの内容

特定のセル(例えばA1)に値が入力されると、外部APIを呼び出すスクリプトを実行するようにしました。コードは次の通りです。

function onEdit(e) {
  const sheet = e.source.getActiveSheet();
  const range = e.range;

  // A1セルに入力された場合にスクリプトを実行
  if (sheet.getName() === 'test_sheet' && range.getA1Notation() === 'A1' && e.value) {
    try {
      // APIからデータを取得
      var response = UrlFetchApp.fetch("http://xxx.xxx.xxx.xxx/app");
      var data = JSON.parse(response.getContentText());

      ・・・

    } catch (error) {
      Browser.msgBox('エラーが発生しました: ' + error.message);
    }
    // 実行後にセルをクリア
    range.clearContent();
  }
}

 

実際に「A1」セルに値を入力すると、イベントは起動するものの、次のエラーメッセージが表示されます。

Specified permissions are not sufficient to call UrlFetchApp.fetch. 
Required permissions: https://www.googleapis.com/auth/script.external_request

このエラーは、外部APIの呼び出し権限が付与されているにもかかわらず発生します。

エラーの原因

このエラーが発生する原因は、GoogleスプレッドシートのonEditイベントからUrlFetchAppを呼び出す際に制限があるためです。

Google Apps Scriptの制限事項によると、シンプルトリガー(onEditなど)はユーザーに承認を求めずに自動的にトリガーされるため、いくつかの制限が適用されます。具体的には、onEditイベントからはAPIリクエストを実行できないという制約があります。

シンプル トリガーはユーザーに承認を求めることなく自動的にトリガーされるため、いくつかの制限が適用されます。

スクリプトの実行や API リクエストによってトリガーが実行されることはありません。
たとえば、Range.setValue() を呼び出してセルを編集しても、スプレッドシートの onEdit トリガーは実行されません。

解決方法

この問題を解決するためには、以下の2つの対応を行う必要があります。

  • カスタムトリガーを使用する(onEditイベントを使用しない)
  • 外部スクリプト呼び出しの許可設定を行う

onEditイベントではなくカスタムトリガーを使用する

onEditイベントをそのまま使用するのではなく、独自のカスタムトリガーを設定して、セルの変更を検出しAPIを呼び出す方法があります。

トリガーの設定手順

  • スプレッドシートの[拡張機能] – [Apps Script]メニューでApps Script画面を開きます。
  • 既存のonEditイベントを別名に変更します。(例:atEdit)
function atEdit(e) {
  const sheet = e.source.getActiveSheet();
  const range = e.range;

  // A1セルに入力された場合にスクリプトを実行
  if (sheet.getName() === 'test_sheet' && range.getA1Notation() === 'A1' && e.value) {
    try {
      // APIからデータを取得
      var response = UrlFetchApp.fetch("http://xxx.xxx.xxx.xxx/app");
      var data = JSON.parse(response.getContentText());

      ・・・

    } catch (error) {
      Browser.msgBox('エラーが発生しました: ' + error.message);
    }
    // 実行後にセルをクリア
    range.clearContent();
  }
}
  • 左メニューの[トリガー]をクリックし、トリガー画面を開きます。
  • 「トリガーを追加」ボタンをクリックし、次の設定を行います。
項目選択内容
実行する関数を選択atEdit
実行するデプロイを選択Head
イベントのソースを選択スプレッドシートから
イベントの種類を選択編集時

外部スクリプト呼び出しの許可設定を行う

appsscript.jsonに「https://www.googleapis.com/auth/script.external_request」を追加することで、外部APIを呼び出す権限を設定します。その後、手動で関数を実行して許可を設定します。

appsscript.jsonの表示手順

  • スプレッドシートの[拡張機能] – [Apps Script]メニューでApps Script画面を開きます。
  • 左メニューの[プロジェクトの設定](歯車アイコン)をクリックし、プロジェクト設定画面を開きます。
  • [全般設定]の「appsscript.jsonマニフェスト ファイルをエディタで表示する」にチェックを入れます。
  • 左メニューの[エディタ]にappsscript.jsonが表示されます。

appsscript.jsonの編集方法

以下のように、oauthScopesにhttps://www.googleapis.com/auth/script.external_requestを追加します。

{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/script.external_request"
  ]
}

関数を手動で実行し、許可設定を行う

  • スプレッドシートの[拡張機能] – [Apps Script]メニューでApps Script画面を開きます。
  • コードを開き、関数名(例:atEdit)を選択して、「実行」ボタンをクリックします。
  • 許可を求める画面が表示されるので、画面に従って許可します。
  • スクリプトが正常に実行されれば、外部APIの呼び出し権限が設定されます。

これで、スマートフォンからでもGoogleスプレッドシートを使って外部APIを呼び出すことができるようになります。

Google

Posted by snow