Xác thực dưới dạng ứng dụng Google Chat

Hướng dẫn này giải thích cách thiết lập và sử dụng tài khoản dịch vụ để truy cập vào API Google Chat thay mặt cho ứng dụng Chat. Đầu tiên, hướng dẫn bạn cách tạo tài khoản dịch vụ. Sau đó, công cụ này minh hoạ cách để viết một tập lệnh sử dụng tài khoản dịch vụ để xác thực với Chat API và đăng tin nhắn trong phòng Chat.

Các ứng dụng trong Chat có thể dùng tài khoản dịch vụ để xác thực khi gọi không đồng bộ API Google Chat để họ có thể:

  • Gửi tin nhắn tới Google Chat bằng spaces.messages.create thành:
    • Thông báo cho người dùng khi hoàn tất việc chạy một công việc chạy trong nền lâu dài.
    • Thông báo cho người dùng rằng máy chủ đã mất kết nối mạng.
    • Đề nghị nhân viên hỗ trợ khách hàng xử lý một trường hợp khách hàng mới mở.
  • Cập nhật các tin nhắn đã gửi trước đó bằng spaces.messages.update thành:
    • Thay đổi trạng thái của hoạt động đang diễn ra.
    • Cập nhật ngày đến hạn hoặc người được giao việc cần làm.
  • Liệt kê người dùng trong không gian bằng spaces.members.list để:
    • Xem ai đang tham gia không gian.
    • Xác minh rằng tư cách thành viên của không gian bao gồm mọi người trong một nhóm.

Khi xác thực bằng tài khoản dịch vụ, để lấy dữ liệu về hoặc thực hiện các thao tác trong phòng Chat, các ứng dụng trong Chat phải có tư cách thành viên trong phòng Chat. Ví dụ: để liệt kê thành viên của không gian hoặc để tạo tin nhắn trong không gian, ứng dụng Chat phải tự mình là thành viên của không gian.

Nếu ứng dụng Chat của bạn cần truy cập vào dữ liệu người dùng hoặc thực hiện thao tác đối với xác thực với tư cách người dùng.

Nếu là quản trị viên miền, bạn có thể cấp quyền uỷ quyền trên toàn miền để cho phép tài khoản dịch vụ của ứng dụng truy cập dữ liệu không có yêu cầu từng người dùng đồng ý. Sau khi định cấu hình uỷ quyền trên toàn miền, bạn có thể thực hiện lệnh gọi API bằng tài khoản dịch vụ của bạn để mạo danh tài khoản người dùng. Mặc dù tài khoản dịch vụ được dùng cho xác thực, thì việc uỷ quyền trên toàn miền sẽ mạo danh người dùng và do đó sẽ được coi là xác thực người dùng. Mọi chức năng yêu cầu người dùng bạn có thể uỷ quyền trên toàn miền.

Để tìm hiểu thêm về thời điểm các ứng dụng trong Chat yêu cầu xác thực và cần sử dụng loại xác thực nào, hãy xem Các loại xác thực bắt buộc trong phần tổng quan về việc xác thực và uỷ quyền API Chat.

Điều kiện tiên quyết

Để chạy ví dụ trong hướng dẫn này, bạn cần có các điều kiện tiên quyết sau:

Ngoài ra, bạn cần có các điều kiện tiên quyết cho từng ngôn ngữ cụ thể sau:

Java

  • JDK 1.7 trở lên
  • Maven công cụ quản lý gói
  • Một dự án Maven đã khởi tạo. Để khởi chạy một dự án mới, hãy chạy sau đây trong giao diện dòng lệnh:

    mvn archetype:generate -DgroupId=com.google.chat.app.authsample -DartifactId=auth-sample-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
    

Python

  • Python 3.6 trở lên
  • pip công cụ quản lý gói

Node.js

  • Node.js
  • npm công cụ quản lý gói
  • Một dự án Node.js đã khởi tạo. Để khởi chạy một dự án mới, hãy tạo và chuyển sang một thư mục mới, sau đó chạy lệnh sau trong giao diện dòng lệnh:

    npm init
    

Apps Script

Bước 1: Tạo tài khoản dịch vụ trong bảng điều khiển Google Cloud

Tạo một tài khoản dịch vụ mà ứng dụng Chat có thể dùng để truy cập API của Google.

Tạo một tài khoản dịch vụ

Để tạo một tài khoản dịch vụ, hãy làm theo các bước sau:

