建構 HTTP Google Chat 應用程式

本頁說明如何使用 Google Cloud 服務建構 HTTP Google Chat 應用程式。如要建構 Chat 應用程式,請編寫並部署 Cloud Run 函式,供 Chat 應用程式用來回覆使用者訊息。

在 HTTP 架構中,您可以設定 Chat 透過 HTTP 與 Google Cloud 或地端伺服器整合,如下圖所示:

使用地端部署伺服器中的 Web 服務,建構 Chat 應用程式的架構。

在上圖中,使用者與 HTTP Chat 應用程式互動時,資訊流程如下:

  1. 使用者在 Chat 中傳送訊息給 Chat 應用程式,無論是透過即時訊息或 Chat 聊天室。
  2. HTTP 要求會傳送至網路伺服器,該伺服器是雲端或地端部署系統,內含 Chat 應用程式邏輯。
  3. 視需要,Chat 應用程式邏輯可與 Google Workspace 服務 (例如 Google 日曆和 Google 試算表)、其他 Google 服務 (例如 Google 地圖、YouTube 和 Vertex AI),或其他網路服務 (例如專案管理系統或票證工具) 整合。
  4. 網頁伺服器會將 HTTP 回應傳回 Chat 中的 Chat 擴充應用程式服務。
  5. 並將回覆傳送給使用者。
  6. Chat 應用程式也可以選擇呼叫 Chat API,以非同步方式發布訊息或執行其他作業。

由於這些 Chat 應用程式可使用不同的程式設計語言設計,因此您能彈性運用系統中現有的程式庫和元件。

目標

  • 設定環境。
  • 建立及部署 Cloud Run 函式。
  • 設定 Chat 應用程式。
  • 測試應用程式。

必要條件

設定環境

使用 Google API 前,您需要在 Google Cloud 專案中啟用這些 API。 您可以在單一 Google Cloud 專案中啟用一或多個 API。
  • 在 Google API 控制台中,啟用 Google Chat API、Cloud Build API、Cloud Functions API、Cloud Pub/Sub API、Cloud Logging API、Artifact Registry API 和 Cloud Run API。

    啟用 API

建立及部署 Cloud Run 函式

建立並部署 Cloud Run 函式,產生含有傳送者顯示名稱和個人資料相片的 Chat 資訊卡。當 Chat 應用程式收到訊息時,會執行函式並以資訊卡回覆。

如要為 Chat 應用程式建立及部署函式,請完成下列步驟:

Node.js

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

    請確認已選取 Chat 應用程式的專案。

  2. 按一下「編寫函式」。

  3. 在「建立服務」頁面中設定函式:

    1. 在「Service name」(服務名稱) 欄位中輸入 addonchatapp。
    2. 在「Region」(區域) 清單中選取區域。
    3. 在「執行階段」清單中,選取最新版的 Node.js。
    4. 在「驗證」部分,選取「需要驗證」。
    5. 按一下「建立」,然後等待 Cloud Run 建立服務。 控制台會將您重新導向至「來源」分頁。
  4. 在「來源」分頁中:

    1. 在「Entry point」(進入點) 中,刪除預設文字並輸入 avatarApp。
    2. 將 index.js 的內容替換為下列程式碼:
    node/chat/avatar-app/index.js
    import { http } from '@google-cloud/functions-framework';
    
    // The ID of the slash command "/about".
    // You must use the same ID in the Google Chat API configuration.
    const ABOUT_COMMAND_ID = 1;
    
    /**
     * Handle requests from Google Workspace add on
     *
     * @param {Object} req Request sent by Google Chat
     * @param {Object} res Response to be sent back to Google Chat
     */
    http('avatarApp', (req, res) => {
      const chatEvent = req.body.chat;
      let message;
      if (chatEvent.appCommandPayload) {
        message = handleAppCommand(chatEvent);
      } else {
        message = handleMessage(chatEvent);
      }
      res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: {
        message: message
      }}}});
    });
    
    /**
     * Responds to an APP_COMMAND event in Google Chat.
     *
     * @param {Object} event the event object from Google Chat
     * @return the response message object.
     */
    function handleAppCommand(event) {
      switch (event.appCommandPayload.appCommandMetadata.appCommandId) {
        case ABOUT_COMMAND_ID:
          return {
            text: 'The Avatar app replies to Google Chat messages.'
          };
      }
    }
    
    /**
     * Responds to a MESSAGE event in Google Chat.
     *
     * @param {Object} event the event object from Google Chat
     * @return the response message object.
     */
    function handleMessage(event) {
      // Stores the Google Chat user as a variable.
      const chatUser = event.messagePayload.message.sender;
      const displayName = chatUser.displayName;
      const avatarUrl = chatUser.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 }
            }]}]
          }
        }]
      };
    }
    1. 按一下「儲存並重新部署」。

