作为 Google Chat 应用进行身份验证

本指南介绍如何设置和使用服务账号访问 Google Chat API 代表 Chat 应用。首先, 将逐步介绍如何创建服务账号。然后,我们将演示如何 编写一个脚本,使用服务账号对 Chat 进行身份验证 API 并在 Chat 聊天室中发布消息。

在异步调用时,聊天应用可以使用服务账号进行身份验证 Google Chat API,以便他们可以:

  • 通过以下方式向 Google Chat 发送消息: spaces.messages.create 更改为:
    • 在长时间运行的后台作业完成运行时通知用户。
    • 提醒用户服务器已离线。
    • 让客户服务人员处理新开设的客户支持请求。
  • 使用以下应用更新之前发送的邮件: spaces.messages.update 更改为:
    • 更改正在进行的操作的状态。
    • 更新任务的分配对象或截止日期。
  • 列出聊天室中的用户 spaces.members.list 至:
    • 查看聊天室中的成员。
    • 确认聊天室成员包括团队中的所有成员。

使用服务账号进行身份验证时,用于获取相关数据或执行操作 在 Chat 聊天室中,Chat 应用必须具有该聊天室的成员资格。例如, 列出聊天室成员,或在聊天室中创建消息,Chat 应用必须 本身会成为聊天室成员。

如果您的 Chat 应用需要访问用户数据或对用户的 以用户身份进行身份验证

如果您是域管理员,您可以授予 全网域授权 授权应用的服务账号访问您用户的数据, 需要每位用户给予同意。配置全网域授权后, 你可以 使用您的服务账号进行 API 调用以模拟用户账号。虽然服务账号用于 全网域授权将模拟用户, 属于用户身份验证。任何需要 您可以使用全网域授权。

如需详细了解 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
    

Python

  • Python 3.6 或更高版本
  • pip 软件包管理工具

Node.js

  • Node.js
  • npm 软件包管理工具
  • 一个已初始化的 Node.js 项目。要初始化新项目,请创建 切换到新文件夹,然后在命令行界面中运行以下命令:

    npm init
    

Apps 脚本

第 1 步:在 Google Cloud 控制台中创建服务账号

创建供 Chat 应用用来执行以下操作的服务账号 访问 Google API。

创建服务账号

如需创建服务账号,请按照以下步骤操作:

Google Cloud 控制台

  1. 在 Google Cloud 控制台中,点击“菜单”图标 > IAM 和管理 > 服务账号

    转到“服务账号”

  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 控制台中,点击“菜单”图标 > IAM 和管理 > 服务账号

    转到“服务账号”

  2. 选择您的服务账号。
  3. 依次点击密钥 > 添加密钥 > 创建新密钥
  4. 选择 JSON,然后点击创建

    您的新公钥/私钥对已生成并下载到 作为新文件将下载的 JSON 文件另存为 credentials.json,位于 工作目录此文件是此密钥的唯一副本。有关如何存储 确保您的密钥安全无虞,请参阅 管理服务账号密钥

  5. 点击关闭

如需详细了解服务账号,请参阅 服务账号

第 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 脚本

此示例使用 适用于 Apps 脚本的 OAuth2 库 为服务账号身份验证生成 JWT 令牌。添加库 添加到您的 Apps 脚本项目中:

  1. 点击左侧的编辑器
  2. 在左侧的旁边,点击添加库
  3. 输入脚本 ID 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF
  4. 点击查找,然后点击添加

此示例使用 高级 Chat 服务 来调用 Google Chat API。要启用该服务,请执行以下操作: Apps 脚本项目:

  1. 点击左侧的编辑器
  2. 在左侧的服务旁边,点击添加服务
  3. 选择 Google Chat API
  4. 版本中,选择 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 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. 在代码中,将 SPACE_NAME 替换为空格 名称,您可以从 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.
    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. 在代码中,将 SPACE_NAME 替换为空格 名称,您可以从 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 替换为空格 名称,您可以从 spaces.list 获取 方法,或者通过聊天室网址添加。确保 您服务账号的私钥文件命名为 credentials.json

Apps 脚本

  1. 在 Apps 脚本编辑器中,修改文件 appsscript.json 并添加发出外部请求以获取 服务账号 OAuth 令牌:

      "oauthScopes": [
        "https://www.googleapis.com/auth/script.external_request"
      ]
    
  2. 将以下代码保存在名为 ChatAppAuth.gs 的 您的 Apps 脚本项目:

    // 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. 在代码中,将 CREDENTIALS 替换为 文件 credentials.json 中的内容。

  4. 在代码中,将 SPACE_NAME 替换为空格 名称,您可以从 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 脚本

在 Apps 脚本编辑器中打开 ChatAppAuth.gs 文件,然后 点击运行

您的脚本会向 Chat 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 API,了解 Chat API 还能做些什么 参考文档