授權範圍

使用者必須授權指令碼專案存取自己的資料或代表自己執行動作。使用者首次執行需要授權的指令碼時,使用者介面會顯示提示,要求啟動授權流程。

在這個流程中,UI 會告知使用者指令碼要求哪些權限。舉例來說,指令碼可能要求讀取使用者的電子郵件訊息,或在日曆中建立活動。指令碼專案會將這些個別權限定義為 OAuth 範圍

對於大多數指令碼,Apps Script 會自動偵測您需要的範圍;您可以隨時查看指令碼使用的範圍。您也可以使用網址字串,在資訊清單明確設定範圍。某些應用程式 (例如外掛程式) 有時需要明確設定範圍,因為發布的應用程式一律應盡可能使用最窄的範圍。

在授權流程中,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 會掃描程式碼中需要範圍的函式呼叫,自動判斷指令碼需要哪些範圍。對大多數指令碼而言,這樣就已足夠,可節省您的時間,但如果是已發布的增益集、網頁應用程式、Google Chat 應用程式,以及對 Google 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 同意畫面後,可以指定要授權的個別 OAuth 範圍。精細 OAuth 權限可讓使用者更精細地控管要與每個指令碼共用的帳戶資料。舉例來說,假設您開發的指令碼同時要求電子郵件和日曆範圍的權限。使用者可能只希望透過指令碼使用 Google 日曆功能,但不想使用 Gmail。透過精細的 OAuth 權限,使用者可以選擇只授予日曆權限,而不授予 Gmail 權限。

以下各節說明處理細部 OAuth 權限的主要方式。

自動要求必要範圍的權限

如果執行流程需要範圍權限才能運作,您可以要求使用者先授予這些權限,才能使用該流程。指令碼可以檢查使用者是否已授予權限,如果沒有,則自動要求權限。

您可以使用 ScriptApp 類別的下列方法,驗證必要範圍的權限,並自動顯示授權提示,要求任何缺少的權限:

範例

以下範例說明如何呼叫 requireScopes(authMode, oAuthScopes)requireAllScopes(authMode) 方法。這個指令碼會使用 Gmail、試算表和日曆的範圍。sendEmail() 函式只需要 Gmail 和 Google 試算表的範圍,而 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!");
}

為缺少範圍建立自訂體驗

您可以取得執行指令碼的使用者權限詳細資料,並根據權限狀態設計自訂體驗。舉例來說,您可以決定關閉指令碼中需要使用者未授予權限的特定功能,或是顯示自訂對話方塊,說明缺少哪些權限。下列方法會取得包含使用者授權範圍的物件,以及可要求任何缺少的範圍的網址:

如要從授權資訊物件取得權限詳細資料 (例如已授權的範圍清單,以及要求缺少權限的網址),請使用 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("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,您必須在發布前遵守特定 API 範圍附加規定