Python

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

    確認已選取 Chat 應用程式的專案。

  2. 按一下「編寫函式」。

  3. 在「建立服務」頁面中設定函式:

    1. 在「Service name」(服務名稱) 欄位中輸入 addonchatapp。
    2. 在「Region」(區域) 清單中選取區域。
    3. 在「Runtime」(執行階段) 清單中,選取最新版本的 Python。
    4. 在「驗證」部分,選取「需要驗證」。
    5. 按一下「建立」,然後等待 Cloud Run 建立服務。 控制台會將您重新導向至「來源」分頁。
  4. 在「來源」分頁中:

    1. 在「Entry point」(進入點) 中,刪除預設文字並輸入 avatar_app。
    2. 將 main.py 的內容替換為下列程式碼:
    python/chat/avatar-app/main.py
    from typing import Any, Mapping
    
    import flask
    import functions_framework
    
    # The ID of the slash command "/about".
    # You must use the same ID in the Google Chat API configuration.
    ABOUT_COMMAND_ID = 1
    
    @functions_framework.http
    def avatar_app(req: flask.Request) -> Mapping[str, Any]:
      """Handle requests from Google Workspace add on
    
      Args:
        flask.Request req: the request sent by Google Chat
    
      Returns:
        Mapping[str, Any]: the response to be sent back to Google Chat
      """
      chat_event = req.get_json(silent=True)["chat"]
      if chat_event and "appCommandPayload" in chat_event:
        message = handle_app_command(chat_event)
      else:
        message = handle_message(chat_event)
      return { "hostAppDataAction": { "chatDataAction": { "createMessageAction": {
          "message": message
      }}}}
    
    def handle_app_command(event: Mapping[str, Any]) -> Mapping[str, Any]:
      """Responds to an APP_COMMAND event in Google Chat.
    
      Args:
        Mapping[str, Any] event: the event object from Google Chat
    
      Returns:
        Mapping[str, Any]: the response message object.
      """
      if event["appCommandPayload"]["appCommandMetadata"]["appCommandId"] == ABOUT_COMMAND_ID:
        return {
          "text": "The Avatar app replies to Google Chat messages.",
        }
      return {}
    
    def handle_message(event: Mapping[str, Any]) -> Mapping[str, Any]:
      """Responds to a MESSAGE event in Google Chat.
    
      Args:
        Mapping[str, Any] event: the event object from Google Chat
    
      Returns:
        Mapping[str, Any]: the response message object.
      """
      # Stores the Google Chat user as a variable.
      chat_user = event["messagePayload"]["message"]["sender"]
      display_name = chat_user.get("displayName", "")
      avatar_url = chat_user.get("avatarUrl", "")
      return {
        "text": "Here's your avatar",
        "cardsV2": [{
          "cardId": "avatarCard",
          "card": {
            "name": "Avatar Card",
            "header": {
              "title": f"Hello {display_name}!"
            },
            "sections": [{ "widgets": [
              { "textParagraph": { "text": "Your avatar picture:" }},
              { "image": { "imageUrl": avatar_url }},
            ]}]
          }
        }]
      }
    1. 按一下「儲存並重新部署」。

