发送卡片消息

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

除了短信之外,Chat 应用还可在聊天室中向用户发送卡片消息。卡片支持定义的布局、交互式界面元素(如按钮)和富媒体(如图片)。

使用卡片消息可以:

  • 提供详细信息
  • 从用户那里收集信息
  • 指导用户采取下一步行动

本指南介绍了如何同步发送卡片消息(如接收用户消息或将其添加到聊天室)和异步发送(即在不使用提示的情况下使用 Chat REST API 从应用向聊天室或用户发送消息)。

前提条件

如需发送本指南中的卡片消息,您需要具备以下权限:

Node.js

Python

Apps 脚本

卡片消息剖析

每张卡片(无论是对话框还是消息)都是 Chat API 中 spaces.messages 资源的 JSON 对象。

卡片 JSON 对象包含以下内容:

  1. 名为 cardsV2[] 的数组,其中包含一个或多个 CardWithId 对象。
  2. 一个 cardId,用于标识卡并在给定消息内限定范围。(不同消息中的卡片可以具有相同的 ID)。
  3. card 对象,由以下部分组成:

    • header 对象,用于指定标题、副标题和头像样式图片等内容。
    • 一个或多个 section 对象,其中至少包含一个微件。
    • 一个或多个 widget 对象。每个微件都是一个可表示文本、图片、按钮和其他对象类型的复合对象。

      卡片消息和对话框中支持以下微件:

      • TextParagraph - 显示一段采用可选的简单 HTML 格式的文本。
      • Image - 显示 HTTPS 网址上托管的可点击或静态 .PNG.JPG 图片。
      • DecoratedText - 显示包含可选布局和功能(例如图标和按钮)的文本。
      • ButtonList - 显示一组按钮。

      对话框支持以下微件(即将支持卡片消息):

      • TextInput - 可供用户在其中输入文本的字段。
      • SelectionInput - 提供一组可选内容,例如复选框、单选按钮、开关或下拉菜单。

      • Divider - 在堆叠的微件之间显示横跨卡片宽度的水平线,充当视觉分隔线。

      • Grid - 将一组内容放在一个网格中。

      即将支持以下微件:

例如,请观察以下卡片消息中的 headersectionwidget 对象:

使用卡片消息在 Chat 聊天室中运行投票的聊天应用

以下代码表示卡片消息的 JSON:

JSON

{
  "cardsV2": [
    {
      "cardId": "unique-card-id",
      "card": {
        "header": {
          "title": "Sasha",
          "subtitle": "Software Engineer",
          "imageUrl":
          "https://developers.google.com/chat/images/quickstart-app-avatar.png",
          "imageType": "CIRCLE",
          "imageAltText": "Avatar for Sasha",
        },
        "sections": [
          {
            "header": "Contact Info",
            "collapsible": true,
            "uncollapsibleWidgetsCount": 1,
            "widgets": [
              {
                "decoratedText": {
                  "startIcon": {
                    "knownIcon": "EMAIL",
                  },
                  "text": "sasha@example.com",
                }
              },
              {
                "decoratedText": {
                  "startIcon": {
                    "knownIcon": "PERSON",
                  },
                  "text": "<font color=\"#80e27e\">Online</font>",
                },
              },
              {
                "decoratedText": {
                  "startIcon": {
                    "knownIcon": "PHONE",
                  },
                  "text": "+1 (555) 555-1234",
                }
              },
              {
                "buttonList": {
                  "buttons": [
                    {
                      "text": "Share",
                      "onClick": {
                        "openLink": {
                          "url": "https://example.com/share",
                        }
                      }
                    },
                    {
                      "text": "Edit",
                      "onClick": {
                        "action": {
                          "function": "goToView",
                          "parameters": [
                            {
                              "key": "viewType",
                              "value": "EDIT",
                            }
                          ],
                        }
                      }
                    },
                  ],
                }
              },
            ],
          },
        ],
      },
    }
  ],
}

发送同步卡片消息

在此示例中,用户在 Google Chat 中向 Chat 应用发送消息,然后该应用通过发送一条简单的同步卡片消息(显示发送者的姓名和头像图片)来进行回复:

