构建 HTTP Google Chat 应用

本页介绍了如何创建 HTTP Chat 应用。 您可以通过不同的方式实现此架构。在 Google Cloud 上 可以使用 Cloud Functions、Cloud Run 和 App Engine。在本快速入门中,您将 编写和部署 Cloud Functions 函数 Chat 应用用来回复用户消息的 ID。

通过这种架构,您可以配置 Chat,使其 使用 HTTP 连接到 Google Cloud 或本地服务器,如 如下图所示:

在本地服务器中使用 Web 服务的 Chat 应用的架构。

在上图中,用户与 HTTP Chat 应用具有以下信息流:

  1. 用户在 Chat 中向 聊天应用(可通过私信或 Chat 聊天室。
  2. HTTP 请求被发送到网络服务器,该服务器可以是云或 包含 Chat 应用的本地系统 逻辑。
  3. (可选)Chat 应用逻辑可以与 Google Workspace 服务(例如 Google 日历和 Google 表格)、其他 Google 服务 (如地图、YouTube 和 Vertex AI)或其他网络服务(如项目 管理系统或工单工具)。
  4. Web 服务器会将 HTTP 响应发回给 Chat 中的 Chat 应用服务。
  5. 系统将响应传送给用户。
  6. (可选)Chat 应用可以调用 用于异步发布消息或执行其他任务的 操作。

此架构可让您灵活地使用现有库和 这类组件 聊天应用可采用不同的编程语言进行设计。

目标

  • 设置环境。
  • 创建和部署 Cloud Functions 函数。
  • 将应用发布到 Chat。
  • 测试应用。

前提条件

设置环境

在使用 Google API 之前,您需要先在 Google Cloud 项目中启用这些 API。 您可以在单个 Google Cloud 项目中启用一个或多个 API。
  • 在 Google Cloud 控制台中,启用 Google Chat API、Cloud Build API、Cloud Functions API。 Cloud Pub/Sub API、Cloud Logging API、Artifact Registry API 和 Cloud Run API。

    启用 API

创建和部署 Cloud Functions 函数

创建和部署 Cloud Functions 函数以生成聊天卡片 替换为发件人的显示名称和头像图片。当 聊天应用收到一条消息,运行该函数并 用卡片进行响应

如需为您的 Chat 应用创建和部署该函数, 请完成以下步骤:

Node.js

  1. 在 Google Cloud 控制台中,转到 Cloud Functions 页面:

    转到 Cloud Functions

    确保 Chat 应用的项目是 已选择。

  2. 点击 创建函数

  3. 在“创建函数”页面上,设置您的函数:

    1. 环境中,选择第 2 代
    2. 函数名称中,输入 QuickStartChatApp
    3. 区域中,选择一个区域。
    4. 在“身份验证”下,选择需要身份验证
    5. 点击下一步
  4. 运行时中,选择最新版本的 Node.js。

  5. 源代码中,选择内嵌编辑器

  6. 入口点中,删除默认文本并输入 avatarApp

  7. index.js 的内容替换为以下代码:

    node/avatar-app/index.js
    // The ID of the slash command "/about".
    // It's not enabled by default, set to the actual ID to enable it. You need to
    // use the same ID as set in the Google Chat API configuration.
    const ABOUT_COMMAND_ID = "";
    
    /**
     * Google Cloud Function that responds to messages sent from a
     * Google Chat space.
     *
     * @param {Object} req Request sent from Google Chat space
     * @param {Object} res Response to send back
     */
    exports.avatarApp = function avatarApp(req, res) {
      if (req.method === 'GET' || !req.body.message) {
        return res.send('Hello! This function is meant to be used ' +
          'in a Google Chat Space.');
      }
    
      // Stores the Google Chat event as a variable.
      const event = req.body;
    
      // Checks for the presence of a slash command in the message.
      if (event.message.slashCommand) {
        // Executes the slash command logic based on its ID.
        // Slash command IDs are set in the Google Chat API configuration.
        switch (event.message.slashCommand.commandId) {
          case ABOUT_COMMAND_ID:
            return res.send({
              privateMessageViewer: event.user,
              text: 'The Avatar app replies to Google Chat messages.'
            });
        }
      }
    
      const sender = req.body.message.sender.displayName;
      const image = req.body.message.sender.avatarUrl;
      const data = createMessage(sender, image);
      res.send(data);
    };
    
    /**
     * Creates a card with two widgets.
     * 
     * @param {string} displayName the sender's display name
     * @param {string} avatarUrl the URL for the sender's avatar
     * @return {Object} a card with the user's avatar.
     */
    function createMessage(displayName, avatarUrl) {
      return {
        text: 'Here\'s your avatar',
        cardsV2: [{
          cardId: 'avatarCard',
          card: {
            name: 'Avatar Card',
            header: {
              title: `Hello ${displayName}!`,
            },
            sections: [{ widgets: [{
              textParagraph: { text: 'Your avatar picture: ' }
            }, {
              image: { imageUrl: avatarUrl }
            }]}]
          }
        }]
      };
    }

  8. 点击部署

Python

  1. 在 Google Cloud 控制台中,转到 Cloud Functions 页面:

    转到 Cloud Functions

    确保 Chat 应用的项目是 已选择。

  2. 点击 创建函数

  3. 在“创建函数”页面上,设置您的函数:

    1. 环境中,选择第 2 代
    2. 函数名称中,输入 QuickStartChatApp
    3. 区域中,选择一个区域。
    4. 在“身份验证”下,选择需要身份验证
    5. 点击下一步
  4. 运行时中,选择最新版本的 Python。

  5. 源代码中,选择内嵌编辑器

  6. 入口点中,删除默认文本并输入 avatar_app

  7. main.py 的内容替换为以下代码:

    python/avatar-app/main.py
    from typing import Any, Mapping
    
    import flask
    import functions_framework
    
    # The ID of the slash command "/about".
    # It's not enabled by default, set to the actual ID to enable it. You need to
    # use the same ID as set in the Google Chat API configuration.
    ABOUT_COMMAND_ID = ""
    
    @functions_framework.http
    def avatar_app(req: flask.Request) -> Mapping[str, Any]:
      """Google Cloud Function that handles requests from Google Chat
    
      Args:
          flask.Request: the request
    
      Returns:
          Mapping[str, Any]: the response
      """
      if req.method == "GET":
        return "Hello! This function must be called from Google Chat."
    
      request_json = req.get_json(silent=True)
    
      # Checks for the presence of a slash command in the message.
      if "slashCommand" in request_json["message"]:
        # Executes the slash command logic based on its ID.
        # Slash command IDs are set in the Google Chat API configuration.
        if request_json["message"]["slashCommand"]["commandId"] == ABOUT_COMMAND_ID:
          return {
            "privateMessageViewer": request_json["user"],
            "text": 'The Avatar app replies to Google Chat messages.'
          }
    
      display_name = request_json["message"]["sender"]["displayName"]
      avatar = request_json["message"]["sender"]["avatarUrl"]
      response = create_message(name=display_name, image_url=avatar)
      return response
    
    
    def create_message(name: str, image_url: str) -> Mapping[str, Any]:
      """Google Cloud Function that handles requests from Google Chat
    
      Args:
          str name: the sender's display name.
          str image_url: the URL for the sender's avatar.
    
      Returns:
          Mapping[str, Any]: a card with the user's avatar.
      """
      return {
        "text": "Here's your avatar",
        "cardsV2": [{
          "cardId": "avatarCard",
          "card": {
              "name": "Avatar Card",
              "header": { "title": f"Hello {name}!" },
              "sections": [{
                "widgets": [{
                  "textParagraph": { "text": "Your avatar picture:" }
                }, {
                  "image": { "imageUrl": image_url }
                }]
              }]
          }
        }]
      }

  8. 点击部署

Java

  1. 在 Google Cloud 控制台中,转到 Cloud Functions 页面:

    转到 Cloud Functions

    确保 Chat 应用的项目是 已选择。

  2. 点击 创建函数

  3. 在“创建函数”页面上,设置您的函数:

    1. 环境中,选择第 2 代
    2. 函数名称中,输入 QuickStartChatApp
    3. 区域中,选择一个区域。
    4. 在“身份验证”下,选择需要身份验证
    5. 点击下一步
  4. 运行时中,选择最新版本的 Java。

  5. 源代码中,选择内嵌编辑器

  6. 入口点中,删除默认文本并输入 App

  7. src/main/java/com/example/Example.java 改名为 src/main/java/App.java

  8. App.java 的内容替换为以下代码:

    java/avatar-app/src/main/java/App.java
    import java.util.List;
    
    import com.google.api.services.chat.v1.model.CardWithId;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1Card;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1CardHeader;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1Image;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1Section;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1TextParagraph;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1Widget;
    import com.google.api.services.chat.v1.model.Message;
    import com.google.cloud.functions.HttpFunction;
    import com.google.cloud.functions.HttpRequest;
    import com.google.cloud.functions.HttpResponse;
    import com.google.gson.Gson;
    import com.google.gson.JsonObject;
    
    public class App implements HttpFunction {
      private static final Gson gson = new Gson();
    
      // The ID of the slash command "/about".
      // It's not enabled by default, set to the actual ID to enable it. You need to
      // use the same ID as set in the Google Chat API configuration.
      private static final String ABOUT_COMMAND_ID = "";
    
      @Override
      public void service(HttpRequest request, HttpResponse response) throws Exception {
        JsonObject body = gson.fromJson(request.getReader(), JsonObject.class);
    
        if (request.getMethod().equals("GET") || !body.has("message")) {
          response.getWriter().write("Hello! This function must be called from Google Chat.");
          return;
        }
    
        // Checks for the presence of a slash command in the message.
        if (body.getAsJsonObject("message").has("slashCommand")) {
          // Executes the slash command logic based on its ID.
          // Slash command IDs are set in the Google Chat API configuration.
          JsonObject slashCommand = body.getAsJsonObject("message").getAsJsonObject("slashCommand");
          switch (slashCommand.get("commandId").getAsString()) {
            case ABOUT_COMMAND_ID:
            JsonObject aboutMessage = new JsonObject();
            aboutMessage.addProperty("text", "The Avatar app replies to Google Chat messages.");
            aboutMessage.add("privateMessageViewer", body.getAsJsonObject("user"));
              response.getWriter().write(gson.toJson(aboutMessage));
              return;
          }
        }
    
        JsonObject sender = body.getAsJsonObject("message").getAsJsonObject("sender");
        String displayName = sender.has("displayName") ? sender.get("displayName").getAsString() : "";
        String avatarUrl = sender.has("avatarUrl") ? sender.get("avatarUrl").getAsString() : "";
        Message message = createMessage(displayName, avatarUrl);
        response.getWriter().write(gson.toJson(message));
      }
    
      Message createMessage(String displayName, String avatarUrl) {
        GoogleAppsCardV1CardHeader cardHeader = new GoogleAppsCardV1CardHeader();
        cardHeader.setTitle(String.format("Hello %s!", displayName));
    
        GoogleAppsCardV1TextParagraph textParagraph = new GoogleAppsCardV1TextParagraph();
        textParagraph.setText("Your avatar picture: ");
    
        GoogleAppsCardV1Widget avatarWidget = new GoogleAppsCardV1Widget();
        avatarWidget.setTextParagraph(textParagraph);
    
        GoogleAppsCardV1Image image = new GoogleAppsCardV1Image();
        image.setImageUrl(avatarUrl);
    
        GoogleAppsCardV1Widget avatarImageWidget = new GoogleAppsCardV1Widget();
        avatarImageWidget.setImage(image);
    
        GoogleAppsCardV1Section section = new GoogleAppsCardV1Section();
        section.setWidgets(List.of(avatarWidget, avatarImageWidget));
    
        GoogleAppsCardV1Card card = new GoogleAppsCardV1Card();
        card.setName("Avatar Card");
        card.setHeader(cardHeader);
        card.setSections(List.of(section));
    
        CardWithId cardWithId = new CardWithId();
        cardWithId.setCardId("previewLink");
        cardWithId.setCard(card);
    
        Message message = new Message();
        message.setText("Here's your avatar");
        message.setCardsV2(List.of(cardWithId));
    
        return message;
      }
    }

  9. pom.xml 的内容替换为以下代码:

    java/avatar-app/pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.google.chat</groupId>
      <artifactId>avatar-app</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <properties>
        <maven.compiler.target>17</maven.compiler.target>
        <maven.compiler.source>17</maven.compiler.source>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>com.google.cloud.functions</groupId>
          <artifactId>functions-framework-api</artifactId>
          <version>1.0.1</version>
        </dependency>
    
        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.1</version>
        </dependency>
    
        <!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-chat -->
        <dependency>
          <groupId>com.google.apis</groupId>
          <artifactId>google-api-services-chat</artifactId>
          <version>v1-rev20230115-2.0.0</version>
        </dependency>
      </dependencies>
    
      <!-- Required for Java 11 functions in the inline editor -->
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
              <excludes>
                <exclude>.google/</exclude>
              </excludes>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>

  10. 点击部署

Cloud Functions 详情页面随即打开,您的函数会显示两个 进度指示器:一个用于构建,一个用于服务。如果 进度指示器消失,取而代之的是复选标记,您的函数 部署完成并准备就绪

授权 Google Chat 调用您的函数

如需授权 Google Chat 调用您的函数,请添加 Google Chat 具有 Cloud Run Invoker 角色的服务账号。

  1. 在 Google Cloud 控制台中,转到 Cloud Run 页面。

    转到 Cloud Run

  2. 在 Cloud Run 服务列表中,选中接收消息旁边的复选框 函数。(请勿点击函数本身。)

  3. 点击权限权限面板随即会打开。

  4. 点击添加主账号

  5. 新主账号中,输入 chat@system.gserviceaccount.com

  6. 选择角色中,选择 Cloud Run >Cloud Run Invoker

  7. 点击保存

将应用发布到 Google Chat

部署 Cloud Functions 函数后,请按照以下步骤将其转换为 Google Chat 应用:

  1. 在 Google Cloud 控制台中,点击“菜单” &gt; Cloud Functions

    转到 Cloud Functions

    请确保您启用了 Cloud Functions 的项目已 已选择。

  2. 在函数列表中,点击 QuickStartChatApp

  3. 点击触发器标签页。

  4. HTTPS 下,复制网址。

  5. 搜索“Google Chat API”依次点击 Google Chat API管理

    前往 Chat API

  6. 点击配置并设置 Google Chat 应用:

    1. 应用名称中,输入 Quickstart App
    2. 头像网址中,输入 https://developers.google.com/chat/images/quickstart-app-avatar.png
    3. 说明中,输入 Quickstart app
    4. 功能下,选择接收 1 对 1 消息,然后 加入聊天室和群组对话
    5. 连接设置下,选择应用网址,然后粘贴 Cloud Functions 函数触发器。
    6. Authentication Audience(身份验证受众群体)中,选择 App 网址(应用网址)。
    7. 公开范围下,选择 将此 Google Chat 应用提供给特定人员并 群组,然后输入您的电子邮件地址。
    8. 日志下,选择将错误记录到 Logging
  7. 点击保存

Chat 应用现在可以接收和回复了 Chat 中的消息。

测试您的 Chat 应用

如需测试您的 Chat 应用,请使用如下应用打开私信聊天室: Chat 应用并发送消息:

  1. 使用您用于登录的 Google Workspace 账号打开 Google Chat 在您添加为可信测试员时提供的凭据。

    前往 Google Chat

  2. 点击 发起新对话
  3. 添加一人或多人字段中,输入 Chat 应用。
  4. 从结果中选择您的 Chat 应用。直接客户 消息会打开。

  5. 在与该应用的新私信对话中,输入“Hello”,然后按 enter

Chat 应用的响应包含 卡片消息,其中显示了 发件人的姓名和头像图片,如下图所示:

Chat 应用以一张卡片的形式回应,卡片上显示了发送者的显示名称和头像
映像

如需添加可信测试员,并详细了解如何测试互动功能,请参阅 测试适用于以下应用的互动功能: Google Chat 应用

问题排查

当 Google Chat 应用或 card 会返回错误, 聊天界面会显示一条内容为“出了点问题”的消息。 或“无法处理您的请求”。有时,Chat 界面 不会显示任何错误消息,但 Chat 应用或 卡片会产生意外结果;例如,卡片消息 。

虽然 Chat 界面中可能不会显示错误消息, 提供描述性错误消息和日志数据,以帮助您修正错误 启用 Chat 应用的错误日志记录时。如需观看方面的帮助, 请参阅 排查并修正 Google Chat 错误

清理

为避免系统因 我们建议您删除 Cloud 项目中。

  1. 在 Google Cloud 控制台中,前往管理资源页面。点击 菜单 &gt; IAM 和管理员 &gt; 管理资源

    <ph type="x-smartling-placeholder"></ph> 前往 Resource Manager

  2. 在项目列表中,选择要删除的项目,然后点击 删除
  3. 在对话框中输入项目 ID,然后点击关停以删除项目 项目。