Java

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

    確認已選取 Chat 應用程式的專案。

  2. 按一下「編寫函式」。

  3. 在「建立服務」頁面中設定函式:

    1. 在「Service name」(服務名稱) 欄位中輸入 addonchatapp。
    2. 在「Region」(區域) 清單中選取區域。
    3. 在「執行階段」清單中,選取最新版本的 Java。
    4. 在「驗證」部分,選取「需要驗證」。
    5. 按一下「建立」,然後等待 Cloud Run 建立服務。 控制台會將您重新導向至「來源」分頁。
  4. 在「來源」分頁中:

    1. 在「Entry point」(進入點) 中,刪除預設文字並輸入 App。
    2. 將預設 Java 檔案重新命名為 src/main/java/com/google/chat/avatar/App.java。
    3. 將 App.java 的內容替換為下列程式碼:
    java/chat/avatar-app/src/main/java/com/google/chat/avatar/App.java
    package com.google.chat.avatar;
    
    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;
    import java.util.List;
    
    public class App implements HttpFunction {
      // The ID of the slash command "/about".
      // You must use the same ID in the Google Chat API configuration.
      private static final int ABOUT_COMMAND_ID = 1;
    
      private static final Gson gson = new Gson();
    
      /**
       * Handle requests from Google Workspace add on
       * 
       * @param request the request sent by Google Chat
       * @param response the response to be sent back to Google Chat
       */
      @Override
      public void service(HttpRequest request, HttpResponse response) throws Exception {
        JsonObject event = gson.fromJson(request.getReader(), JsonObject.class);
        JsonObject chatEvent = event.getAsJsonObject("chat");
        Message message;
        if (chatEvent.has("appCommandPayload")) {
          message = handleAppCommand(chatEvent);
        } else {
          message = handleMessage(chatEvent);
        }
        JsonObject createMessageAction = new JsonObject();
        createMessageAction.add("message", gson.fromJson(gson.toJson(message), JsonObject.class));
        JsonObject chatDataAction = new JsonObject();
        chatDataAction.add("createMessageAction", createMessageAction);
        JsonObject hostAppDataAction = new JsonObject();
        hostAppDataAction.add("chatDataAction", chatDataAction);
        JsonObject dataActions = new JsonObject();
        dataActions.add("hostAppDataAction", hostAppDataAction);
        response.getWriter().write(gson.toJson(dataActions));
      }
    
      /**
       * Handles an APP_COMMAND event in Google Chat.
       *
       * @param event the event object from Google Chat
       * @return the response message object.
       */
      private Message handleAppCommand(JsonObject event) throws Exception {
        switch (event.getAsJsonObject("appCommandPayload")
          .getAsJsonObject("appCommandMetadata").get("appCommandId").getAsInt()) {
          case ABOUT_COMMAND_ID:
            return new Message()
              .setText("The Avatar app replies to Google Chat messages.");
          default:
            return null;
        }
      }
    
      /**
       * Handles a MESSAGE event in Google Chat.
       *
       * @param event the event object from Google Chat
       * @return the response message object.
       */
      private Message handleMessage(JsonObject event) throws Exception {
        // Stores the Google Chat user as a variable.
        JsonObject chatUser = event.getAsJsonObject("messagePayload").getAsJsonObject("message").getAsJsonObject("sender");
        String displayName = chatUser.has("displayName") ? chatUser.get("displayName").getAsString() : "";
        String avatarUrl = chatUser.has("avatarUrl") ? chatUser.get("avatarUrl").getAsString() : "";
        return new Message()
          .setText("Here's your avatar")
          .setCardsV2(List.of(new CardWithId()
            .setCardId("avatarCard")
            .setCard(new GoogleAppsCardV1Card()
              .setName("Avatar Card")
              .setHeader(new GoogleAppsCardV1CardHeader()
                .setTitle(String.format("Hello %s!", displayName)))
              .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(
                new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
                  .setText("Your avatar picture:")),
                new GoogleAppsCardV1Widget()
                  .setImage(new GoogleAppsCardV1Image().setImageUrl(avatarUrl)))))))));
      }
    }
  5. 將 pom.xml 的內容替換為下列程式碼:

    java/chat/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.1.4</version>
        </dependency>
        <dependency>
          <groupId>com.google.code.gson</groupId>
          <artifactId>gson</artifactId>
          <version>2.9.1</version>
        </dependency>
        <dependency>
          <groupId>com.google.apis</groupId>
          <artifactId>google-api-services-chat</artifactId>
          <version>v1-rev20230115-2.0.0</version>
        </dependency>
      </dependencies>
    
      <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>
    1. 按一下「儲存並重新部署」。

