ユーザーは、データにアクセスしたり、ユーザーに代わって操作を行ったりするスクリプト プロジェクトを承認する必要があります。ユーザーが初めて承認を必要とするスクリプトを実行すると、UI に承認フローを開始するよう求めるメッセージが表示されます。
このフローでは、スクリプトが権限を必要とする理由が UI に表示されます。たとえば、ユーザーのメール メッセージの読み取りや、カレンダーでの予定の作成をスクリプトが権限を必要とする理由などです。スクリプト プロジェクトでは、これらの個々の権限が OAuth スコープとして定義されます。
多くの場合、Apps Script が必要なスコープを自動的に検出します。スクリプトで使用されるスコープはいつでも確認できます。URL 文字列を使用して、マニフェストでスコープを明示的に設定することも可能です。公開されたアプリは常に可能な限り狭いスコープを使用する必要があるため、アドオンなどの特定のアプリでは、スコープを明示的に設定することが必要になる場合があります。
承認フローでは、Apps Script は必要なスコープの説明を人間が読める形式でユーザーに提示します。たとえば、スクリプトでスプレッドシートへの読み取り専用アクセスが必要な場合、マニフェストには https://www.googleapis.com/auth/spreadsheets.readonly
のスコープが含まれていることがあります。承認フローでは、このスコープを持つスクリプトが、このアプリケーションに「Google スプレッドシートの閲覧」を許可するようユーザーに求めます。
一部のスコープは他のスコープを含みます。たとえば、スコープ https://www.googleapis.com/auth/spreadsheets
が承認されると、スプレッドシートに対する読み取りと書き込みのアクセスが許可されます。
Apps Script IDE から直接スクリプトを実行するなど、スクリプトの実行環境によっては、ユーザーにきめ細かな OAuth 同意画面が表示されます。これにより、ユーザーはすべての権限を一度に付与するのではなく、付与する特定の権限を選択できるようになります。きめ細かな OAuth 権限を処理するようにスクリプトを設計することが重要です。
スコープを表示する
スクリプト プロジェクトで現在必要なスコープを確認するには、次の操作を行います。
- スクリプト プロジェクトを開きます。
- 左側の [概要] をクリックします。
- [プロジェクトの OAuth スコープ] でスコープを確認します。
明示的なスコープを設定する
Apps Script は、必要な関数呼び出しのコードをスキャンして、スクリプトに必要なスコープを自動的に判断します。多くの場合はこれだけで十分ですが、公開されたアドオン、ウェブアプリ、Google Chat 用アプリ、Google Chat API の呼び出しでは、スコープをより直接的に制御する必要があります。
Apps Script では、プロジェクトに非常に緩いスコープが自動的に割り当てられることがあります。これは、スクリプトがユーザーに必要以上の情報を要求していることを意味し、望ましくありません。スクリプトを公開する際は、広範なスコープを、スクリプトのニーズを過不足なくカバーする、より限定的なセットに置き換える必要があります。
スクリプト プロジェクトで使用するスコープは、マニフェスト ファイルを編集して明示的に設定できます。マニフェスト フィールド oauthScopes
は、プロジェクトで使用されるすべてのスコープの配列です。プロジェクトのスコープを設定する手順は次のとおりです。
- スクリプト プロジェクトを開きます。
- 左側の [プロジェクト設定] をクリックします。
- [「appsscript.json」マニフェスト ファイルをエディタで表示する] チェックボックスをオンにします。
- 左側の [エディタ] をクリックします。
- 左側の
appsscript.json
ファイルをクリックします。 oauthScopes
というラベルの付いた最上位のフィールドを見つけます。存在しない場合は、追加できます。oauthScopes
フィールドは、文字列の配列を指定します。プロジェクトで使用するスコープを設定するには、この配列の内容を、使用するスコープに置き換えます。次に例を示します。{ ... "oauthScopes": [ "https://www.googleapis.com/auth/spreadsheets.readonly", "https://www.googleapis.com/auth/userinfo.email" ], ... }
- 上部の保存アイコン( )をクリックします。
きめ細かな OAuth 権限を処理する
きめ細かな OAuth 同意画面では、ユーザーが認証する OAuth スコープを個別に指定できます。きめ細かな OAuth 権限により、ユーザーは各スクリプトと共有するアカウント データをより細かく制御できます。たとえば、メールとカレンダーの両方のスコープの権限をリクエストするスクリプトを開発するとします。ユーザーは、Gmail ではなく Google カレンダーの機能でのみスクリプトを使用したい場合があります。きめ細かな OAuth 権限を使用すると、ユーザーは Gmail ではなくカレンダーの権限のみを付与できます。
以降のセクションでは、きめ細かな OAuth 権限を処理する主な方法について説明します。
必要なスコープの権限を自動的に要求する
実行フローの動作にスコープの権限が必要な場合は、ユーザーがその権限を付与してからでないと使用できないようにすることができます。スクリプトで、ユーザーがすでに権限を付与しているかどうかを確認し、付与していない場合は自動的に権限をリクエストできます。
ScriptApp
クラスの次のメソッドを使用すると、必要なスコープの権限を検証し、不足している権限をリクエストする認証プロンプトを自動的に表示できます。
requireScopes(authMode, oAuthScopes)
: このメソッドは、1 つ以上のスコープに依存する実行フローで使用しますが、実行フローがスクリプトで使用されるすべてのスコープに依存する場合には使用しません。requireAllScopes(authMode)
: 実行フローがスクリプトで使用されるすべてのスコープに依存している場合は、このメソッドを使用します。
例
次の例は、requireScopes(authMode, oAuthScopes)
メソッドと requireAllScopes(authMode)
メソッドを呼び出す方法を示しています。このスクリプトでは、Gmail、スプレッドシート、カレンダーのスコープを使用します。sendEmail()
関数に必要なのは Gmail とスプレッドシートのスコープのみですが、createEventSendEmail()
関数に必要なのはスクリプトで使用されるすべてのスコープです。
// This function requires the Gmail and Sheets scopes. function sendEmail() { // Validates that the user has granted permission for the Gmail and Sheets scopes. // If not, the execution ends and prompts the user for authorization. ScriptApp.requireScopes(ScriptApp.AuthMode.FULL, [ 'https://mail.google.com/', 'https://www.googleapis.com/auth/spreadsheets' ]); // Sends an email. GmailApp.sendEmail("[email protected]", "Subject", "Body"); Logger.log("Email sent successfully!"); // Opens a spreadsheet and sheet to track the sent email. const ss = SpreadsheetApp.openById("abc1234567"); const sheet = ss.getSheetByName("Email Tracker") // Gets the last row of the sheet. const lastRow = sheet.getLastRow(); // Adds "Sent" to column E of the last row of the spreadsheet. sheet.getRange(lastRow, 5).setValue("Sent"); Logger.log("Sheet updated successfully!"); } // This function requires all scopes used by the script (Gmail, // Calendar, and Sheets). function createEventSendEmail() { // Validates that the user has granted permission for all scopes used by the // script. If not, the execution ends and prompts the user for authorization. ScriptApp.requireAllScopes(ScriptApp.AuthMode.FULL); // Creates an event. CalendarApp.getDefaultCalendar().createEvent( "Meeting", new Date("November 28, 2024 10:00:00"), new Date("November 28, 2024 11:00:00") ); Logger.log("Calendar event created successfully!"); // Sends an email. GmailApp.sendEmail("[email protected]", "Subject 2", "Body 2"); Logger.log("Email sent successfully!"); // Opens a spreadsheet and sheet to track the created meeting and sent email. const ss = SpreadsheetApp.openById("abc1234567"); const sheet = ss.getSheetByName("Email and Meeting Tracker") // Gets the last row const lastRow = sheet.getLastRow(); // Adds "Sent" to column E of the last row sheet.getRange(lastRow, 5).setValue("Sent"); // Adds "Meeting created" to column F of the last row sheet.getRange(lastRow, 6).setValue("Meeting created"); Logger.log("Sheet updated successfully!"); }
スコープが不足している場合のカスタム処理を作成する
スクリプトを実行しているユーザーの権限の詳細を取得し、権限ステータスに基づいてカスタム処理を設計できます。このカスタム処理では、ユーザーが権限を付与していない場合に、権限を必要とするスクリプトの特定の機能を無効にしたり、権限がないことを説明するカスタム ダイアログを表示したりすることが可能です。次のメソッドは、ユーザーが承認したスコープと、不足しているスコープをリクエストするための URL を含む、ユーザーの権限情報を含むオブジェクトを取得します。
getAuthorizationInfo(authMode, oAuthScopes)
: このメソッドを使用して、特定のスコープの権限ステータスを確認します。getAuthorizationInfo(authMode)
: このメソッドを使用して、スクリプトで使用されているすべてのスコープの権限ステータスを確認します。
承認されたスコープのリストや、不足している権限をリクエストする URL など、認可情報オブジェクトから権限の詳細を取得するには、AuthorizationInfo
クラスのメソッドを使用します。
例
次の例は、必要なスコープが付与されていない実行フロー内の特定の機能をスキップするために getAuthorizationInfo(authMode, oAuthScopes)
メソッドを呼び出す方法を示しています。これにより、残りの実行フローは、不足しているスコープの承認を求めることなく続行できます。
// This function uses the Gmail scope and skips the email // capabilities if the scope for Gmail hasn't been granted. function myFunction() { const authInfo = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL, ['https://mail.google.com/']); if (authInfo.getAuthorizationStatus() === ScriptApp.AuthorizationStatus.NOT_REQUIRED) { GmailApp.sendEmail("[email protected]", "Subject", "Body"); Logger.log("Email sent successfully!"); } else { const scopesGranted = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL).getAuthorizedScopes(); console.warn(`Authorized scopes: ${scopesGranted} not enough to send mail, skipping.`); } // Continue the rest of the execution flow... }
トリガー実行に権限があることを確認する
トリガーに関連付けられた関数は特定のイベントで自動的に実行されるため、ユーザーが追加の権限を付与できない場合があります。トリガーをインストールする前に requireScopes(authMode, oAuthScopes)
を使用することをおすすめします。これは、ユーザーに不足している権限の確認を求めるもので、権限の確認がないとトリガーはインストールできません。
例
// This function requires scope Sheets. function trackFormSubmissions(e){ // Opens a spreadsheet to track the sent email. const ss = SpreadsheetApp.openById("abc1234567"); const sheet = ss.getSheetByName("Submission Tracker") // Gets the last row of the sheet. const lastRow = sheet.getLastRow(); // Adds email address of user that submitted the form // to column E of the last row of the spreadsheet. sheet.getRange(lastRow, 5).setValue(e.name); Logger.log("Sheet updated successfully!"); } function installTrigger(){ // Validates that the user has granted permissions for trigger // installation and execution. If not, trigger doesn't get // installed and prompts the user for authorization. ScriptApp.requireScopes(ScriptApp.AuthMode.FULL, [ 'https://www.googleapis.com/auth/script.scriptapp', 'https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/forms.currentonly' ]); ScriptApp.newTrigger('trackFormSubmission') .forForm(FormApp.getActiveForm()) .onFormSubmit() .create(); }
OAuth の検証
特定の OAuth スコープは、Google ユーザーデータへのアクセスを許可するため、機密性が高いと見なされます。スクリプト プロジェクトがユーザーデータへのアクセスを許可するスコープを使用する場合は、ウェブアプリまたはアドオンとして一般公開する前に、OAuth クライアントの検証を受ける必要があります。詳しくは、次のガイドを参照してください。
制限付きスコープ
機密性の高いスコープのほかにも、特定のスコープは制限付きに分類され、ユーザーデータの保護を目的とした追加のルールが適用されます。1 つ以上の制限付きスコープを使用するウェブアプリまたはアドオンを公開する場合は、公開前にアプリが指定されたすべての制限に準拠する必要があります。
公開前に、制限付きスコープの完全なリストを確認してください。アプリでこれらの API のいずれかを使用している場合は、公開前に特定の API スコープの追加要件に準拠させる必要があります。