为 Google Chat 应用构建首页

本页将介绍如何为 Google Chat 应用。应用首页是一个可自定义的卡片界面 用户打开直接 消息。

包含两个微件的应用首页卡片。

例如,您可以 配置应用首页卡片消息,以包含与 Chat 扩展应用 斜杠命令。对于最终用户,应用主屏幕是 只有在 Chat 应用的私信中 应用开发者启用相应功能


使用卡片构建器设计和预览聊天应用的 JSON 卡片消息:

打开卡片制作工具

前提条件

Python

一款已启用互动功能的 Google Chat 应用。要创建 交互式 Chat 应用,请完成此快速入门

Apps 脚本

一款已启用互动功能的 Google Chat 应用。要创建 交互式聊天应用,请完成此快速入门

Node.js

一款已启用互动功能的 Google Chat 应用。要创建 交互式 Chat 应用,请完成此快速入门

Java

一款已启用互动功能的 Google Chat 应用。要创建 交互式 Chat 应用,请完成此快速入门

配置 Chat API

如要支持应用主屏幕,您必须更新 Chat API 配置 Google Cloud 控制台中。

Python

  1. 在 Google Cloud 控制台中,点击菜单 > 更多产品 > Google Workspace > 产品库 > Google Chat API

    前往 Google Chat API

  2. 点击管理,然后点击配置标签页。

  3. 选中 Support App Home 复选框。

  4. App Home 网址(应用主屏幕网址)字段中,添加网址。这个值通常与 作为应用网址的网址。此网址是针对 APP_HOME 事件

  5. 点击保存

Apps 脚本

  1. 在 Google Cloud 控制台中,点击菜单 > 更多产品 > Google Workspace > 产品库 > Google Chat API

    前往 Google Chat API

  2. 点击管理,然后点击配置标签页。

  3. 选中 Support App Home 复选框。

  4. 点击保存

Node.js

  1. 在 Google Cloud 控制台中,点击菜单 > 更多产品 > Google Workspace > 产品库 > Google Chat API

    前往 Google Chat API

  2. 点击管理,然后点击配置标签页。

  3. 选中 Support App Home 复选框。

  4. App Home 网址(应用主屏幕网址)字段中,添加网址。这个值通常与 作为应用网址的网址。此网址是针对 APP_HOME 事件

  5. 点击保存

Java

  1. 在 Google Cloud 控制台中,点击菜单 > 更多产品 > Google Workspace > 产品库 > Google Chat API

    前往 Google Chat API

  2. 点击管理,然后点击配置标签页。

  3. 选中 Support App Home 复选框。

  4. App Home 网址(应用主屏幕网址)字段中,添加网址。这个值通常与 作为应用网址的网址。此网址是针对 APP_HOME 事件

  5. 点击保存

构建应用首页

当用户通过 聊天应用,并且可以在 一个互动事件,例如点击按钮、提交表单或关闭对话框。

在以下示例中,Chat 应用会显示 一张初始应用首页卡片,其中显示了该卡片的创建时间 按钮。当用户点击该按钮时,Chat 应用 会返回一张更新后的卡片,其中会显示更新后的卡片的创建时间。

为应用首页创建初始卡片

如要构建应用主屏幕,Chat 应用必须处理 APP_HOME 个互动事件,并返回一个 RenderActions pushCard 导航。

Python

python/app-home/main.py
@app.route('/', methods=['POST'])
def post() -> Mapping[str, Any]:
  """Handle requests from Google Chat

  Returns:
      Mapping[str, Any]: the response
  """
  event = request.get_json()
  match event['chat'].get('type'):

    case 'APP_HOME':
      # App home is requested
      body = { "action": { "navigations": [{
        "pushCard": get_home_card()
      }]}}

    case 'SUBMIT_FORM':
      # The update button from app home is clicked
      event_object = event.get('commonEventObject')
      if event_object is not None:
        if 'update_app_home' == event_object.get('invokedFunction'):
          body = update_app_home()

    case _:
      # Other response types are not supported
      body = {}

  return json.jsonify(body)


def get_home_card() -> Mapping[str, Any]:
  """Create the app home card

  Returns:
      Mapping[str, Any]: the card
  """
  return { "sections": [{ "widgets": [
    { "textParagraph": {
      "text": "Here is the app home 🏠 It's " +
        datetime.datetime.now().isoformat()
    }},
    { "buttonList": { "buttons": [{
      "text": "Update app home",
      "onClick": { "action": {
        "function": "update_app_home"
      }}
    }]}}
  ]}]}

Apps 脚本

实现在所有 APP_HOME 事件后调用的 onAppHome 函数:

此示例通过返回 卡片 JSON。 您还可以使用 Apps 脚本卡片服务

apps-script/app-home/app-home.gs
/**
 * Responds to a APP_HOME event in Google Chat.
 */
function onAppHome() {
  return { action: { navigations: [{
    pushCard: getHomeCard()
  }]}};
}

/**
 * Returns the app home card.
 */