Cloud Run 服務詳細資料頁面隨即開啟。等待函式部署完成。

設定 Chat 應用程式

部署 Cloud Run 函式後,請按照下列步驟設定及部署 Google Chat 應用程式:

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

    請確保選取的是已啟用 Cloud Run 的專案。

  2. 在函式清單中,按一下「addonchatapp」addonchatapp。

  3. 在「服務詳細資料」頁面,複製函式的「網址」。網址結尾為 run.app。

  4. 在 Google Cloud 搜尋欄位中搜尋「Google Chat API」,然後點選「Google Chat API」,再點選「管理」。

    前往 Chat API

  5. 按一下「設定」,然後設定 Google Chat 應用程式:

    1. 在「應用程式名稱」中輸入 Quickstart App。
    2. 在「顯示圖片網址」中輸入 https://developers.google.com/workspace/chat/images/quickstart-app-avatar.png。
    3. 在「Description」(說明) 中輸入 Quickstart app。
    4. 在「功能」下方,選取「加入聊天室和群組對話」。
    5. 在「連線設定」下方,選取「HTTP 端點網址」。
    6. 在「觸發條件」下方,選取「為所有觸發條件使用通用的 HTTP 端點網址」,然後將 Cloud Run 函式觸發條件的網址貼到方塊中。
    7. 在「可見度」下方,選取「將這個 Google Chat 應用程式提供給網域中的特定使用者和群組」,然後輸入電子郵件地址。
    8. 在「記錄」下方,選取「將錯誤記錄至 Logging」。
  6. 按一下 [儲存]。

  7. 在「連線設定」下方,複製「服務帳戶電子郵件」。授權 Chat 應用程式叫用函式時,您需要這封電子郵件。

接著,授權 Chat 應用程式叫用 Cloud Run 函式。

授權 Google Chat 叫用函式

如要授權 Google Chat 叫用函式,請新增具有 Cloud Run 叫用者角色的 Chat 應用程式服務帳戶。

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

  2. 在 Cloud Run 服務清單中,選取接收函式旁的核取方塊。(請勿點選函式本身)。

  3. 按一下 [權限],「權限」面板隨即開啟。

  4. 按一下「Add principal」(新增主體)。

  5. 在「新增主體」中,輸入與 Chat 應用程式相關聯的服務帳戶電子郵件地址。

    服務帳戶電子郵件地址位於 Chat API 設定頁面,依序點選「連線設定」 >「HTTP 端點網址」 >「服務帳戶電子郵件地址」:

    前往 Chat API 設定

  6. 在「請選擇角色」部分,依序選取「Cloud Run」 >「Cloud Run Invoker」。

  7. 按一下 [儲存]。

Chat 應用程式已準備好接收及回覆 Chat 訊息。

測試 Chat 應用程式

如要測試 Chat 應用程式,請開啟與 Chat 應用程式互傳的即時訊息聊天室,然後傳送訊息:

  1. 使用您在新增為早鳥測試者時提供的 Google Workspace 帳戶,開啟 Google Chat。

    前往 Google Chat

  2. 按一下 「發起新即時通訊」。
  3. 在「新增 1 位以上使用者」欄位中,輸入 Chat 應用程式的名稱。
  4. 從結果中選取 Chat 應用程式。系統會開啟即時訊息。

  5. 在與應用程式互傳的新即時訊息中,輸入 Hello 並按下 enter。