bảng điều khiển Google Cloud

  1. Trong bảng điều khiển Google Cloud, hãy chuyển đến Trình đơn > IAM và Quản trị > Tài khoản dịch vụ.

    Chuyển đến trang Tài khoản dịch vụ

  2. Nhấp vào Tạo tài khoản dịch vụ.
  3. Điền thông tin chi tiết về tài khoản dịch vụ, sau đó nhấp vào Tạo và tiếp tục.
  4. Không bắt buộc: Chỉ định vai trò cho tài khoản dịch vụ của bạn để cấp quyền truy cập vào tài nguyên của dự án Google Cloud. Để biết thêm thông tin, hãy tham khảo bài viết Cấp, thay đổi và thu hồi quyền truy cập vào tài nguyên.
  5. Nhấp vào Tiếp tục.
  6. Không bắt buộc: Nhập những người dùng hoặc nhóm có thể quản lý và thực hiện hành động với tài khoản dịch vụ này. Để biết thêm thông tin chi tiết, hãy tham khảo bài viết Quản lý hành vi mạo danh tài khoản dịch vụ.
  7. Nhấp vào Xong. Ghi lại địa chỉ email của tài khoản dịch vụ.

Giao diện dòng lệnh (CLI) của gcloud

  1. Tạo tài khoản dịch vụ:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. Không bắt buộc: Chỉ định vai trò cho tài khoản dịch vụ của bạn để cấp quyền truy cập vào tài nguyên của dự án Google Cloud. Để biết thêm thông tin, hãy tham khảo bài viết Cấp, thay đổi và thu hồi quyền truy cập vào tài nguyên.

Tài khoản dịch vụ sẽ xuất hiện trên trang tài khoản dịch vụ. Tiếp theo, hãy tạo khoá cho tài khoản dịch vụ.

Tạo khoá riêng tư

Để tạo và tải khoá riêng tư xuống cho tài khoản dịch vụ, hãy làm theo các bước sau:

  1. Trong bảng điều khiển Google Cloud, hãy chuyển đến Trình đơn > IAM và Quản trị > Tài khoản dịch vụ.

    Chuyển đến trang Tài khoản dịch vụ

  2. Chọn tài khoản dịch vụ của bạn.
  3. Nhấp vào Khoá > Thêm khoá > Tạo khoá mới.
  4. Chọn JSON, rồi nhấp vào Tạo.

    Cặp khoá công khai/riêng tư mới của bạn sẽ được tạo và tải xuống dưới dạng tệp mới. Lưu tệp JSON đã tải xuống dưới dạng credentials.json trong thư mục đang làm việc. Tệp này là bản sao duy nhất của khoá này. Để biết thông tin về cách lưu trữ chìa khoá của bạn một cách an toàn, hãy xem Quản lý khoá tài khoản dịch vụ.

  5. Nhấp vào Đóng.

Để biết thêm thông tin về tài khoản dịch vụ, hãy xem tài khoản dịch vụ trong tài liệu về Google Cloud IAM.

Bước 2: Cài đặt thư viện ứng dụng của Google và các phần phụ thuộc khác

Cài đặt thư viện ứng dụng của Google và các phần phụ thuộc cần thiết khác cho dự án.

Java

Để thêm thư viện ứng dụng của Google và các phần phụ thuộc bắt buộc khác vào Dự án Maven, hãy chỉnh sửa tệp pom.xml trong thư mục của dự án rồi thêm phần tử các phần phụ thuộc sau:

<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

Nếu bạn chưa cài đặt thư viện ứng dụng của Google cho Python, hãy chạy lệnh sau trong giao diện dòng lệnh:

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

Node.js

Để thêm các thư viện ứng dụng của Google vào dự án Node.js, hãy chuyển sang thư mục của dự án và chạy lệnh sau trong giao diện dòng lệnh:

npm install "@googleapis/chat"

Apps Script

Mẫu này sử dụng phương pháp OAuth2 cho thư viện Apps Script để tạo mã thông báo JWT nhằm xác thực tài khoản dịch vụ. Cách thêm thư viện vào dự án Apps Script:

  1. Ở bên trái, hãy nhấp vào biểu tượng Trình chỉnh sửa .
  2. Ở bên trái, bên cạnh mục Thư viện, hãy nhấp vào Thêm thư viện .
  3. Nhập mã tập lệnh 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF.
  4. Nhấp vào Tra cứu, rồi nhấp vào Thêm.

Mẫu này sử dụng phương pháp Dịch vụ Chat nâng cao để gọi API Google Chat. Để bật dịch vụ cho Dự án Apps Script:

  1. Ở bên trái, hãy nhấp vào biểu tượng Trình chỉnh sửa .
  2. Ở bên trái, bên cạnh Dịch vụ, hãy nhấp vào Thêm dịch vụ .
  3. Chọn API Google Chat.
  4. Trong Phiên bản, hãy chọn v1.
  5. Nhấp vào Thêm.