聊天应用,其中包含显示发送者的显示名和头像图片的卡片

在以下代码示例中,Node.js 和 Python 应用托管在 Google Cloud Functions 上。Apps 脚本示例托管在 Google Apps 脚本上。

如需查看有关如何构建和部署聊天应用的完整说明,请参阅构建聊天应用

Node.js

/**
  * Google Cloud Function that responds to messages sent in
  * Google Chat.
  *
  * @param {Object} req Request sent from Google Chat.
  * @param {Object} res Response to send back.
  */
exports.helloChat = function helloChat(req, res) {
  if (req.method === 'GET' || !req.body.message) {
    res.send('Hello! This function must be called from Google Chat.');
  }

  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} imageURL the URL for the sender's avatar.
  * @return {Object} a card with the user's avatar.
  */
function createMessage(displayName, imageURL) {
  const cardHeader = {
    'title': 'Hello ' + displayName + '!',
  };

  const avatarWidget = {
    'textParagraph': {'text': 'Your avatar picture: '},
  };

  const avatarImageWidget = {
    image: {'imageUrl': imageURL},
  };

  const avatarSection = {
    'widgets': [
      avatarWidget,
      avatarImageWidget,
    ],
  };

  return {
    'cards': [{
      'name': 'Avatar Card',
      'header': cardHeader,
      'sections': [avatarSection],
    }],
  };
}

Python

from typing import Any, Mapping

import flask
import functions_framework

# Google Cloud Function that responds to messages sent in
# Google Chat.
#
# @param {Object} req Request sent from Google Chat.
# @param {Object} res Response to send back.
@functions_framework.http
def hello_chat(req: flask.Request):
  if req.method == 'GET':
    return 'Hello! This function must be called from Google Chat.'

  request_json = req.get_json(silent=True)

  display_name = request_json['message']['sender']['displayName']
  avatar = request_json['message']['sender']['avatarUrl']

  response = create_message(name=display_name, image_url=avatar)

  return response

# Creates a card with two widgets.
# @param {string} name the sender's display name.
# @param {string} image_url the URL for the sender's avatar.
# @return {Object} a card with the user's avatar.
def create_message(name: str, image_url: str) -> Mapping[str, Any]:
  avatar_image_widget = {'image': {'imageUrl': image_url}}
  avatar_text_widget = {'textParagraph': {'text': 'Your avatar picture:'}}
  avatar_section = {'widgets': [avatar_text_widget, avatar_image_widget]}

  header = {'title': f'Hello {name}!'}

  cards = {'cards': [{'name': 'Avatar Card',
                      'header': header, 'sections': [avatar_section]}]}

  return cards  

Apps 脚本

/**
* Responds to a MESSAGE event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onMessage(event) {
    const displayName = event.message.sender.displayName;
    const avatarUrl = event.message.sender.avatarUrl;

    return createMessage(displayName, avatarUrl);
}

/**
* 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 sender's avatar.
*/
function createMessage(displayName, avatarUrl) {
    const cardHeader = {
        title: `Hello ${displayName}!`
    };

    const avatarWidget = {
        textParagraph: { text: 'Your avatar picture: ' }
    };

    const avatarImageWidget = {
        image: { imageUrl: avatarUrl }
    };

    const avatarSection = {
        widgets: [
            avatarWidget,
            avatarImageWidget
        ],
    };

    return {
        cards: [{
            name: 'Avatar Card',
            header: cardHeader,
            sections: [avatarSection]
        }]
    };
}

使用 Chat API 发送异步卡片消息

此示例使用 Chat API 异步创建消息,并将其发送到添加了 Chat 应用的聊天室,如下所示:

使用 Chat REST API 创建的卡片消息。
图 1:使用 Chat REST API 创建的卡片消息。