Chat 應用程式的訊息包含顯示傳送者名稱和個人資料相片的資訊卡,如下圖所示:

Chat 應用程式會回覆一張資訊卡,顯示傳送者的顯示名稱和虛擬人像圖片

如要新增早鳥測試者,並進一步瞭解如何測試互動式功能,請參閱「測試 Google Chat 應用程式的互動式功能」。

疑難排解

如果 Google Chat 應用程式或資訊卡傳回錯誤,Chat 介面會顯示「發生錯誤」訊息。或「無法處理您的要求。」有時 Chat UI 不會顯示任何錯誤訊息,但 Chat 應用程式或資訊卡會產生非預期結果,例如資訊卡訊息可能不會顯示。

即使 Chat 使用者介面可能不會顯示錯誤訊息,但只要開啟 Chat 應用程式的錯誤記錄功能,就能取得說明性錯誤訊息和記錄資料,協助修正錯誤。如需查看、偵錯及修正錯誤的相關協助,請參閱「排解及修正 Google Chat 錯誤」。

清除所用資源

為避免系統向您的 Google Cloud 帳戶收取本教學課程所用資源的費用,建議您刪除雲端專案。

  1. 在 Google API 控制台中,前往「管理資源」頁面。依序點選「選單」圖示 >「IAM 與管理」>「管理資源」。

    前往 Resource Manager

  2. 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除) 。
  3. 在對話方塊中輸入專案 ID,然後按一下「Shut down」(關閉) 即可刪除專案。

非外掛程式的 Chat 應用程式:建構 HTTP Google Chat 應用程式

如要建構非 Google Workspace 外掛程式的 Chat 擴充應用程式,請按照下列步驟部署 Cloud Run 函式、授予叫用權限,並設定非外掛程式的 Chat 擴充應用程式。

為非外掛程式的 Chat 應用程式建立及部署 Cloud Run 函式

Node.js

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

    確認已選取 Chat 應用程式的專案。

  2. 按一下「編寫函式」。

  3. 在「建立服務」頁面中設定函式:

    1. 在「Service name」(服務名稱) 欄位中輸入 quickstartchatapp。
    2. 在「Region」(區域) 清單中選取區域。
    3. 在「執行階段」清單中,選取最新版的 Node.js。
    4. 在「驗證」部分,選取「需要驗證」。
    5. 按一下「建立」,然後等待 Cloud Run 建立服務。 控制台會將您重新導向至「來源」分頁。
  4. 在「來源」分頁中:

    1. 在「Entry point」(進入點) 中,刪除預設文字並輸入 avatarApp。
    2. 將 index.js 的內容替換為下列程式碼:

      node/avatar-app/index.js
      const functions = require('@google-cloud/functions-framework');
      
      // Command IDs (configure these in Google Chat API)
      const ABOUT_COMMAND_ID = 1; // ID for the "/about" slash command
      const HELP_COMMAND_ID = 2; // ID for the "Help" quick command
      
      /**
       * Google Cloud Function that handles HTTP requests from Google Chat.
       *
       * @param {Object} req - The HTTP request object sent from Google Chat.
       * @param {Object} res - The HTTP response object.
       */
      functions.http('avatarApp', (req, res) => {
        const event = req.body;
      
        if (event.appCommandMetadata) {
          handleAppCommands(event, res);
        } else {
          handleRegularMessage(event, res);
        }
      });
      
      /**
       * Handles slash and quick commands.
       *
       * @param {Object} event - The Google Chat event.
       * @param {Object} res - The HTTP response object.
       */
      function handleAppCommands(event, res) {
        const {appCommandId, appCommandType} = event.appCommandMetadata;
      
        switch (appCommandId) {
          case ABOUT_COMMAND_ID:
            return res.send({
              privateMessageViewer: event.user,
              text: 'The Avatar app replies to Google Chat messages.'
            });
          case HELP_COMMAND_ID:
            return res.send({
              privateMessageViewer: event.user,
              text: 'The Avatar app replies to Google Chat messages.'
            });
        }
      }
      
      /**
       * Handles regular messages (not commands).
       *
       * @param {Object} event - The Google Chat event.
       * @param {Object} res - The HTTP response object.
       */
      function handleRegularMessage(event, res) {
        const messageData = createMessage(event.user);
        res.send(messageData);
      }
      
      /**
       * Creates a card message with the user's avatar.
       *
       * @param {Object} user - The user who sent the message.
       * @param {string} user.displayName - The user's display name.
       * @param {string} user.avatarUrl - The URL of the user's avatar.
       * @return {Object} - The card message object.
       */
      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}},
                ],
              }],
            },
          }],
        };
      }

    3. 按一下「儲存並重新部署」。

