Interaktive Karten erstellen und aktualisieren

In diesem Leitfaden wird beschrieben, wie Sie mit der Google Chat API Nachrichten mit interaktiven Karten im Namen von Nutzern erstellen, Karten an vorhandene Nachrichten anhängen und diese Karten asynchron aktualisieren.

Das Erstellen und Aktualisieren von Karten ist nützlich, wenn Sie Folgendes tun möchten:

  • Eine Karte posten, die eine Aufgabe oder externe Ressource im Namen eines Nutzers darstellt.
  • Sie können einer vorhandenen Nutzernachricht eine Karte anhängen, um interaktiven Kontext oder interaktive Arbeitsabläufe bereitzustellen.
  • Aktualisieren Sie den Status der Karte (z. B. von „Wird bearbeitet“ zu „Abgeschlossen“) basierend auf externen Ereignissen, ohne auf eine Nutzerinteraktion zu warten.
  • Aktualisieren Sie den Inhalt einer Karte in einer Nutzernachricht, z. B. eine Linkvorschau.

Vorbereitung

Node.js

Python

Java

Apps Script

Kartenmitteilung im Namen eines Nutzers erstellen

Wenn Sie eine Nachricht mit Karten im Namen eines Nutzers erstellen möchten, verwenden Sie die Nutzerauthentifizierung.

Geben Sie in Ihrer Anfrage Folgendes an, um die Nachricht zu erstellen:

  • Der Autorisierungsbereich chat.messages.create oder chat.messages.
  • Das Feld cardsV2 in der Ressource Message, das die Kartendaten enthält.
  • Die cardId für jede Karte, die für asynchrone Aktualisierungen erforderlich ist.

Das folgende Beispiel zeigt, wie Sie im Namen eines Nutzers eine Nachricht mit einer Karte erstellen:

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 Script

/**
 * 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);
  }
}

Karten im Namen eines Nutzers an eine vorhandene Nachricht anhängen

Wenn Sie Karten im Namen eines Nutzers an eine vorhandene Nachricht anhängen möchten, rufen Sie die Methode patch mit Nutzerauthentifizierung auf.

Wenn Sie einer Nachricht Karten anhängen möchten, geben Sie in Ihrer Anfrage Folgendes an:

  • Der Autorisierungsbereich chat.messages.
  • Die name der zu aktualisierenden Nachricht im Format spaces/{space}/messages/{message}.
  • updateMask ist auf cards_v2 gesetzt. Wenn Sie eine Nachricht mit Nutzerauthentifizierung aktualisieren, muss cards_v2 das einzige Feld in der Aktualisierungsmaske sein. Die Nachrichten text und cards_v2 können nicht in derselben Anfrage aktualisiert werden.
  • Das Feld cardsV2 in der Ressource Message, das die Kartendaten enthält.
  • Die cardId für jede Karte, die für nachfolgende asynchrone Aktualisierungen erforderlich ist.

Das folgende Beispiel zeigt, wie Sie im Namen eines Nutzers einer vorhandenen Nachricht eine Karte anhängen:

Node.js

/**
 * This sample shows how to attach a card to an existing message on behalf of a user.
 */
const {google} = require('googleapis');
const {auth} = require('google-auth-library');

async function main() {
  // Create a client with user credentials
  const authClient = await auth.getClient({
    scopes: ['https://www.googleapis.com/auth/chat.messages']
  });
  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,
    updateMask: 'cards_v2',
    requestBody: {
      cardsV2: [{
        cardId: 'unique-card-id',
        card: {
          header: {
            title: 'Card Title',
            subtitle: 'Card Subtitle'
          },
          sections: [{
            widgets: [{
              textParagraph: {
                text: 'This card was attached to an existing user message.'
              }
            }]
          }]
        }
      }]
    }
  };

  // Call the API
  const response = await chat.spaces.messages.patch(request);

  // Handle the response
  console.log(response.data);
}

main().catch(console.error);

Python

"""
This sample shows how to attach a card to an existing message on behalf of a user.
"""
from googleapiclient.discovery import build
import google.auth

def attach_card_to_message():
    # Create a client with user credentials
    scopes = ["https://www.googleapis.com/auth/chat.messages"]
    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().patch(
        name=message_name,
        updateMask="cards_v2",
        body={
            'cardsV2': [{
                'cardId': 'unique-card-id',
                'card': {
                    'header': {
                        'title': 'Card Title',
                        'subtitle': 'Card Subtitle'
                    },
                    'sections': [{
                        'widgets': [{
                            'textParagraph': {
                                'text': 'This card was attached to an existing user message.'
                            }
                        }]
                    }]
                }
            }]
        }
    ).execute()

    print(result)