Python

  1. 在工作目录中,创建一个名为 chat_create_card_message.py 的文件。
  2. chat_create_card_message.py 中添加以下代码:

    from httplib2 import Http
    from oauth2client.service_account import ServiceAccountCredentials
    from apiclient.discovery import build
    
    # Specify required scopes.
    SCOPES = ['https://www.googleapis.com/auth/chat.bot']
    
    # Specify service account details.
    CREDENTIALS = ServiceAccountCredentials.from_json_keyfile_name(
        'service_account.json', SCOPES)
    
    # Build the URI and authenticate with the service account.
    chat = build('chat', 'v1', http=CREDENTIALS.authorize(Http()))
    
    # Create a Chat message.
    result = chat.spaces().messages().create(
    
        # The space to create the message in.
        #
        # Replace SPACE with a space name.
        # Obtain the space name from the spaces resource of Chat API,
        # or from a space's URL.
        parent='spaces/SPACE',
    
        # The message to create.
        body=
        {
          'cards_v2': [{
            'card_id': 'createCardMessage',
            'card': {
              'header': {
                'title': 'A Card Message!',
                'subtitle': 'Created with Chat REST API',
                'imageUrl': 'https://developers.google.com/chat/images/chat-product-icon.png',
                'imageType': 'CIRCLE'
              },
              'sections': [
                {
                  'widgets': [
                    {
                      'buttonList': {
                        'buttons': [
                          {
                            'text': 'Read the docs!',
                            'onClick': {
                              'openLink': {
                                'url': 'https://developers.google.com/chat'
                              }
                            }
                          }
                        ]
                      }
                    }
                  ]
                }
              ]
            }
          }]
        }
    
    ).execute()
    
    print(result)
    
  3. 在代码中,将 SPACE 替换为聊天室名称(可以从 Chat API 中的 spaces.list() 方法或聊天室网址获取)。

  4. 在工作目录中,构建并运行示例:

    python3 chat_create_card_message.py
    

要详细了解如何在 Chat REST API 中处理消息,请参阅创建、读取、更新和删除消息

打开对话框

对话框是基于卡片的窗口式界面,可供聊天应用与用户进行互动。为了帮助用户完成多步流程,应用可以打开连续的对话框。应用可以打开对话框以响应点击卡片消息或响应斜杠命令

对话框对于许多类型的用户互动非常有用,包括:

  • 向用户收集信息
  • 使用网络服务对用户进行身份验证
  • 配置 Chat 应用设置

在此示例中,Chat 应用会打开一个对话框,以帮助用户为其通讯录创建新联系人:

包含各种不同微件的对话框。

如需实现对话框,请参阅打开对话框

卡片格式

卡片文本格式

在卡片内,大多数文本字段通过少量 HTML 标记支持基本文本格式。支持的代码及其用途如下表所示:

粗体 <b> 斜体 <i>
下划线 <> 删除线 <警示>
字体颜色 <font color=""> 超链接 <a href="">
换行符 <br>

请注意,基本消息的文本正文解析使用不同的标记语法,该语法针对人类用户进行了优化。有关详情,请参阅发送短信

内置图标

DecoratedTextButtonList 微件支持 icon 元素,该元素用于指定 Google Chat 中提供的某个内置图标:

{ . . . "knownIcon": "训练", . . }

下表列出了可用于卡片消息的内置图标:

飞机 图书标记
公交车 汽车
时钟 确认 _NUMBER_ICON
说明 DOLLAR
电子邮件 活动_服务
航班抵达 航班起飞
酒店 HOTEL_ROOM_TYPE
邀请 MAP_PIN 码
会员资格 多用户
个人 电话
RESTAURANT_ICON SHOPPING_CART(购物车)
星标 商店
门票 训练
VIDEO_CAMERA 视频播放

自定义图标

借助 DecoratedTextButtonList 微件,您可以使用上面列出的内置图标,也可以定义自己的自定义图标。如需指定自定义图标,请使用 iconUrl 元素,如下所示:

{ . . . "iconUrl": "https://developers.google.com/chat/images/quickstart-app-avatar.png" . . }

限制和注意事项

在您准备发送卡片消息时,请注意这些限制和注意事项。

  • 卡片消息不支持以下微件,但即将支持:

    • TextInput:用户可在其中输入文本的字段。
    • SelectionInput:提供一组可选的内容,例如复选框列表、单选按钮、开关或下拉菜单。
    • DateTimePicker:可让用户指定日期和/或时间。
    • Grid,用于在一组网格中布局一组项。