インタラクティブなカードを作成して更新する

このガイドでは、Google Chat API を使用して、ユーザーに代わってインタラクティブなカードを含むメッセージを作成する方法と、それらのカードを非同期的に更新する方法について説明します。

カードの作成と更新は、次のような場合に便利です。

  • ユーザーに代わって、タスクまたは外部リソースを表すカードを投稿します。
  • ユーザーの操作を待たずに、外部イベントに基づいてカードのステータス(「進行中」から「完了」など)を更新します。
  • リンクのプレビューなど、ユーザー メッセージのカードのコンテンツを更新します。

デベロッパー プレビュー プログラム以外では、ユーザー認証で作成されたメッセージにはテキストのみを含めることができます。

前提条件

Node.js

Python

Java

Apps Script

デベロッパー プレビュー機能にアクセスするための API キーを作成する

デベロッパー プレビュー API メソッドを呼び出すには、API ディスカバリ ドキュメントの非公開のデベロッパー プレビュー バージョンを使用する必要があります。リクエストを認証するには、API キーを渡す必要があります。

API キーを作成するには、アプリの Google Cloud プロジェクトを開いて次の操作を行います。

  1. Google Cloud コンソールで、メニュー > [API とサービス] > [認証情報] に移動します。

    [認証情報] に移動

  2. [認証情報を作成] > [API キー] をクリックします。
  3. 新しい API キーが表示されます。
    • [コピー] をクリックして、アプリのコードで使用する API キーをコピーします。API キーは、プロジェクトの認証情報の [API キー] セクションでも確認できます。
    • 不正使用を防ぐため、API キーを使用できる場所と対象の API を制限することをおすすめします。詳細については、API 制限を追加するをご覧ください。

ユーザーに代わってカード メッセージを作成する

ユーザーに代わってカード付きのメッセージを作成するには、ユーザー認証を使用します。

メッセージを作成するには、リクエストで次の情報を指定します。

  • 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 with Developer Preview labels
  const chat = await google.discoverAPI(
    'https://chat.googleapis.com/$discovery/rest?version=v1&labels=DEVELOPER_PREVIEW&key=API_KEY'
  );

  // 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 with Developer Preview labels.
    service = build(
        'chat',
        'v1',
        credentials=credentials,
        discoveryServiceUrl='https://chat.googleapis.com/$discovery/rest?version=v1&labels=DEVELOPER_PREVIEW&key=API_KEY'
    )

    # 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);
  }
}

カードを非同期で更新する

カードを含むメッセージを作成した後、アプリ認証を使用してカードを非同期的に更新できます。これにより、ユーザー操作なしでアプリがカードのコンテンツを更新できるようになります。カードをユーザーのメッセージに追加した 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 with Developer Preview labels
  const chat = await google.discoverAPI(
    'https://chat.googleapis.com/$discovery/rest?version=v1&labels=DEVELOPER_PREVIEW&key=API_KEY'
  );

  // 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 with Developer Preview labels.
    service = build(
        'chat',
        'v1',
        credentials=credentials,
        discoveryServiceUrl='https://chat.googleapis.com/$discovery/rest?version=v1&labels=DEVELOPER_PREVIEW&key=API_KEY'
    )

    # 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);
  }
}

制限事項

  • ユーザーに代わってカードを含むメッセージを作成したり、カードを更新したりする場合、Chat 用アプリはスペースのメンバーである必要があります。この要件は、次の場合に適用されます。

    この要件は、ユーザー認証を使用する他の API とは異なります。他の API では通常、アプリがスペースのメンバーである必要はありません。

  • replaceCards メソッドはカードの置き換えと削除をサポートしています。置き換え中にカードを追加できますが、カードがまだ含まれていないメッセージにカードを追加することはできません。

  • Chat 用アプリは、他の Chat 用アプリがメッセージに添付したカードではなく、自身がメッセージに添付したカードのみを置き換えることができます。

  • ユーザーがメッセージ テキストを編集すると、Chat 用アプリが所有するカードが削除され、更新できなくなります。