以 Google Chat 應用程式的身分進行驗證

本指南說明如何設定及使用服務帳戶,代表 Chat 應用程式存取 Google Chat API。首先,我們會逐步引導您建立服務帳戶。接著,說明如何編寫指令碼,使用服務帳戶驗證 Chat API,並在 Chat 空間中發布訊息。

使用服務帳戶進行驗證時,Chat 應用程式必須是 Chat 聊天室的成員,才能取得聊天室的資料或執行相關操作。舉例來說,如要列出聊天室的成員,或在聊天室中建立訊息,Chat 應用程式本身必須是聊天室的成員。唯一的例外狀況是 Chat 應用程式使用應用程式驗證功能建立聊天室,在這種情況下,應用程式會建立聊天室,然後自動成為成員。

支援應用程式授權的 Google Chat API 方法,其授權範圍名稱會以 https://www.googleapis.com/auth/chat.app.* 開頭,需要一次性管理員核准。支援使用 https://www.googleapis.com/auth/chat.bot 授權範圍授權應用程式的 Google Chat API 方法,不需要額外核准。開發人員預覽版提供 https://www.googleapis.com/auth/chat.app.* 授權範圍。

如果 Chat 應用程式需要存取使用者資料或代表使用者執行動作,請改為以使用者的身分進行驗證。如果您是網域管理員,可以授予全網域授權委派權限,授權 Chat 應用程式的服務帳戶存取使用者資料,無需每位使用者取得同意。詳情請參閱「使用全網域委派功能進行驗證和授權」。

如要進一步瞭解 Chat 擴充應用程式何時需要驗證,以及應使用哪種驗證方式,請參閱 Chat API 驗證和授權總覽中的「需要驗證的類型」。

必要條件

Java

  • JDK 1.7 以上版本
  • Maven 套件管理工具
  • 已初始化的 Maven 專案。如要初始化新專案,請在指令列介面中執行下列指令:
    mvn archetype:generate -DgroupId=com.google.chat.app.authsample -DartifactId=auth-sample-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
  • 已啟用互動功能的 Google Chat 應用程式。如要使用 HTTP 服務建立互動式 Chat 應用程式,請完成這個快速入門導覽課程
  • 將 Chat 應用程式新增至聊天室。如要新增 Chat 應用程式,請參閱「 測試 Google Chat 應用程式的互動功能」。

Python

Node.js

  • Node.js 14 以上版本
  • npm 套件管理工具
  • 已初始化的 Node.js 專案。如要初始化新專案,請建立並切換至新資料夾,然後在指令列介面中執行下列指令:
    npm init
  • 已啟用互動功能的 Google Chat 應用程式。如要使用 HTTP 服務建立互動式 Chat 應用程式,請完成這個快速入門導覽課程
  • 將 Chat 應用程式新增至聊天室。如要新增 Chat 應用程式,請參閱「 測試 Google Chat 應用程式的互動功能」。

Apps Script

步驟 1:在 Google Cloud 控制台中建立服務帳戶

建立服務帳戶,讓 Chat 應用程式可以用來存取 Google API。

建立服務帳戶

如要建立服務帳戶,請按照下列步驟操作:

Google Cloud 控制台

  1. 在 Google Cloud 控制台中,依序前往「Menu」(選單) >「IAM & Admin」(IAM 與管理) >「Service Accounts」(服務帳戶)

    前往「Service Accounts」(服務帳戶) 頁面

  2. 按一下「建立服務帳戶」
  3. 填寫服務帳戶詳細資料,然後按一下「建立並繼續」
  4. 選用:為服務帳戶指派角色,授予 Google Cloud 專案資源的存取權。詳情請參閱「授予、變更及撤銷資源的存取權」。
  5. 按一下「繼續」
  6. 選用:輸入可管理這個服務帳戶並執行相關動作的使用者或群組。詳情請參閱「管理服務帳戶模擬功能」。
  7. 按一下「完成」,請記下服務帳戶的電子郵件地址。

gcloud CLI

  1. 建立服務帳戶:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. 選用:為服務帳戶指派角色,授予 Google Cloud 專案資源的存取權。詳情請參閱「授予、變更及撤銷資源的存取權」。

服務帳戶會顯示在服務帳戶頁面上。接下來,為服務帳戶建立私密金鑰