if __name__ == "__main__":
    attach_card_to_message()

Java

/**
 * This sample shows how to attach a card to an existing message 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 AttachCardToMessage {
  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"));
    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 + "?updateMask=cards_v2");

    // Construct the card body
    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 was attached to an existing 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);

    Map<String, Object> message = new HashMap<>();
    message.put("cardsV2", Collections.singletonList(cardWithId));

    HttpRequest request = requestFactory.buildPatchRequest(url, new JsonHttpContent(jsonFactory, message));
    System.out.println(request.execute().parseAsString());
  }
}

Apps Script

/**
 * This sample shows how to attach a card to an existing message on behalf of a user.
 */
function attachCardToMessage() {
  const messageName = 'spaces/SPACE_NAME/messages/MESSAGE_ID';
  const url = `https://chat.googleapis.com/v1/${messageName}?updateMask=cards_v2`;

  const message = {
    cardsV2: [{
      cardId: 'unique-card-id',
      card: {
        header: {
          title: 'Card Title',
          subtitle: 'Card Subtitle'
        },
        sections: [{
          widgets: [{
            textParagraph: {
              text: 'This card was attached to an existing user message.'
            }
          }]
        }]
      }
    }]
  };

  const options = {
    method: 'patch',
    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 attach card: ' + err.message);
  }
}

Karten asynchron aktualisieren

Nachdem Sie eine Nachricht mit Karten erstellt oder Karten an eine vorhandene Nachricht angehängt haben, können Sie die Karten asynchron mit der App-Authentifizierung aktualisieren. So kann Ihre App den Karteninhalt aktualisieren, ohne dass der Nutzer eingreifen muss. Nur die Chat-App, die die Karte der Nachricht des Nutzers hinzugefügt hat, kann sie ersetzen. Wenn ein Nutzer den Nachrichtentext bearbeitet, werden die kartenbezogenen Karten entfernt und Ihre App kann sie nicht mehr aktualisieren.

Wenn Karten asynchron aktualisiert werden, wird in Google Chat neben der Quellenangabe der Karte der Hinweis Bearbeitet angezeigt, um Nutzer darüber zu informieren, dass der Karteninhalt unabhängig von der Nachricht aktualisiert wurde.

Rufen Sie zum Aktualisieren der Karten die Methode replaceCards mit den folgenden Parametern auf:

  • Der Autorisierungsbereich chat.bot.
  • Die name der zu aktualisierenden Mitteilung.
  • Die neue cardsV2-Liste. Dadurch werden alle vorhandenen Karten in der Nachricht ersetzt. Wenn Sie eine leere Liste angeben, werden die Karten entfernt. Wenn Sie alle Karten entfernen, können Sie sie nicht mit replaceCards wieder hinzufügen. Verwenden Sie stattdessen UpdateMessage mit Nutzerauthentifizierung, um neue Karten anzuhängen.

Das folgende Beispiel zeigt, wie die Karten einer Nachricht aktualisiert werden:

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 Script

/**
 * 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);
  }
}

Beschränkungen

  • Wenn Sie im Namen eines Nutzers Nachrichten mit Karten erstellen oder Karten aktualisieren, muss die Chat-App Mitglied des Gruppenbereichs sein. Diese Anforderung gilt, wenn:

    Diese Anforderung unterscheidet sich von anderen APIs, die die Nutzerauthentifizierung verwenden und bei denen die App in der Regel nicht Mitglied des Bereichs sein muss.

  • Wenn Sie eine Nachricht mit Nutzerauthentifizierung aktualisieren und cards_v2 in updateMask angegeben ist, können keine anderen Felder (z. B. text) in derselben Anfrage aktualisiert werden.

  • Die Methode replaceCards unterstützt das Ersetzen und Entfernen von Karten. Sie können beim Ersetzen auch zusätzliche Karten hinzufügen. Karten können jedoch nicht zu einer Nachricht hinzugefügt werden, die noch keine Karten enthält. Wenn Sie einer Nachricht, die keine Karten enthält, Karten anhängen möchten, verwenden Sie UpdateMessage mit Nutzerauthentifizierung.

  • Kartenattribution und ‑inhaberschaft:

    • Karten, die an eine Nutzernachricht angehängt sind, werden der Chat-App zugeordnet, die sie angehängt hat, und gehören dieser. Das wird durch das Nur-Ausgabe-Feld CardWithId.owner angegeben.
    • Die Chat-App kann nur Karten ersetzen, die sie an eine Nachricht angehängt hat, nicht Karten, die von anderen Chat-Apps angehängt wurden.
  • Wenn ein Nutzer den Nachrichtentext bearbeitet, werden die Karten der Chat-App entfernt und Sie können sie nicht mehr aktualisieren.