Python

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

    確認已選取 Chat 應用程式的專案。

  2. 按一下「編寫函式」。

  3. 在「建立服務」頁面中設定函式:

    1. 在「Service name」(服務名稱) 欄位中輸入 quickstartchatapp。
    2. 在「Region」(區域) 清單中選取區域。
    3. 在「Runtime」(執行階段) 清單中,選取最新版本的 Python。
    4. 在「驗證」部分,選取「需要驗證」。
    5. 按一下「建立」,然後等待 Cloud Run 建立服務。 控制台會將您重新導向至「來源」分頁。
  4. 在「來源」分頁中:

    1. 在「Entry point」(進入點) 中,刪除預設文字並輸入 avatar_app。
    2. 將 main.py 的內容替換為下列程式碼:

      python/avatar-app/main.py
      from typing import Any, Mapping
      
      import flask
      import functions_framework
      
      # Command IDs (configure these in Google Chat API)
      ABOUT_COMMAND_ID = 1  # ID for the "/about" slash command
      HELP_COMMAND_ID = 2  # ID for the "Help" quick command
      
      
      @functions_framework.http
      def avatar_app(req: flask.Request) -> Mapping[str, Any]:
          """Google Cloud Function that handles HTTP requests from Google Chat.
      
          Args:
              flask.Request: the request
      
          Returns:
              Mapping[str, Any]: the response
          """
          event = req.get_json(silent=True)
      
          if event and "appCommandMetadata" in event:
              return handle_app_commands(event)
          else:
              return handle_regular_message(event)
      
      
      def handle_app_commands(event: Mapping[str, Any]) -> Mapping[str, Any]:
          """Handles slash and quick commands.
      
          Args:
              Mapping[str, Any] event: The Google Chat event.
      
          Returns:
              Mapping[str, Any]: the response
          """
          app_command_id = event["appCommandMetadata"]["appCommandId"]
      
          if app_command_id == ABOUT_COMMAND_ID:
              return {
                  "privateMessageViewer": event["user"],
                  "text": "The Avatar app replies to Google Chat messages.",
              }
          elif app_command_id == HELP_COMMAND_ID:
              return {
                  "privateMessageViewer": event["user"],
                  "text": "The Avatar app replies to Google Chat messages.",
              }
          return {}
      
      
      
      
      def handle_regular_message(event: Mapping[str, Any]) -> Mapping[str, Any]:
          """Handles regular messages (not commands).
      
          Args:
              Mapping[str, Any] event: The Google Chat event.
      
          Returns:
              Mapping[str, Any]: the response
          """
      
          if not event or "user" not in event:
              return "Invalid request."
      
          message_data = create_message(event["user"])
          return message_data
      
      
      def create_message(user: Mapping[str, Any]) -> Mapping[str, Any]:
          """Creates a card message with the user's avatar.
      
          Args:
              Mapping[str, Any] user: The user who sent the message.
      
          Returns:
              Mapping[str, Any]: a card with the user's avatar.
          """
          display_name = user.get("displayName", "")
          avatar_url = user.get("avatarUrl", "")
      
          return {
              "text": "Here's your avatar",
              "cardsV2": [
                  {
                      "cardId": "avatarCard",
                      "card": {
                          "name": "Avatar Card",
                          "header": {"title": f"Hello {display_name}!"},
                          "sections": [
                              {
                                  "widgets": [
                                      {"textParagraph": {"text": "Your avatar picture:"}},
                                      {"image": {"imageUrl": avatar_url}},
                                  ]
                              }
                          ],
                      },
                  }
              ],
          }

    3. 按一下「儲存並重新部署」。