建立私密金鑰

如要為服務帳戶建立及下載私密金鑰,請按照下列步驟操作:

  1. 在 Google Cloud 控制台中,依序前往「Menu」(選單) >「IAM & Admin」(IAM 與管理) >「Service Accounts」(服務帳戶)

    前往「Service Accounts」(服務帳戶) 頁面

  2. 選取服務帳戶。
  3. 依序點選「金鑰」>「新增金鑰」>「建立新的金鑰」
  4. 選取「JSON」,然後按一下「建立」

    系統會產生新的公開/私密金鑰組,並以新檔案的形式下載到您的電腦。將下載的 JSON 檔案儲存為 credentials.json,並儲存在工作目錄中。這個檔案是這組金鑰的唯一副本。如要瞭解如何安全儲存金鑰,請參閱「管理服務帳戶金鑰」。

  5. 按一下「關閉」

如要進一步瞭解服務帳戶,請參閱 Google Cloud IAM 說明文件中的「服務帳戶」一文。

接著,請為這個服務帳戶建立與 Google Workspace Marketplace 相容的 OAuth 用戶端。

取得管理員核准

如要使用開頭為 https://www.googleapis.com/auth/chat.app.* 的授權範圍 (可在開發人員預覽版中使用),Chat 應用程式必須取得一次性管理員核准

如要使用 https://www.googleapis.com/auth/chat.bot 授權範圍,則不需要經過管理員核准。

如要取得管理員核准,您必須為 Chat 應用程式的服務帳戶準備下列資訊:

  • 與 Google Workspace Marketplace 相容的 OAuth 用戶端。
  • Google Workspace Marketplace SDK 中的應用程式設定。

建立與 Google Workspace Marketplace 相容的 OAuth 用戶端

如要建立與 Google Workspace Marketplace 相容的 OAuth 用戶端,請按照下列步驟操作:

  1. 在 Google Cloud 控制台中,依序前往「選單」 >「IAM 與管理」>「服務帳戶」

    前往「Service Accounts」(服務帳戶)

  2. 按一下您為 Chat 應用程式建立的服務帳戶。

  3. 按一下 [進階設定]

  4. 按一下「Create Google Workspace Marketplace-compatible OAuth Client」(建立與 Google Workspace Marketplace 相容的 OAuth 用戶端)

  5. 按一下「繼續」

畫面上會顯示確認訊息,指出已建立與 Google Workspace Marketplace 相容的 OAuth 用戶端。

在 Google Workspace Marketplace SDK 中設定 Chat 應用程式

如要在 Google Workspace Marketplace SDK 中設定 Chat 應用程式,請按照下列步驟操作:

  1. 在 Google Cloud 控制台中啟用 Google Workspace Marketplace SDK。

    啟用 Google Workspace Marketplace SDK

  2. 在 Google Cloud 控制台中,依序前往「Menu」圖示 >「APIs & Services」(API 和服務) >「Enabled API & services」>「Google Workspace Marketplace SDK」>「App Configuration」

    前往「應用程式設定」

  3. 完成「App Configuration」(應用程式設定) 頁面。您如何設定 Chat 應用程式,取決於目標對象和其他因素。如需完成應用程式設定頁面的說明,請參閱「在 Google Workspace Marketplace SDK 中設定應用程式」一文。請根據本指南的目的,輸入下列資訊:

    1. 在「應用程式顯示設定」下方,選取「私人」
    2. 在「安裝設定」下方,選取「個人 + 管理員安裝」
    3. 在「應用程式整合服務」下方,選取「Chat 擴充應用程式」
    4. 在「OAuth 範圍」下方,輸入 Chat 應用程式使用的所有驗證範圍

    5. 在「開發人員資訊」下方,輸入「開發人員名稱」、「開發人員網站網址」和「開發人員電子郵件」

    6. 按一下「儲存草稿」

取得管理員核准

服務帳戶已設定為接收管理員核准,請按照「設定 Chat 應用程式的授權」一文中的步驟,向 Google Workspace 管理員取得核准。

步驟 2:安裝 Google 用戶端程式庫和其他依附元件

安裝 Google 用戶端程式庫和專案需要的其他依附元件。

Java

