GoogleスプレッドシートのonEditイベントでUrlFetchAppを使用するとエラーが発生する理由と解決方法
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を呼び出すことができるようになります。