function getHomeCard() {
  return { sections: [{ widgets: [
    { textParagraph: {
      text: "Here is the app home 🏠 It's " + new Date().toTimeString()
    }},
    { buttonList: { buttons: [{
      text: "Update app home",
      onClick: { action: {
        function: "updateAppHome"
      }}
    }]}}
  ]}]};
}

Node.js

node/app-home/index.js
app.post('/', async (req, res) => {
  let event = req.body.chat;

  let body = {};
  if (event.type === 'APP_HOME') {
    // App home is requested
    body = { action: { navigations: [{
      pushCard: getHomeCard()
    }]}}
  } else if (event.type === 'SUBMIT_FORM') {
    // The update button from app home is clicked
    commonEvent = req.body.commonEventObject;
    if (commonEvent && commonEvent.invokedFunction === 'updateAppHome') {
      body = updateAppHome()
    }
  }

  return res.json(body);
});

// Create the app home card
function getHomeCard() {
  return { sections: [{ widgets: [
    { textParagraph: {
      text: "Here is the app home 🏠 It's " + new Date().toTimeString()
    }},
    { buttonList: { buttons: [{
      text: "Update app home",
      onClick: { action: {
        function: "updateAppHome"
      }}
    }]}}
  ]}]};
}

Java

java/app-home/src/main/java/com/google/chat/app/home/App.java
/**
 * Process Google Chat events
 *
 * @param event Event from chat.
 * @return GenericJson
 * @throws Exception
 */
@PostMapping("/")
@ResponseBody
public GenericJson onEvent(@RequestBody JsonNode event) throws Exception {
  switch (event.at("/chat/type").asText()) {
    case "APP_HOME":
      // App home is requested
      GenericJson navigation = new GenericJson();
      navigation.set("pushCard", getHomeCard());

      GenericJson action = new GenericJson();
      action.set("navigations", List.of(navigation));

      GenericJson response = new GenericJson();
      response.set("action", action);
      return response;
    case "SUBMIT_FORM":
      // The update button from app home is clicked
      if (event.at("/commonEventObject/invokedFunction").asText().equals("updateAppHome")) {
        return updateAppHome();
      }
  }

  return new GenericJson();
}

// Create the app home card
GoogleAppsCardV1Card getHomeCard() {
  GoogleAppsCardV1TextParagraph textParagraph = new GoogleAppsCardV1TextParagraph();
  textParagraph.setText("Here is the app home 🏠 It's " + new Date());

  GoogleAppsCardV1Widget textParagraphWidget = new GoogleAppsCardV1Widget();
  textParagraphWidget.setTextParagraph(textParagraph);

  GoogleAppsCardV1Action action = new GoogleAppsCardV1Action();
  action.setFunction("updateAppHome");

  GoogleAppsCardV1OnClick onClick = new GoogleAppsCardV1OnClick();
  onClick.setAction(action);

  GoogleAppsCardV1Button button = new GoogleAppsCardV1Button();
  button.setText("Update app home");
  button.setOnClick(onClick);

  GoogleAppsCardV1ButtonList buttonList = new GoogleAppsCardV1ButtonList();
  buttonList.setButtons(List.of(button));

  GoogleAppsCardV1Widget buttonListWidget = new GoogleAppsCardV1Widget();
  buttonListWidget.setButtonList(buttonList);

  GoogleAppsCardV1Section section = new GoogleAppsCardV1Section();
  section.setWidgets(List.of(textParagraphWidget, buttonListWidget));

  GoogleAppsCardV1Card card = new GoogleAppsCardV1Card();
  card.setSections(List.of(section));

  return card;
}

更新应用首页卡片

如果初始应用首页卡片包含按钮等交互式微件 或选择输入,您的 Chat 应用必须处理 来检索相关互动事件 RenderActions updateCard导航。详细了解如何处理 小程序,请参见 处理用户输入的信息

Python

python/app-home/main.py
def update_app_home() -> Mapping[str, Any]:
  """Update the app home

  Returns:
      Mapping[str, Any]: the update card render action
  """
  return { "renderActions": { "action": { "navigations": [{
    "updateCard": get_home_card()
  }]}}}

Apps 脚本

此示例通过返回 卡片 JSON。 您还可以使用 Apps 脚本卡片服务

apps-script/app-home/app-home.gs
/**
 * Updates the home app.
 */
function updateAppHome() {
  return { renderActions: { action: { navigations: [{
    updateCard: getHomeCard()
  }]}}};
}

Node.js

node/app-home/index.js
// Update the app home
function updateAppHome() {
  return { renderActions: { action: { navigations: [{
    updateCard: getHomeCard()
  }]}}}
};

Java

java/app-home/src/main/java/com/google/chat/app/home/App.java
// Update the app home
GenericJson updateAppHome() {
  GenericJson navigation = new GenericJson();
  navigation.set("updateCard", getHomeCard());

  GenericJson action = new GenericJson();
  action.set("navigations", List.of(navigation));

  GenericJson renderActions = new GenericJson();
  renderActions.set("action", action);

  GenericJson response = new GenericJson();
  response.set("renderActions", renderActions);
  return response;
}

限制

一般来说, navigation为 不适用于 Chat 应用。您无法退回一叠卡片。 只有 pushCard(适用于初始响应)和 updateCard(适用于更新) 。