認証スコープ

ユーザーは、データにアクセスしたり、ユーザーに代わって操作を行ったりするスクリプト プロジェクトを承認する必要があります。ユーザーが承認を必要とするスクリプトを初めて実行すると、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 権限を処理するようにスクリプトを設計します。

表示スコープ

スクリプト プロジェクトに必要なスコープを確認するには:

  1. スクリプト プロジェクトを開きます。
  2. 左側の [概要] をクリックします。
  3. [プロジェクトの OAuth スコープ] でスコープを確認します。

明示的なスコープを設定する

Apps Script は、関数呼び出しのコードをスキャンして、必要なスコープを自動的に判断します。ほとんどのスクリプトではこれで十分ですが、公開されたアドオン、ウェブアプリ、Chat 用アプリ、Chat API の呼び出しでは、より直接的に制御する必要があります。

Apps Script では、緩いスコープが自動的に割り当てられることがあります。これは、スクリプトがユーザーに必要以上のアクセス権を要求していることを意味します。スクリプトを公開する際は、広範なスコープを、スクリプトのニーズをカバーする限定的なセットに置き換えます。

スクリプト プロジェクトで使用するスコープは、マニフェスト ファイルを編集して明示的に設定できます。oauthScopes マニフェスト フィールドは、プロジェクトで使用されるスコープの配列です。プロジェクトのスコープを設定する手順は次のとおりです。

  1. スクリプト プロジェクトを開きます。
  2. 左側の [プロジェクト設定] をクリックします。
  3. [「appsscript.json」マニフェスト ファイルをエディタで表示する] チェックボックスをオンにします。
  4. 左側の [エディタ] をクリックします。
  5. 左側の appsscript.json ファイルをクリックします。
  6. oauthScopes というラベルの付いた最上位フィールドを見つけます。存在しない場合は、追加できます。
  7. oauthScopes 配列の内容を、プロジェクトで使用するスコープに置き換えます。次に例を示します。
          {
            ...
            "oauthScopes": [
              "https://www.googleapis.com/auth/spreadsheets.readonly",
              "https://www.googleapis.com/auth/userinfo.email"
            ],
           ...
          }
  8. 上部の [保存] をクリックします。

きめ細かな OAuth 権限を処理する

きめ細かい OAuth の同意画面は、まずスクリプトを直接実行するユーザー向けに Apps Script IDE にリリースされました。この同意画面は、今後マクロ、トリガー、アドオンなどの他の実行環境にも段階的に導入される予定です。詳しくは、Google Apps Script の IDE の実行におけるきめ細かい OAuth の同意をご覧ください。

きめ細かな OAuth 同意画面では、ユーザーが認証する OAuth スコープを個別に指定できます。これにより、ユーザーは各スクリプトと共有するアカウント データをきめ細かく制御できます。たとえば、スクリプトがメールとカレンダーのスコープをリクエストしている場合、ユーザーは Gmail ではなくカレンダーの権限のみを付与できます。

以降のセクションでは、きめ細かい OAuth 権限を処理する方法について説明します。

必要なスコープの権限を自動的に要求する

実行フローに特定のスコープが必要な場合は、ユーザーにその権限の付与を要求できます。スクリプトで権限を確認し、権限がない場合は自動的にリクエストできます。

ScriptApp クラスの次のメソッドは、権限を検証し、認証プロンプトを表示します。

次の例は、requireScopes()requireAllScopes() を呼び出す方法を示しています。このスクリプトでは、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("dana@example.com", "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("dana@example.com", "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 を含む、ユーザーの権限情報を含むオブジェクトを取得します。

承認されたスコープのリストや、不足している権限をリクエストする URL など、認可情報オブジェクトから権限の詳細を取得するには、AuthorizationInfo クラスのメソッドを使用します。

次の例は、getAuthorizationInfo() を使用して、ユーザーが必要なスコープを付与していない機能をスキップする方法を示しています。これにより、不足しているスコープの承認を求めることなく、残りの実行フローを続行できます。

// 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("dana@example.com", "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 クライアントの検証を受ける必要があります。詳細については、次のガイドをご覧ください。

制限付きスコープ

機密性の高いスコープのほかにも、特定のスコープは制限付きに分類され、ユーザーデータの保護を目的とした追加のルールが適用されます。制限付きスコープを使用するアプリを公開する場合は、すべての仕様に準拠する必要があります。

公開前に、制限付きスコープの完全なリストを確認してください。準拠しているアプリは、特定の API スコープの追加要件に準拠する必要があります。

審査プロセスを簡素化するため、可能な限り制限付きスコープの使用は避けてください。非公開のアプリでは、制限付きスコープを自由に使用できます。