GAS『DriveApp cannot be used in this context』の原因と対処法
- 作成日 2025.11.04
- その他
DriveAppが許可されない実行文脈(カスタム関数、シンプルトリガー、クライアント側JS、未認可の実行主体など)でDrive操作を呼んだときに発生。実行“入口”を見直し、インストール型トリガーやサーバ側関数へ寄せ、適切なスコープと実行主体で再デプロイするのが基本方針。
- 1. エラーの意味と発生条件(まず押さえる)
- 2. 最短の切り分け(実行文脈を確定する)
- 3. カスタム関数ではDriveAppを使わない(設計の分離)
- 4. サンプル:I/Oをインストール型トリガーへ移す
- 5. シンプルトリガー→インストール型トリガーに置換
- 6. クライアント側からはgoogle.script.runでサーバへ委譲
- 7. ウェブアプリ/実行API:実行主体・スコープ・再デプロイ
- 8. 共有ドライブ/権限のすれ違いを点検
- 9. 外部フロントからの直叩き禁止(CORS/認可の壁)
- 10. アドオン/組織ポリシーの制約とマニフェスト
- 11. NG→OK早見表(クイック修正)
- 12. チェックリスト(導入順)
エラーの意味と発生条件(まず押さえる)
・セルのカスタム関数(=MYFUNC())は認可が必要なサービスを禁止
・シンプルトリガー(onOpen/onEdit/onInstall 等)は権限制限下で実行
・HtmlServiceのクライアントJSや外部ページからDriveAppを直接呼べない
・ウェブアプリ/実行API/アドオンでも、実行主体やスコープ不備で失敗
・共有ドライブ権限・所有者変更・ゴミ箱など周辺条件の取り違えも誘因
最短の切り分け(実行文脈を確定する)
・どこから呼んだか:セル/トリガー/ボタン/ウェブアプリ/外部HTTP
・誰の権限で走っているか:Session.getEffectiveUserで確認
・デプロイの種類とバージョン:最新バージョンか、実行主体は適切か
カスタム関数ではDriveAppを使わない(設計の分離)
・取得・作成などのI/Oはボタン/メニュー/定期実行に移し、結果だけをシートへ反映
・セルは“表示専用”、I/Oは“イベント駆動バッチ”に分担
サンプル:I/Oをインストール型トリガーへ移す
// ❌ カスタム関数内でDriveAppを呼ぶ(禁止文脈)
function LIST_FILES(folderId) {
// return DriveApp.getFolderById(folderId).getFiles(); // ここでエラー
}
// ✅ メニューや手動実行・時間トリガーで動かす
function listFilesToSheet(folderId, sheetId, sheetName) {
const sh = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);
const it = DriveApp.getFolderById(folderId).getFiles();
const out = [];
while (it.hasNext()) {
const f = it.next();
out.push([f.getName(), f.getId(), f.getUrl(), f.getSize()]);
}
sh.clearContents();
if (out.length) sh.getRange(1,1,out.length,4).setValues(out);
}
function onOpen() {
SpreadsheetApp.getUi().createMenu('DriveOps')
.addItem('フォルダ一覧を書き出す', 'runList')
.addToUi();
}
function runList() {
listFilesToSheet('YOUR_FOLDER_ID','YOUR_SHEET_ID','Data');
}シンプルトリガー→インストール型トリガーに置換
・onEdit/onOpenなど“simple”は権限が弱い
・ScriptApp.newTriggerで“installed”に切替え、作成者が認可を通す
function job(e) {
// DriveApp利用OK(トリガー作成者の認可で実行)
const name = DriveApp.getFileById('YOUR_FILE_ID').getName();
const sh = SpreadsheetApp.getActive().getSheetByName('Log');
sh.appendRow([new Date(), name, e?.range?.getA1Notation() || '']);
}
function installOnEdit() {
ScriptApp.newTrigger('job')
.forSpreadsheet(SpreadsheetApp.getActive())
.onEdit()
.create();
}クライアント側からはgoogle.script.runでサーバへ委譲
・ブラウザJSはDriveAppに触れない。サーバ関数がDrive操作を担当
// Code.gs
function createFileInFolder(folderId, name, content) {
const file = DriveApp.getFolderById(folderId).createFile(name, content, MimeType.PLAIN_TEXT);
return { id: file.getId(), url: file.getUrl() };
}
function doGet(){ return HtmlService.createHtmlOutputFromFile('index'); }
<!-- index.html -->
<input id="name" placeholder="file.txt">
<button onclick="run()">作成</button>
<script>
function run(){
const n = document.getElementById('name').value || 'file.txt';
google.script.run
.withSuccessHandler(res => alert('作成: ' + res.url))
.withFailureHandler(err => alert('失敗: ' + (err && err.message)))
.createFileInFolder('YOUR_FOLDER_ID', n, 'hello');
}
</script>ウェブアプリ/実行API:実行主体・スコープ・再デプロイ
・「自分として実行」or「アクセスするユーザーとして実行」を要件で選択
・Driveスコープが必要な変更後は“新バージョンとしてデプロイ”し再同意
・TestingとProductionのURL混在に注意(古いURLを叩かない)
共有ドライブ/権限のすれ違いを点検
・対象が共有ドライブなら実行主体に適切ロールが必須(閲覧のみでは作成不可)
・openByIdにURLではなく“IDのみ”を渡す、ゴミ箱・所有者変更も確認
function diagDrive(targetId) {
const ctx = {
effective: Session.getEffectiveUser().getEmail(),
active: Session.getActiveUser().getEmail()
};
try {
const f = DriveApp.getFileById(targetId);
console.log('OK', { ctx, name: f.getName(), url: f.getUrl() });
return true;
} catch (e) {
console.error('Drive diag failed', { ctx, msg: e.message });
throw e;
}
}外部フロントからの直叩き禁止(CORS/認可の壁)
・外部サイト→GASをXHR直叩きし、サーバ側でDrive操作…は実装困難
・必要なら中継(Cloud Run/Functions)やGAS側UIで完結する設計へ
アドオン/組織ポリシーの制約とマニフェスト
・アドオンはappsscript.jsonで必要最小スコープを宣言し、管理者承認が必要
・組織で「信頼できるアプリ」制限があるとユーザー同意だけでは不可
NG→OK早見表(クイック修正)
・NG:カスタム関数でDriveApp → OK:ボタン/メニュー/時間トリガーでサーバ関数実行
・NG:onEdit(シンプル)でDrive → OK:インストール型onEditに置換
・NG:ブラウザJSでDrive → OK:google.script.runでサーバへ委譲
・NG:デプロイ更新/再同意なし → OK:新バージョンとしてデプロイ+認可完了
・NG:共有ドライブ権限不足 → OK:実行主体に適切ロール付与
・NG:openByIdにURL → OK:純粋なファイルIDを渡す
チェックリスト(導入順)
・実行“入口”はDriveApp可の文脈か(installed trigger / server-side)
・実行主体は要件どおりか(effectiveUser確認)
・Driveスコープで再デプロイし、同意を取り直したか
・共有ドライブや所有者・ゴミ箱など周辺権限を満たしているか
・クライアントはgoogle.script.runのみでサーバへ委譲しているか
・診断関数(diagDrive)で最小再現を確認し、ログを残しているか
-
前の記事
GAS『Unknown Error Occurred』の原因と対処法 2025.10.31
-
次の記事
GAS『Unknown Error Occurred』の原因と対処法 2025.11.05
コメントを書く