Bạn có thể sử dụng bất kỳ ngôn ngữ nào được hỗ trợ bởi thư viện ứng dụng.

Bước 3: Viết một tập lệnh sử dụng tài khoản dịch vụ để xác thực bằng API Chat

Mã sau đây xác thực với API Chat bằng tài khoản dịch vụ, sau đó đăng tin nhắn lên một phòng Chat:

Java

  1. Trong thư mục của dự án, hãy mở tệp src/main/java/com/google/chat/app/authsample/App.java.
  2. Thay thế nội dung trong App.java bằng mã sau:

    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 via 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. Trong mã, hãy thay thế SPACE_NAME bằng một dấu cách mà bạn có thể lấy từ spaces.list trong API Chat hoặc từ URL của một không gian.

  4. Tạo một thư mục con mới có tên là resources trong thư mục của dự án.

  5. Đảm bảo rằng bạn đã đặt tên cho tệp khoá riêng tư cho tài khoản dịch vụ của mình credentials.json rồi sao chép tệp này vào thư mục con resources.

  6. Cách định cấu hình Maven đưa tệp khoá riêng tư vào gói dự án: chỉnh sửa tệp pom.xml trong thư mục của dự án và thêm đoạn mã sau cấu hình cho phần <build>:

    <build>
      <!-- ... existing configurations ... -->
      <resources>
        <resource>
          <directory>resources</directory>
        </resource>
      </resources>
    </build>
    
  7. Để định cấu hình Maven đưa các phần phụ thuộc vào gói dự án và để thực thi lớp chính của ứng dụng, hãy chỉnh sửa tệp pom.xml trong thư mục của dự án và thêm cấu hình sau vào thư mục Mục <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. Trong thư mục đang làm việc, hãy tạo một tệp có tên chat_app_auth.py.
  2. Đưa mã sau vào 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.
    CREDENTIALS = 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=CREDENTIALS)
    
    # 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. Trong mã, hãy thay thế SPACE_NAME bằng một dấu cách mà bạn có thể lấy từ spaces.list trong API Chat hoặc từ URL của một không gian. Hãy đảm bảo rằng tệp khoá riêng tư cho tài khoản dịch vụ của bạn có tên là credentials.json.

Node.js

  1. Trong thư mục của dự án, hãy tạo một tệp có tên chat_app_auth.js.
  2. Đưa mã sau vào 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. Trong mã, hãy thay thế SPACE_NAME bằng một dấu cách mà bạn có thể lấy từ spaces.list trong API Chat hoặc từ URL của một không gian. Hãy đảm bảo rằng tệp khoá riêng tư cho tài khoản dịch vụ của bạn có tên là credentials.json.

Apps Script

  1. Trong trình chỉnh sửa Apps Script, hãy chỉnh sửa tệp appsscript.json và thêm phạm vi OAuth cần thiết để thực hiện các yêu cầu bên ngoài nhằm lấy mã thông báo OAuth của tài khoản dịch vụ:

      "oauthScopes": [
        "https://www.googleapis.com/auth/script.external_request"
      ]
    
  2. Lưu mã sau trong tệp có tên ChatAppAuth.gs trong dự án Apps Script của bạn:

    // 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 via 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. Trong mã này, hãy thay thế CREDENTIALS bằng nội dung của tệp credentials.json.

  4. Trong mã, hãy thay thế SPACE_NAME bằng một dấu cách mà bạn có thể lấy từ spaces.list trong API Chat hoặc từ URL của một không gian.

Bước 4: Chạy ví dụ hoàn chỉnh

Trong thư mục đang làm việc, hãy tạo và chạy mẫu:

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

Mở tệp ChatAppAuth.gs trong Trình chỉnh sửa Apps Script và nhấp vào Run (Chạy).

Tập lệnh của bạn đưa ra một yêu cầu được xác thực đến API Chat để phản hồi bằng cách đăng một tin nhắn trong phòng Chat dưới dạng ứng dụng Chat.

Khắc phục sự cố cho ví dụ

Phần này mô tả các vấn đề phổ biến mà bạn có thể gặp phải khi thử để chạy mẫu này.

Bạn không được phép sử dụng ứng dụng này

Khi chạy tập lệnh, bạn có thể nhận được thông báo lỗi như sau:

<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">

Thông báo lỗi này có nghĩa là ứng dụng Chat không có quyền tạo tin nhắn trong Chat trong Phòng Chat.

Để khắc phục lỗi này, hãy thêm ứng dụng Chat vào phòng Chat được chỉ định trong tập lệnh.

Xem API Chat để tìm hiểu những việc khác mà API Chat có thể làm tài liệu tham khảo.