如要將 Google 用戶端程式庫和其他必要的依附元件新增至 Maven 專案,請編輯專案目錄中的 pom.xml 檔案,並新增下列依附元件:

<dependencies>
  <!-- ... existing dependencies ... -->
  <dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-chat</artifactId>
    <version>v1-rev20230905-2.0.0</version>
  </dependency>
  <dependency>
    <groupId>com.google.auth</groupId>
    <artifactId>google-auth-library-oauth2-http</artifactId>
    <version>1.19.0</version>
  </dependency>
  <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.10.1</version>
  </dependency>
</dependencies>

Python

如果您尚未安裝 Python 適用的 Google 用戶端程式庫,請在指令列介面中執行下列指令:

pip3 install --upgrade google-api-python-client google-auth

Node.js

如要將 Google 用戶端程式庫新增到 Node.js 專案,請切換至專案目錄,然後在指令列介面中執行下列指令:

npm install "@googleapis/chat"

Apps Script

這個範例會使用 Apps Script 程式庫的 OAuth2,產生服務帳戶驗證的 JWT 權杖。如要將程式庫新增至 Apps Script 專案,請按照下列步驟操作:

  1. 按一下左側的「編輯器」圖示
  2. 在左側的「資料庫」旁邊,按一下「新增資料庫」圖示
  3. 輸入指令碼 ID 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF
  4. 依序按一下「查詢」和「新增」

本範例使用進階 Chat 服務來呼叫 Google Chat API。如要為 Apps Script 專案啟用服務,請按照下列步驟操作:

  1. 按一下左側的「編輯器」圖示
  2. 在左側的「Service」(服務) 旁邊,按一下「Add a service」(新增服務)
  3. 選取「Google Chat API」
  4. 在「Version」中,選取「v1」
  5. 按一下 [新增]。

您可以使用用戶端程式庫支援的任何語言。

步驟 3:編寫使用服務帳戶驗證 Chat API 的指令碼

以下程式碼會使用服務帳戶驗證 Chat API,然後將訊息發布至 Chat 聊天室:

Java

  1. 在專案目錄中,開啟 src/main/java/com/google/chat/app/authsample/App.java 檔案。
  2. App.java 中的內容替換為以下程式碼:

    package com.google.chat.app.authsample;
    
    import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
    import com.google.api.client.http.HttpRequestInitializer;
    import com.google.api.client.json.gson.GsonFactory;
    import com.google.api.services.chat.v1.HangoutsChat;
    import com.google.api.services.chat.v1.model.Message;
    import com.google.auth.http.HttpCredentialsAdapter;
    import com.google.auth.oauth2.GoogleCredentials;
    
    /**
     * Authenticates with Chat API using service account credentials,
     * then creates a Chat message.
     */
    public class App {
        // Specify required scopes.
        private static final String CHAT_SCOPE = "https://www.googleapis.com/auth/chat.bot";
    
        // Specify service account details.
        private static final String PRIVATE_KEY_RESOURCE_URI = "/credentials.json";
    
        public static void main( String[] args ) {
            try {
                // Run app.
                Message response = App.createChatMessage();
                // Print details about the created message.
                System.out.println(response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private static Message createChatMessage() throws Exception {
            // Build the Chat API client and authenticate with the service account.
            GoogleCredentials credentials = GoogleCredentials.fromStream(
                App.class.getResourceAsStream(PRIVATE_KEY_RESOURCE_URI))
                .createScoped(CHAT_SCOPE);
            HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);
            HangoutsChat chatService = new HangoutsChat.Builder(
                GoogleNetHttpTransport.newTrustedTransport(),
                GsonFactory.getDefaultInstance(),
                requestInitializer)
                .setApplicationName("auth-sample-app")
                .build();
    
            // The space to create the message in.
            //
            // Replace SPACE_NAME with a space name.
            // Obtain the space name from the spaces resource of Chat API,
            // or from a space's URL.
            String spaceName = "spaces/SPACE_NAME";
    
            // Create a Chat message.
            Message message = new Message().setText("Hello, world!");
            return chatService.spaces().messages().create(spaceName, message).execute();
        }
    }
    
  3. 在程式碼中,將 SPACE_NAME 替換成聊天室名稱,您可以透過 Chat API 中的 spaces.list 方法,或從聊天室的網址取得名稱。

  4. 在專案目錄中建立名為 resources 的新子目錄。

  5. 請確認服務帳戶的私密金鑰檔案名稱為 credentials.json,並將該檔案複製到 resources 子目錄。

  6. 如要設定 Maven 在專案套件中加入私密金鑰檔案,請編輯專案目錄中的 pom.xml 檔案,然後在 <build> 區段中加入下列設定:

    <build>
      <!-- ... existing configurations ... -->
      <resources>
        <resource>
          <directory>resources</directory>
        </resource>
      </resources>
    </build>
    
  7. 如要設定 Maven 以納入專案套件中的依附元件,並執行應用程式的主類別,請編輯專案目錄中的 pom.xml 檔案,並在 <plugins> 區段中新增下列設定:

    <plugins>
      <!-- ... existing configurations ... -->
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <mainClass>com.google.chat.app.authsample.App</mainClass>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
    

Python

  1. 在工作目錄中,建立名為 chat_app_auth.py 的檔案。
  2. chat_app_auth.py 中加入以下程式碼:

    from apiclient.discovery import build
    from google.oauth2 import service_account
    
    # Specify required scopes.
    SCOPES = ['https://www.googleapis.com/auth/chat.bot']
    
    # Specify service account details.
    creds = service_account.Credentials.from_service_account_file(
        'credentials.json', scopes=SCOPES)
    
    # Build the URI and authenticate with the service account.
    chat = build('chat', 'v1', credentials=creds)
    
    # Create a Chat message.
    result = chat.spaces().messages().create(
    
        # The space to create the message in.
        #
        # Replace SPACE_NAME with a space name.
        # Obtain the space name from the spaces resource of Chat API,
        # or from a space's URL.
        parent='spaces/SPACE_NAME',
    
        # The message to create.
        body={'text': 'Hello, world!'}
    
    ).execute()
    
    # Prints details about the created message.
    print(result)
    
  3. 在程式碼中,將 SPACE_NAME 替換成聊天室名稱,您可以透過 Chat API 中的 spaces.list 方法,或從聊天室的網址取得名稱。請確認服務帳戶的私密金鑰檔案名稱為 credentials.json

Node.js

  1. 在專案的目錄中,建立名為 chat_app_auth.js 的檔案。
  2. chat_app_auth.js 中加入下列程式碼:

    const chat = require('@googleapis/chat');
    
    async function createMessage() {
      const auth = new chat.auth.GoogleAuth({
    
        // Specify service account details.
        keyFilename: 'credentials.json',
    
        // Specify required scopes.
        scopes: ['https://www.googleapis.com/auth/chat.bot']
    
      });
      const authClient = await auth.getClient();
    
      // Create the Chat API client and authenticate with the service account.
      const chatClient = await chat.chat({
        version: 'v1',
        auth: authClient
      });
    
      // Create a Chat message.
      const result = await chatClient.spaces.messages.create({
    
        // The space to create the message in.
        //
        // Replace SPACE_NAME with a space name.
        // Obtain the space name from the spaces resource of Chat API,
        // or from a space's URL.
        parent: 'spaces/SPACE_NAME',
    
        // The message to create.
        requestBody: { 'text': 'Hello, world!' }
    
      });
      return result;
    }
    
    // Execute function then print details about the created message.
    createMessage().then(console.log);
    
  3. 在程式碼中,將 SPACE_NAME 替換成聊天室名稱,您可以透過 Chat API 中的 spaces.list 方法,或從聊天室的網址取得名稱。請確認服務帳戶的私密金鑰檔案名稱為 credentials.json

Apps Script

  1. 在 Apps Script 編輯器中,編輯 appsscript.json 檔案並新增發出外部要求所需的 OAuth 範圍,以取得服務帳戶 OAuth 權杖:

      "oauthScopes": [
        "https://www.googleapis.com/auth/script.external_request"
      ]
    
  2. 將下列程式碼儲存在 Apps Script 專案中名為 ChatAppAuth.gs 的檔案:

    // Specify the contents of the file credentials.json.
    const CREDENTIALS = CREDENTIALS;
    
    const SCOPE = 'https://www.googleapis.com/auth/chat.bot';
    
    // The space to create the message in.
    //
    // Replace SPACE_NAME with a space name.
    // Obtain the space name from the spaces resource of Chat API,
    // or from a space's URL.
    const PARENT = 'spaces/SPACE_NAME'
    
    /**
     * Authenticates with Chat API using app credentials, then posts a message.
     */
    function createMessageWithAppCredentials() {
      try {
        const service = getService_();
        if (!service.hasAccess()) {
          console.error(service.getLastError());
          return;
        }
    
        // Specify the message to create.
        const message = {'text': 'Hello world!'};
    
        // Call Chat API with a service account to create a message.
        const result = Chat.Spaces.Messages.create(
            message,
            PARENT,
            {},
            // Authenticate with the service account token.
            {'Authorization': 'Bearer ' + service.getAccessToken()});
    
        // Log details about the created message.
        console.log(result);
    
      } catch (err) {
        // TODO (developer) - Handle exception.
        console.log('Failed to create message with error %s', err.message);
      }
    }
    
    /**
     * Configures the OAuth library to authenticate with the service account.
     */
    function getService_() {
      return OAuth2.createService(CREDENTIALS.client_email)
          .setTokenUrl('https://oauth2.googleapis.com/token')
          .setPrivateKey(CREDENTIALS.private_key)
          .setIssuer(CREDENTIALS.client_email)
          .setSubject(CREDENTIALS.client_email)
          .setScope(SCOPE)
          .setPropertyStore(PropertiesService.getScriptProperties());
    }
    
  3. 在程式碼中,將 CREDENTIALS 替換為 credentials.json 檔案的內容。

  4. 在程式碼中,將 SPACE_NAME 替換為聊天室名稱,您可以從 Chat API 的 spaces.list 方法或聊天室網址取得。

步驟 4:執行完整範例

在工作目錄中建構並執行範例:

Java

mvn compile assembly:single
java -jar target/auth-sample-app-1.0-SNAPSHOT-jar-with-dependencies.jar

Python

python3 chat_app_auth.py

Node.js

node chat_app_auth.js

Apps Script

在 Apps Script 編輯器中開啟檔案 ChatAppAuth.gs,然後按一下「Run」

您的指令碼會向 Chat API 提出經過驗證的要求,而 API 會以 Chat 應用程式在 Chat 聊天室中發布訊息來回應。

排解範例問題

本節將說明您在嘗試執行此範例時可能會遇到的常見問題。

您無權使用這個應用程式

執行指令碼時,您可能會收到以下錯誤訊息:

<HttpError 403 when requesting https://chat.googleapis.com/v1/spaces/{space}/messages?alt=json returned "You are not permitted to use this app". Details: "You are not permitted to use this app">

這則錯誤訊息表示 Chat 應用程式的權限不足,無法在指定 Chat 聊天室中建立 Chat 訊息。

如要解決這項錯誤,請將 Chat 應用程式新增至指派給 Chat 聊天室的權限

管理員必須授予應用程式這項操作所需的 OAuth 授權範圍

執行指令碼時,您可能會收到以下錯誤訊息:

<HttpError 403 when requesting https://chat.googleapis.com/v1/spaces/{space}?alt=json returned "The administrator must grant the app the required OAuth authorization scope for this action.". Details: "The administrator must grant the app the required OAuth authorization scope for this action.">

這則錯誤訊息表示 Google Workspace 管理員尚未授予一次 Chat 應用程式使用授權範圍,因此無法使用以 https://www.googleapis.com/auth/chat.app.* 名稱開頭的授權範圍。

如何解決錯誤:

  • 請 Google Workspace 管理員核准 Chat 應用程式。在 Chat 應用程式邏輯中處理這個錯誤時,建議傳送訊息,說明 Chat 應用程式需要管理員核准才能執行要求的動作,例如:To perform this action, I need approval. <https://support.google.com/a?p=chat-app-auth|Learn more>.
  • 如果 Google Chat API 方法支援 https://www.googleapis.com/auth/chat.bot 授權範圍,而不需要管理員核准,請考慮改用。如要查看方法支援哪些授權範圍,請參閱 Google Chat API 參考說明文件
  • 如要瞭解 Chat API 的其他功能,請參閱 Chat API 參考說明文件
  • 如果使用以 https://www.googleapis.com/auth/chat.app.* 開頭的 OAuth 授權範圍,請參閱這篇文章,瞭解如何由管理員授予一次性核准。