Java

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

    請確認已選取 Chat 應用程式的專案。

  2. 按一下「編寫函式」。

  3. 在「建立服務」頁面中設定函式:

    1. 在「Service name」(服務名稱) 欄位中輸入 quickstartchatapp。
    2. 在「Region」(區域) 清單中選取區域。
    3. 在「執行階段」清單中,選取最新版本的 Java。
    4. 在「驗證」部分,選取「需要驗證」。
    5. 按一下「建立」,然後等待 Cloud Run 建立服務。 控制台會將您重新導向至「來源」分頁。
  4. 在「來源」分頁中:

    1. 在「Entry point」(進入點) 中,刪除預設文字並輸入 App。
    2. 將 src/main/java/com/example/Example.java 重新命名為 src/main/java/AvatarApp.java。
    3. 將 AvatarApp.java 的內容替換為下列程式碼:

      java/avatar-app/src/main/java/AvatarApp.java
      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.api.services.chat.v1.model.User;
      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;
      import java.util.List;
      
      public class AvatarApp implements HttpFunction {
        private static final Gson gson = new Gson();
      
        // Command IDs (configure these in Google Chat API)
        private static final int ABOUT_COMMAND_ID = 1; // ID for the "/about" slash command
        private static final int HELP_COMMAND_ID = 2; // ID for the "Help" quick command
      
        @Override
        public void service(HttpRequest request, HttpResponse response) throws Exception {
          JsonObject event = gson.fromJson(request.getReader(), JsonObject.class);
      
          if (event.has("appCommandMetadata")) {
            handleAppCommands(event, response);
          } else {
            handleRegularMessage(event, response);
          }
        }
      
        /**
         * Handles slash and quick commands.
         *
         * @param event    The Google Chat event.
         * @param response The HTTP response object.
         */
        private void handleAppCommands(JsonObject event, HttpResponse response) throws Exception {
          int appCommandId = event.getAsJsonObject("appCommandMetadata").get("appCommandId").getAsInt();
      
          switch (appCommandId) {
            case ABOUT_COMMAND_ID:
              Message aboutMessage = new Message();
              aboutMessage.setText("The Avatar app replies to Google Chat messages.");
              aboutMessage.setPrivateMessageViewer(new User()
                  .setName(event.getAsJsonObject("user").get("name").getAsString()));
              response.getWriter().write(gson.toJson(aboutMessage));
              return;
            case HELP_COMMAND_ID:
              Message helpMessage = new Message();
              helpMessage.setText("The Avatar app replies to Google Chat messages.");
              helpMessage.setPrivateMessageViewer(new User()
                  .setName(event.getAsJsonObject("user").get("name").getAsString()));
              response.getWriter().write(gson.toJson(helpMessage));
              return;
          }
        }
      
        /**
         * Handles regular messages (not commands).
         *
         * @param event    The Google Chat event.
         * @param response The HTTP response object.
         */
        private void handleRegularMessage(JsonObject event, HttpResponse response) throws Exception {
      
          if (!event.has("user")) {
            response.getWriter().write("Invalid request.");
            return;
          }
      
          JsonObject user = event.getAsJsonObject("user");
          String displayName = user.has("displayName") ? user.get("displayName").getAsString() : "";
          String avatarUrl = user.has("avatarUrl") ? user.get("avatarUrl").getAsString() : "";
          Message message = createMessage(displayName, avatarUrl);
          response.getWriter().write(gson.toJson(message));
        }
      
        /**
         * Creates a card message with the user's avatar.
         *
         * @param displayName The user's display name.
         * @param avatarUrl   The URL of the user's avatar.
         * @return The card message object.
         */
        private Message createMessage(String displayName, String avatarUrl) {
          return new Message()
              .setText("Here's your avatar")
              .setCardsV2(List.of(new CardWithId()
                  .setCardId("avatarCard")
                  .setCard(new GoogleAppsCardV1Card()
                      .setName("Avatar Card")
                      .setHeader(new GoogleAppsCardV1CardHeader()
                          .setTitle(String.format("Hello %s!", displayName)))
                      .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(
                          new GoogleAppsCardV1Widget()
                              .setTextParagraph(new GoogleAppsCardV1TextParagraph()
                                  .setText("Your avatar picture:")),
                          new GoogleAppsCardV1Widget()
                              .setImage(new GoogleAppsCardV1Image().setImageUrl(avatarUrl)))))))));
        }
      }

    4. 將 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/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
      
        <groupId>gcfv2</groupId>
        <artifactId>avatar-app</artifactId>
        <version>0.0.1</version>
        <name>Avatar App</name>
      
        <properties>
          <maven.compiler.release>21</maven.compiler.release>
        </properties>
      
        <dependencies>
          <dependency>
            <groupId>com.google.cloud.functions</groupId>
            <artifactId>functions-framework-api</artifactId>
            <version>1.1.4</version>
          </dependency>
      
          <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
          <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.12.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-rev20250116-2.0.0</version>
          </dependency>
      
        </dependencies>
      
      </project>

    5. 按一下「儲存並重新部署」。

