DriveApp.getFileByIdのGoogleApps ScriptAPI認証
ほとんどすべてのスクリプト/関数を直接実行するGoogleCloud Platform Project(GCP)がありますが、APIを介していくつか実行します。すべてはGSuiteドメインの内部でのみアクセス可能であり、OAuth同意画面のアプリケーションタイプは「内部」です。
APIを介して呼び出されるのではなく、x分ごとにタイマーで直接呼び出されるスクリプトがあります。それは実行します
DriveApp.getFileByID(pictureID)
これはうまくいきます!問題はありません。
また、同じGCPプロジェクトに別のスクリプトがあり、タイマーによってトリガーされて実行されるのではなく、APIを介して呼び出されて実行されます。これを呼び出すコード行は次のとおりです(それほど重要ではありません)。
var result = UrlFetchApp.fetch(url, options);
APIスクリプトはうまく機能します!次の行に到達するまで:
try { var file = DriveApp.getFileById(pictureID); }
catch (e) {
Logger.log('e = ' + JSON.stringify(e));
return;
}
ログの結果は次のとおりです。
e = {"name":"Exception"}
pictureIDが、動作する非APIスクリプトの場合と同じであることを確認しました。このAPI実行スクリプトで「試行」を行って、ソフトウェアが実際にファイルにアクセスするのではなく、ファイルにアクセスできることを確認しています。
これは承認の問題であると確信しています。GCPを使用してからしばらく経ちましたが、承認の経験はありますが、それほど多くはありません。
承認に関する詳細は次のとおりです...
プロジェクトのスクリプトプロジェクトプロパティ(ファイル/プロジェクトプロパティ)は、次のOAuthスコープが必要であることを示しています。
Googleのドキュメントによると https://developers.google.com/apps-script/reference/drive/drive-app#getfilebyidid、
Scripts that use this method require authorization with one or more of the following scopes:
https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive
GCPOauth同意画面で定義したスコープは次のとおりです。
ご覧のとおり、drive、drive.readonly、およびdrive.fileを追加しました(実際には必要ないようです)。
さらに、この特定の画像ファイルは、GCPプロジェクトの所有者のGoogleドライブ、スクリプト、GSuiteドメインのトップレベルの管理者に保存されます。ユーザーは自分のGoogleドライブからこのソフトウェア/ GCPの所有者に画像を共有するため、常にそうなるとは限りません。ただし、タイマーによってトリガーされたスクリプトは、これらのユーザー共有ファイルでは機能しますが、APIを介して呼び出されたスクリプトでは機能しないと感じています。
これは認証の問題であると確信していますが、どこかに何かが足りません。
ご協力ありがとうございました!
更新:
これは、APIスクリプトを呼び出すスクリプトのコードです(機密性のために一部変更されています)。おそらく問題がクライアント/呼び出し側にあるのではないかと思います。おそらく、OAuthTokenを正しく取得していませんか?または、トークンに正しい権限がありませんか?
var token = ScriptApp.getOAuthToken();
var header = {
"Content-Type": "application/json",
"Authorization": "Bearer " + token,
};
var parms = [id];
var data = {
"function": "updateSettings",
"parameters": parms,
"devMode": true,
}
var options = {
"method":"POST",
"headers": header,
"muteHttpExceptions": true,
"payload": JSON.stringify(data)
};
// Call the API
var result = UrlFetchApp.fetch(url, options);
回答
グーグルに連絡した後、私はそれを理解しました、そして残念ながらあまり助けを得られませんでした、そしてさらに数時間の試みと研究...
私が見逃していたのは、manifest /appsscript.jsonファイルに「oathScopes」を追加することでした。必要なスコープをいじってみたところ、以下の2つになりました。私はこの答えを見て解決策を見つけました:ScriptApp.getAuthToken()を介して取得したAuthTokenを使用してGASのWebアプリを呼び出します。
スクリプトエディタ内で、マニフェストファイルの表示/表示に移動します。
以前は次のようになりました。
{
"timeZone": "America/New_York",
"dependencies": {
},
"webapp": {
"access": "MYSELF",
"executeAs": "USER_DEPLOYING"
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
これが今の様子です...
{
"timeZone": "America/New_York",
"dependencies": {
},
"webapp": {
"access": "MYSELF",
"executeAs": "USER_DEPLOYING"
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/script.external_request"
]
}
追加した後、appsscript.jsonを保存しました。次に、runOnEditトリガー(呼び出し元のスクリプト)に移動し、それを削除して再度追加しました。しかし、それは厄介な見た目のエラーを引き起こしました:
私はそれを調べて、この投稿を見つけました:AppsScriptで新しいトリガーを作成するときにエラーを受け取ります。そこで、スクリプトエディターでコードを実行すると、実際に認証画面が表示されました。承認し、トリガーを再度追加しました。これで、APIの呼び出しですべてがうまく機能します。