使用者必須授權指令碼專案存取自己的資料或代表自己執行動作。使用者首次執行需要授權的指令碼時,使用者介面會顯示提示,要求啟動授權流程。
在這個流程中,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 權限。
查看範圍
如要查看指令碼專案目前需要的範圍,請按照下列步驟操作:
- 開啟指令碼專案。
- 按一下左側的「總覽」 。
- 查看「專案 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 權限可讓使用者更精細地控管要與每個指令碼共用的帳戶資料。舉例來說,假設您開發的指令碼同時要求電子郵件和日曆範圍的權限。使用者可能只希望透過指令碼使用 Google 日曆功能,但不想使用 Gmail。透過精細的 OAuth 權限,使用者可以選擇只授予日曆權限,而不授予 Gmail 權限。
以下各節說明處理細部 OAuth 權限的主要方式。
自動要求必要範圍的權限
如果執行流程需要範圍權限才能運作,您可以要求使用者先授予這些權限,才能使用該流程。指令碼可以檢查使用者是否已授予權限,如果沒有,則自動要求權限。
您可以使用 ScriptApp
類別的下列方法,驗證必要範圍的權限,並自動顯示授權提示,要求任何缺少的權限:
requireScopes(authMode, oAuthScopes)
: 如果執行流程依賴一或多個範圍,但並非指令碼使用的所有範圍,請使用這個方法。requireAllScopes(authMode)
:如果執行流程依附於指令碼使用的所有範圍,請使用這個方法。
範例
以下範例說明如何呼叫 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!");
}
為缺少範圍建立自訂體驗
您可以取得執行指令碼的使用者權限詳細資料,並根據權限狀態設計自訂體驗。舉例來說,您可以決定關閉指令碼中需要使用者未授予權限的特定功能,或是顯示自訂對話方塊,說明缺少哪些權限。下列方法會取得包含使用者授權範圍的物件,以及可要求任何缺少的範圍的網址:
getAuthorizationInfo(authMode, oAuthScopes)
:使用這個方法檢查特定範圍的權限狀態。getAuthorizationInfo(authMode)
: 使用這個方法檢查指令碼所用所有範圍的權限狀態。
如要從授權資訊物件取得權限詳細資料 (例如已授權的範圍清單,以及要求缺少權限的網址),請使用 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 範圍附加規定。