授權 Google Chat 叫用函式

如要授權 Google Chat 叫用函式,請新增具有 Cloud Run 叫用者角色的 Google Chat 服務帳戶:

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

  2. 在 Cloud Run 服務清單中,選取接收函式旁的核取方塊。(請勿點選函式本身)。

  3. 按一下 [權限],「權限」面板隨即開啟。

  4. 按一下「Add principal」(新增主體)。

  5. 在「New principals」(新增主體) 中輸入 chat@system.gserviceaccount.com。

  6. 在「請選擇角色」部分,依序選取「Cloud Run」 >「Cloud Run Invoker」。

  7. 按一下 [儲存]。

設定非外掛程式的 Chat 應用程式

部署 Cloud Run 函式後,請按照下列步驟將其轉換為非外掛程式的 Chat 應用程式:

  1. 在 Google API 控制台中,前往 Cloud Run 頁面:

    前往 Cloud Run。

    請確保選取的是已啟用 Cloud Run 的專案。

  2. 在服務清單中,點選「quickstartchatapp」quickstartchatapp。

  3. 在「服務詳細資料」頁面,複製函式的「網址」。

  4. 搜尋「Google Chat API」,然後依序點選「Google Chat API」和「管理」。

    前往 Chat API

  5. 按一下「設定」,然後設定非外掛程式的 Chat 應用程式:

    1. 取消勾選「將這個 Chat 擴充應用程式建構為 Google Workspace 外掛程式」。系統會開啟對話方塊,要求您確認。在對話方塊中,按一下「停用」。
    2. 在「應用程式名稱」中輸入 Quickstart App。
    3. 在「顯示圖片網址」中輸入 https://developers.google.com/workspace/chat/images/quickstart-app-avatar.png。
    4. 在「Description」(說明) 中輸入 Quickstart app。
    5. 在「功能」下方,選取「加入聊天室和群組對話」。
    6. 在「連線設定」下方,選取「HTTP 端點網址」。
    7. 在「觸發條件」下方,選取「為所有觸發條件使用通用的 HTTP 端點網址」,然後將 Cloud Run 函式觸發條件的網址貼到方塊中。
    8. 在「可見度」下方,選取「將這個即時通訊應用程式提供給網域中的特定使用者和群組」,然後輸入電子郵件地址。
    9. 在「記錄」下方,選取「將錯誤記錄至 Logging」。
  6. 按一下 [儲存]。