本指南介绍了如何使用 Google Chat API 代表用户创建包含互动式卡片的消息,以及如何异步更新这些卡片。
如果您想执行以下操作,则创建和更新卡片非常有用:
- 代表用户发布表示任务或外部资源的卡片。
- 根据外部事件更新卡片的状态(例如,从“进行中”更新为“已完成”),而无需等待用户互动。
- 刷新用户消息中卡片的内容,例如链接预览。
前提条件
Node.js
- 可访问 Google Chat 的 Google Workspace 商务版或企业版账号。
- 设置环境:
- 创建 Google Cloud 项目。
- 配置 OAuth 权限请求页面。
- 启用并配置 Google Chat API,为您的 Chat 应用设置名称、图标和说明。
- 安装 Node.js Google API 客户端库。
- 根据您希望在 Google Chat API 请求中进行身份验证的方式,创建访问凭据:
- 如需以 Chat 用户身份进行身份验证,请创建 OAuth 客户端 ID 凭证,并将凭证作为名为
credentials.json的 JSON 文件保存到本地目录。 - 如需以 Chat 应用身份进行身份验证,请创建服务账号凭证,并将凭证保存为名为
credentials.json的 JSON 文件。
- 如需以 Chat 用户身份进行身份验证,请创建 OAuth 客户端 ID 凭证,并将凭证作为名为
- 根据您是要以用户身份还是以 Chat 应用身份进行身份验证, 选择授权范围。
Python
- 可访问 Google Chat 的 Google Workspace 商务版或企业版账号。
- 设置环境:
- 创建 Google Cloud 项目。
- 配置 OAuth 权限请求页面。
- 启用并配置 Google Chat API,为 Chat 应用设置名称、图标和说明。
- 安装 Python Google API 客户端库。
- 根据您希望在 Google Chat API 请求中进行身份验证的方式,创建访问凭据:
- 如需以 Chat 用户身份进行身份验证,请创建 OAuth 客户端 ID 凭证,并将凭证作为名为
credentials.json的 JSON 文件保存到本地目录。 - 如需以 Chat 应用身份进行身份验证,请创建服务账号凭证,并将凭证保存为名为
credentials.json的 JSON 文件。
- 如需以 Chat 用户身份进行身份验证,请创建 OAuth 客户端 ID 凭证,并将凭证作为名为
- 根据您是要以用户身份还是以 Chat 应用身份进行身份验证, 选择授权范围。
Java
- 可访问 Google Chat 的 Google Workspace 商务版或企业版账号。
- 设置环境:
- 创建 Google Cloud 项目。
- 配置 OAuth 权限请求页面。
- 启用并配置 Google Chat API,为您的 Chat 应用设置名称、图标和说明。
- 安装 Java Google API 客户端库。
- 根据您希望在 Google Chat API 请求中进行身份验证的方式,创建访问凭据:
- 如需以 Chat 用户身份进行身份验证,请创建 OAuth 客户端 ID 凭证,并将凭证作为名为
credentials.json的 JSON 文件保存到本地目录。 - 如需以 Chat 应用身份进行身份验证,请创建服务账号凭证,并将凭证保存为名为
credentials.json的 JSON 文件。
- 如需以 Chat 用户身份进行身份验证,请创建 OAuth 客户端 ID 凭证,并将凭证作为名为
- 根据您是要以用户身份还是以 Chat 应用身份进行身份验证, 选择授权范围。
Apps 脚本
- 可访问 Google Chat 的 Google Workspace 商务版或企业版账号。
- 设置环境:
- 创建 Google Cloud 项目。
- 配置 OAuth 权限请求页面。
- 启用和配置 Google Chat API,为您的 Chat 应用设置名称、图标和说明。
- 创建独立的 Apps 脚本项目,并启用高级 Chat 服务。
- 在本指南中,您必须使用用户或应用身份验证。如需以 Chat 应用身份进行身份验证,请创建服务账号凭证。如需了解相关步骤,请参阅以 Google Chat 应用身份进行身份验证和授权。
- 根据您是要以用户身份还是以 Chat 应用身份进行身份验证, 选择授权范围。
代表用户创建卡片消息
如需代表用户创建包含卡片的消息,请使用用户身份验证。
如需创建消息,请在请求中指定以下内容:
chat.messages.create或chat.messages授权范围。Message资源中的cardsV2字段,其中包含卡片数据。- 每张卡的
cardId,这是异步更新所必需的。
以下示例展示了如何代表用户创建包含卡片的消息:
Node.js
/**
* This sample shows how to create a message with a card on behalf of a user.
*/
const {google} = require('googleapis');
const {auth} = require('google-auth-library');
async function main() {
// Create a client
const authClient = await auth.getClient({
scopes: ['https://www.googleapis.com/auth/chat.messages.create']
});
google.options({auth: authClient});
// Initialize the Chat API
const chat = google.chat({version: 'v1'});
// The space to create the message in.
const parent = 'spaces/SPACE_NAME';
// Create the request
const request = {
parent: parent,
requestBody: {
text: 'Here is a card created on my behalf:',
cardsV2: [{
cardId: 'unique-card-id',
card: {
header: {
title: 'Card Title',
subtitle: 'Card Subtitle'
},
sections: [{
widgets: [{
textParagraph: {
text: 'This card is attached to a user message.'
}
}]
}]
}
}]
}
};
// Call the API
const response = await chat.spaces.messages.create(request);
// Handle the response
console.log(response.data);
}
main().catch(console.error);
Python
"""
This sample shows how to create a message with a card on behalf of a user.
"""
from google.oauth2 import service_account
from googleapiclient.discovery import build
import google.auth
def create_message_with_card():
# Create a client
scopes = ["https://www.googleapis.com/auth/chat.messages.create"]
credentials, _ = google.auth.default(scopes=scopes)
# Build the service endpoint for Chat API.
service = build('chat', 'v1', credentials=credentials)
# The space to create the message in.
parent = "spaces/SPACE_NAME"
# Create the request
result = service.spaces().messages().create(
parent=parent,
body={
'text': 'Here is a card created on my behalf:',
'cardsV2': [{
'cardId': 'unique-card-id',
'card': {
'header': {
'title': 'Card Title',
'subtitle': 'Card Subtitle'
},
'sections': [{
'widgets': [{
'textParagraph': {
'text': 'This card is attached to a user message.'
}
}]
}]
}
}]
}
).execute()
print(result)
if __name__ == "__main__":
create_message_with_card()
Java
/**
* This sample shows how to create a message with a card on behalf of a user.
*/
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.json.JsonHttpContent;
import com.google.api.client.json.gson.GsonFactory;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class CreateMessageWithCard {
public static void main(String[] args) throws Exception {
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
GsonFactory jsonFactory = GsonFactory.getDefaultInstance();
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault()
.createScoped(Arrays.asList("https://www.googleapis.com/auth/chat.messages.create"));
HttpRequestFactory requestFactory = transport.createRequestFactory(new HttpCredentialsAdapter(credentials));
String parent = "spaces/SPACE_NAME";
GenericUrl url = new GenericUrl("https://chat.googleapis.com/v1/" + parent + "/messages");
// Construct the message body
Map<String, Object> message = new HashMap<>();
message.put("text", "Here is a card created on my behalf:");
Map<String, Object> header = new HashMap<>();
header.put("title", "Card Title");
header.put("subtitle", "Card Subtitle");
Map<String, Object> textParagraph = new HashMap<>();
textParagraph.put("text", "This card is attached to a user message.");
Map<String, Object> widget = new HashMap<>();
widget.put("textParagraph", textParagraph);
Map<String, Object> section = new HashMap<>();
section.put("widgets", Collections.singletonList(widget));
Map<String, Object> card = new HashMap<>();
card.put("header", header);
card.put("sections", Collections.singletonList(section));
Map<String, Object> cardWithId = new HashMap<>();
cardWithId.put("cardId", "unique-card-id");
cardWithId.put("card", card);
message.put("cardsV2", Collections.singletonList(cardWithId));
HttpRequest request = requestFactory.buildPostRequest(url, new JsonHttpContent(jsonFactory, message));
System.out.println(request.execute().parseAsString());
}
}
Apps 脚本
/**
* This sample shows how to create a message with a card on behalf of a user.
*/
function createMessageWithCard() {
const parent = 'spaces/SPACE_NAME';
const url = `https://chat.googleapis.com/v1/${parent}/messages`;
const message = {
text: 'Here is a card created on my behalf:',
cardsV2: [{
cardId: 'unique-card-id',
card: {
header: {
title: 'Card Title',
subtitle: 'Card Subtitle'
},
sections: [{
widgets: [{
textParagraph: {
text: 'This card is attached to a user message.'
}
}]
}]
}
}]
};
const options = {
method: 'post',
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
},
contentType: 'application/json',
payload: JSON.stringify(message),
muteHttpExceptions: true
};
try {
const response = UrlFetchApp.fetch(url, options);
console.log(response.getContentText());
} catch (err) {
console.log('Failed to create message: ' + err.message);
}
}
异步更新卡片
创建包含卡片的消息后,您可以使用应用身份验证异步更新卡片。这样,您的应用就可以在无需用户互动的情况下刷新卡片内容。 只有将卡片添加到用户消息中的 Chat 应用才能替换该卡片。如果用户修改了消息文本,系统会移除应用拥有的卡片,并且您的应用无法再更新这些卡片。
如需更新卡片,请使用以下内容调用 replaceCards 方法:
chat.bot授权范围。- 要更新的消息的
name。 - 新的
cardsV2列表。这会替换消息中的所有现有卡片。 如果您提供空列表,则系统会移除这些卡。
以下示例展示了如何更新消息的卡片:
Node.js
/**
* This sample shows how to update cards on a message.
*/
const {google} = require('googleapis');
const {auth} = require('google-auth-library');
async function main() {
// Create a client with app credentials
const authClient = await auth.getClient({
scopes: ['https://www.googleapis.com/auth/chat.bot']
});
google.options({auth: authClient});
// Initialize the Chat API
const chat = google.chat({version: 'v1'});
// The message to update.
const messageName = 'spaces/SPACE_NAME/messages/MESSAGE_ID';
// Create the request
const request = {
name: messageName,
requestBody: {
cardsV2: [{
cardId: 'unique-card-id',
card: {
header: {
title: 'Updated Card Title',
subtitle: 'Updated Card Subtitle'
},
sections: [{
widgets: [{
textParagraph: {
text: 'The card content has been updated asynchronously.'
}
}]
}]
}
}]
}
};
// Call the API
await chat.spaces.messages.replaceCards(request);
console.log('Cards updated.');
}
main().catch(console.error);
Python
"""
This sample shows how to update cards on a message.
"""
from google.oauth2 import service_account
from googleapiclient.discovery import build
import google.auth
def replace_message_cards():
# Create a client with app credentials
scopes = ["https://www.googleapis.com/auth/chat.bot"]
credentials, _ = google.auth.default(scopes=scopes)
# Build the service endpoint for Chat API.
service = build('chat', 'v1', credentials=credentials)
# The message to update.
message_name = "spaces/SPACE_NAME/messages/MESSAGE_ID"
# Create the request
result = service.spaces().messages().replaceCards(
name=message_name,
body={
'cardsV2': [{
'cardId': 'unique-card-id',
'card': {
'header': {
'title': 'Updated Card Title',
'subtitle': 'Updated Card Subtitle'
},
'sections': [{
'widgets': [{
'textParagraph': {
'text': 'The card content has been updated asynchronously.'
}
}]
}]
}
}]
}
).execute()
print("Cards updated.")
if __name__ == "__main__":
replace_message_cards()
Java
/**
* This sample shows how to update cards on a message.
*/
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.json.JsonHttpContent;
import com.google.api.client.json.gson.GsonFactory;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class ReplaceMessageCards {
public static void main(String[] args) throws Exception {
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
GsonFactory jsonFactory = GsonFactory.getDefaultInstance();
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault()
.createScoped(Arrays.asList("https://www.googleapis.com/auth/chat.bot"));
HttpRequestFactory requestFactory = transport.createRequestFactory(new HttpCredentialsAdapter(credentials));
String messageName = "spaces/SPACE_NAME/messages/MESSAGE_ID";
GenericUrl url = new GenericUrl("https://chat.googleapis.com/v1/" + messageName + ":replaceCards");
// Construct the body
Map<String, Object> header = new HashMap<>();
header.put("title", "Updated Card Title");
header.put("subtitle", "Updated Card Subtitle");
Map<String, Object> textParagraph = new HashMap<>();
textParagraph.put("text", "The card content has been updated asynchronously.");
Map<String, Object> widget = new HashMap<>();
widget.put("textParagraph", textParagraph);
Map<String, Object> section = new HashMap<>();
section.put("widgets", Collections.singletonList(widget));
Map<String, Object> card = new HashMap<>();
card.put("header", header);
card.put("sections", Collections.singletonList(section));
Map<String, Object> cardWithId = new HashMap<>();
cardWithId.put("cardId", "unique-card-id");
cardWithId.put("card", card);
Map<String, Object> body = new HashMap<>();
body.put("cardsV2", Collections.singletonList(cardWithId));
HttpRequest request = requestFactory.buildPostRequest(url, new JsonHttpContent(jsonFactory, body));
request.execute();
System.out.println("Cards updated.");
}
}
Apps 脚本
/**
* This sample shows how to update cards on a message.
*/
function replaceMessageCards() {
const messageName = 'spaces/SPACE_NAME/messages/MESSAGE_ID';
const url = `https://chat.googleapis.com/v1/${messageName}:replaceCards`;
const request = {
cardsV2: [{
cardId: 'unique-card-id',
card: {
header: {
title: 'Updated Card Title',
subtitle: 'Updated Card Subtitle'
},
sections: [{
widgets: [{
textParagraph: {
text: 'The card content has been updated asynchronously.'
}
}]
}]
}
}]
};
const options = {
method: 'post',
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
},
contentType: 'application/json',
payload: JSON.stringify(request),
muteHttpExceptions: true
};
try {
const response = UrlFetchApp.fetch(url, options);
console.log('Cards updated.');
} catch (err) {
console.log('Failed to update cards: ' + err.message);
}
}
限制
代表用户创建包含卡片的消息或更新卡片时,Chat 应用必须是聊天室的成员。此要求适用于以下情况:
- 代表用户创建包含卡片的消息。
- 替换或更新消息的卡片。
此要求不同于其他使用用户身份验证的 API,后者通常不要求应用是聊天室的成员。
replaceCards方法支持卡片替换和移除,您可以在替换卡片时添加其他卡片,但无法向尚未包含卡片的消息添加卡片。Chat 应用只能替换其附加到消息的卡片,而不能替换其他 Chat 应用附加的卡片。
如果用户修改了消息文本,则 Chat 应用拥有的卡片会被移除,您将无法再更新这些卡片。