HTTP Google Chat アプリを作成する

このページでは、HTTP サービスを使用して Google Chat で動作する Google Workspace アドオンを作成する方法について説明します。Google Chat では、アドオンは Google Chat アプリとしてユーザーに表示されます。詳細については、Google Chat の拡張機能の概要をご覧ください。

このクイックスタートでは、Google Cloud サービスを使用して HTTP サービスを構築する方法について説明します。Chat アプリを作成するには、Chat アプリがユーザーのメッセージに応答するために使用する Cloud Functions の関数を作成してデプロイします。

HTTP アーキテクチャでは、次の図に示すように、HTTP を使用して Google Cloud またはオンプレミス サーバーと統合するように Chat を構成します。

オンプレミス サーバーでウェブサービスを使用している Chat アプリのアーキテクチャ。

上の図では、HTTP Chat アプリを操作しているユーザーの情報フローは次のとおりです。

  1. ユーザーが、ダイレクト メッセージまたは Chat スペースで Chat アプリにメッセージを送信します。
  2. HTTP リクエストが、Chat アプリのロジックを含むクラウドまたはオンプレミス システムであるウェブサーバーに送信されます。
  3. 必要に応じて、Chat アプリのロジックを Google Workspace サービス(カレンダーやスプレッドシートなど)、他の Google サービス(マップ、YouTube、Vertex AI など)、または他のウェブサービス(プロジェクト管理システムやチケット ツールなど)と統合できます。
  4. ウェブサーバーは、Chat の Chat アプリ サービスに HTTP レスポンスを返します。
  5. レスポンスがユーザーに配信されます。
  6. 必要に応じて、Chat アプリは Chat API を呼び出して、メッセージを非同期的に投稿したり、他のオペレーションを実行したりできます。

このアーキテクチャでは、これらの Chat アプリをさまざまなプログラミング言語を使用して設計できるため、システムにすでに存在する既存のライブラリとコンポーネントを柔軟に使用できます。

目標

  • 環境をセットアップする。
  • Cloud Functions の関数を作成してデプロイします。
  • Chat アプリ用に Google Workspace アドオンを構成します。
  • アプリをテストします。

前提条件

環境を設定する

Google API を使用する前に、Google Cloud プロジェクトで API を有効にする必要があります。1 つの Google Cloud プロジェクトで 1 つ以上の API を有効にできます。
  • Google Cloud コンソールで、Google Chat API、Cloud Build API、Cloud Functions API、Cloud Pub/Sub API、Cloud Logging API、Artifact Registry API、Cloud Run API を有効にします。

    API を有効にする

Cloud 関数を作成してデプロイする

送信者の表示名とアバター画像を含む Chat カードを生成する Cloud Functions の関数を作成してデプロイします。Chat アプリがメッセージを受信すると、関数を実行してカードで応答します。

Chat アプリの関数を作成してデプロイする手順は次のとおりです。

Node.js

  1. Google Cloud コンソールで、[Cloud Functions] ページに移動します。

    Cloud Functions に移動

    Chat アプリのプロジェクトが選択されていることを確認します。

  2. [ 関数を作成] をクリックします。

  3. [関数の作成] ページで、関数を設定します。

    1. [環境] で、[Cloud Run 関数] を選択します。
    2. [関数名] に「AddOnChatApp」と入力します。
    3. [リージョン] でリージョンを選択します。
    4. [認証] で [認証を要求する] を選択します。
    5. [次へ] をクリックします。
  4. [ランタイム] で、最新バージョンの Node.js を選択します。

  5. [ソースコード] で [インライン エディタ] を選択します。

  6. [エントリ ポイント] で、デフォルトのテキストを削除して avatarApp と入力します。

  7. index.js の内容を次のコードに置き換えます。

    /**
     * Google Cloud Function that responds to messages sent from a
     * Google Chat space.
     *
     * @param {Object} req Request sent from Google Chat space
     * @param {Object} res Response to send back
     */
    exports.avatarApp = function avatarApp(req, res) {
        if (req.method === 'GET' || !req.body.chat) {
            return res.send('Hello! This function is meant to be used ' +
                'in a Google Chat Space.');
        }
    
        // Stores the Google Chat event as a variable.
        const chatMessage = req.body.chat.messagePayload.message;
    
        // Replies with the sender's avatar in a card.
        const displayName = chatMessage.sender.displayName;
        const avatarUrl = chatMessage.sender.avatarUrl;
        res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
            text: 'Here\'s your avatar',
            cardsV2: [{
                cardId: 'avatarCard',
                card: {
                    name: 'Avatar Card',
                    header: {
                        title: `Hello ${displayName}!`,
                    },
                    sections: [{
                        widgets: [{
                            textParagraph: { text: 'Your avatar picture: ' }
                        }, {
                            image: { imageUrl: avatarUrl }
                        }]
                    }]
                }
            }]
        }}}}});
    };
    
  8. [デプロイ] をクリックします。

Python

  1. Google Cloud コンソールで、[Cloud Functions] ページに移動します。

    Cloud Functions に移動

    Chat アプリのプロジェクトが選択されていることを確認します。

  2. [ 関数を作成] をクリックします。

  3. [関数の作成] ページで、関数を設定します。

    1. [環境] で、[Cloud Run 関数] を選択します。
    2. [関数名] に「AddOnChatApp」と入力します。
    3. [リージョン] でリージョンを選択します。
    4. [認証] で [認証を要求する] を選択します。
    5. [次へ] をクリックします。
  4. [ランタイム] で、最新バージョンの Python を選択します。

  5. [ソースコード] で [インライン エディタ] を選択します。

  6. [エントリ ポイント] で、デフォルトのテキストを削除して avatar_app と入力します。

  7. main.py の内容を次のコードに置き換えます。

    from typing import Any, Mapping
    
    import flask
    import functions_framework
    
    @functions_framework.http
    def avatar_app(req: flask.Request) -> Mapping[str, Any]:
        """Google Cloud Function that handles requests from Google Chat
    
        Args:
            flask.Request: the request
    
        Returns:
            Mapping[str, Any]: the response
        """
        if req.method == "GET":
            return "Hello! This function must be called from Google Chat."
    
        request_json = req.get_json(silent=True)
    
        # Stores the Google Chat event as a variable.
        chat_message = request_json["chat"]["messagePayload"]["message"]
    
        # Replies with the sender's avatar in a card.
        display_name = chat_message["sender"]["displayName"]
        avatar_url = chat_message["sender"]["avatarUrl"]
        return { "hostAppDataAction": { "chatDataAction": { "createMessageAction": { "message": {
            "text": "Here's your avatar",
            "cardsV2": [{
                "cardId": "avatarCard",
                "card": {
                    "name": "Avatar Card",
                    "header": { "title": f"Hello {display_name}!" },
                    "sections": [{
                        "widgets": [{
                            "textParagraph": { "text": "Your avatar picture:" }
                        }, {
                            "image": { "imageUrl": avatar_url }
                        }]
                    }]
                }
            }]
        }}}}}
    
  8. [デプロイ] をクリックします。

Java

  1. Google Cloud コンソールで、[Cloud Functions] ページに移動します。

    Cloud Functions に移動

    Chat アプリのプロジェクトが選択されていることを確認します。

  2. [ 関数を作成] をクリックします。

  3. [関数の作成] ページで、関数を設定します。

    1. [環境] で、[Cloud Run 関数] を選択します。
    2. [関数名] に「AddOnChatApp」と入力します。
    3. [リージョン] でリージョンを選択します。
    4. [認証] で [認証を要求する] を選択します。
    5. [次へ] をクリックします。
  4. [ランタイム] で、最新バージョンの Java を選択します。

  5. [ソースコード] で [インライン エディタ] を選択します。

  6. [エントリ ポイント] で、デフォルトのテキストを削除して AvatarApp と入力します。

  7. デフォルトの Java ファイルの名前を src/main/java/AvatarApp.java に変更します。

  8. AvatarApp.java の内容を次のコードに置き換えます。

    import java.util.List;
    
    import com.google.api.services.chat.v1.model.CardWithId;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1Card;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1CardHeader;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1Image;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1Section;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1TextParagraph;
    import com.google.api.services.chat.v1.model.GoogleAppsCardV1Widget;
    import com.google.api.services.chat.v1.model.Message;
    import com.google.cloud.functions.HttpFunction;
    import com.google.cloud.functions.HttpRequest;
    import com.google.cloud.functions.HttpResponse;
    import com.google.gson.Gson;
    import com.google.gson.JsonObject;
    
    public class AvatarApp implements HttpFunction {
        private static final Gson gson = new Gson();
    
        @Override
        public void service(HttpRequest request, HttpResponse response) throws Exception {
            JsonObject body = gson.fromJson(request.getReader(), JsonObject.class);
            if (request.getMethod().equals("GET") || !body.has("chat")) {
                response.getWriter().write("Hello! This function is meant to be used " +
                    "in a Google Chat Space..");
                return;
            }
    
            // Stores the Google Chat event as a variable.
            JsonObject chatMessage = body.getAsJsonObject("chat")
                .getAsJsonObject("messagePayload").getAsJsonObject("message");
    
            // Replies with the sender's avatar in a card.
            String displayName = chatMessage.getAsJsonObject("sender").get("displayName").getAsString();
            String avatarUrl = chatMessage.getAsJsonObject("sender").get("avatarUrl").getAsString();
            Message message = createMessage(displayName, avatarUrl);
    
            JsonObject createMessageAction = new JsonObject();
            createMessageAction.add("message", gson.fromJson(gson.toJson(message), JsonObject.class));
    
            JsonObject chatDataAction = new JsonObject();
            chatDataAction.add("createMessageAction", createMessageAction);
    
            JsonObject hostAppDataAction = new JsonObject();
            hostAppDataAction.add("chatDataAction", chatDataAction);
    
            JsonObject dataActions = new JsonObject();
            dataActions.add("hostAppDataAction", hostAppDataAction);
            response.getWriter().write(gson.toJson(dataActions));
        }
    
        Message createMessage(String displayName, String avatarUrl) {
            GoogleAppsCardV1CardHeader cardHeader = new GoogleAppsCardV1CardHeader();
            cardHeader.setTitle(String.format("Hello %s!", displayName));
    
            GoogleAppsCardV1TextParagraph textParagraph = new GoogleAppsCardV1TextParagraph();
            textParagraph.setText("Your avatar picture: ");
    
            GoogleAppsCardV1Widget avatarWidget = new GoogleAppsCardV1Widget();
            avatarWidget.setTextParagraph(textParagraph);
    
            GoogleAppsCardV1Image image = new GoogleAppsCardV1Image();
            image.setImageUrl(avatarUrl);
    
            GoogleAppsCardV1Widget avatarImageWidget = new GoogleAppsCardV1Widget();
            avatarImageWidget.setImage(image);
    
            GoogleAppsCardV1Section section = new GoogleAppsCardV1Section();
            section.setWidgets(List.of(avatarWidget, avatarImageWidget));
    
            GoogleAppsCardV1Card card = new GoogleAppsCardV1Card();
            card.setName("Avatar Card");
            card.setHeader(cardHeader);
            card.setSections(List.of(section));
    
            CardWithId cardWithId = new CardWithId();
            cardWithId.setCardId("avatarCard");
            cardWithId.setCard(card);
    
            Message message = new Message();
            message.setText("Here's your avatar");
            message.setCardsV2(List.of(cardWithId));
    
            return message;
        }
    }
    
  9. pom.xml の内容を次のコードに置き換えます。

    <project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.google.chat</groupId>
        <artifactId>avatar-app</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.target>17</maven.compiler.target>
            <maven.compiler.source>17</maven.compiler.source>
        </properties>
    
        <dependencies>
            <dependency>
            <groupId>com.google.cloud.functions</groupId>
            <artifactId>functions-framework-api</artifactId>
            <version>1.0.4</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>2.9.1</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-chat -->
            <dependency>
                <groupId>com.google.apis</groupId>
                <artifactId>google-api-services-chat</artifactId>
                <version>v1-rev20230115-2.0.0</version>
            </dependency>
        </dependencies>
    
        <!-- Required for Java functions in the inline editor -->
        <build>
            <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                <excludes>
                    <exclude>.google/</exclude>
                </excludes>
                </configuration>
            </plugin>
            </plugins>
        </build>
    </project>
    
  10. [デプロイ] をクリックします。

Cloud Functions の詳細ページが開き、関数と 2 つの進行状況インジケーター(ビルド用とサービス用)が表示されます。両方の進行状況インジケーターが消えてチェックマークに置き換えられると、関数はデプロイされ、準備が整います。

Google Chat に関数の呼び出しを許可する

Google Workspace アドオンが関数を呼び出すことを許可するには、Cloud Run 起動元ロールを持つ Google Workspace アドオン サービス アカウントを追加します。

  1. Google Cloud コンソールで [Cloud Run] ページに移動します。

    Cloud Run に移動します

  2. Cloud Run サービスリストで、受信側関数の横にあるチェックボックスをオンにします。(関数自体はクリックしないでください)。

  3. [権限] をクリックします。[権限] パネルが開きます。

  4. [プリンシパルを追加] をクリックします。

  5. [新しいプリンシパル] に、プロジェクトに関連付けられている Google Workspace アドオン サービス アカウントのメールアドレスを入力します。

  6. [ロールを選択] で、[Cloud Run] > [Cloud Run 起動元] を選択します。

  7. [保存] をクリックします。

アドオンを構成する

Cloud Functions の関数をデプロイしたら、次の手順でアドオンを作成し、Google Chat アプリをデプロイします。

  1. Google Cloud コンソールで、メニュー アイコン > [Cloud Functions] をクリックします。

    Cloud Functions に移動

    Cloud Functions を有効にしたプロジェクトが選択されていることを確認します。

  2. 関数のリストで [AddOnChatApp] をクリックします。

  3. [トリガー] タブをクリックします。

  4. [HTTPS] で URL をコピーします。

  5. 「Google Chat API」を検索し、[Google Chat API]、[管理] の順にクリックします。

    Chat API に移動

  6. [構成] をクリックして、Google Chat アプリを設定します。

    1. [アプリ名] に「Add-on Chat app」と入力します。
    2. [アバターの URL] に「https://developers.google.com/chat/images/quickstart-app-avatar.png」と入力します。
    3. [説明] に「Add-on Chat app」と入力します。
    4. [機能] で、[1:1 のメッセージを受信する] と [スペースとグループの会話に参加する] を選択します。
    5. [接続設定] で [HTTP エンドポイント URL] を選択し、Cloud Functions トリガーの URL をボックスに貼り付けます。
    6. [Authentication Audience] で [HTTP エンドポイント URL] を選択します。
    7. [公開設定] で、ドメイン内の [この Google Chat アプリを特定のユーザーとグループに公開する] を選択し、メールアドレスを入力します。
    8. [ログ] で [エラーを Logging にロギング] を選択します。
  7. [保存] をクリックします。

Chat アプリは、Chat でメッセージを受信して返信できるようになりました。

Chat 用アプリをテストする

Chat アプリをテストするには、Chat アプリでダイレクト メッセージ スペースを開き、メッセージを送信します。

  1. 信頼できるテスターとして自分自身を追加したときに指定した Google Workspace アカウントを使用して Google Chat を開きます。

    Google Chat に移動

  2. [ 新しいチャット] をクリックします。
  3. [1 人以上を追加] フィールドに、Chat アプリの名前を入力します。
  4. 検索結果から Chat アプリを選択します。ダイレクト メッセージが開きます。

  5. そのアプリの新しいダイレクト メッセージに、「Hello」と入力して enter を押します。

Chat アプリのメッセージには、次の図に示すように、送信者の名前とアバター画像を表示するカードが含まれています。

送信者の表示名とアバター画像を表示したカードで返信する Chat アプリ

信頼できるテスターを追加し、インタラクティブな機能のテストについて詳しくは、Google Chat アプリのインタラクティブな機能をテストするをご覧ください。

トラブルシューティング

Google Chat アプリまたはカードからエラーが返されると、Chat インターフェースに「エラーが発生しました」というメッセージが表示されます。または「リクエストを処理できません」というメッセージが表示されます。Chat UI にエラー メッセージが表示されない場合でも、Chat アプリまたはカードで予期しない結果が生成されることがあります(カード メッセージが表示されないなど)。

チャット UI にエラー メッセージが表示されない場合でも、チャットアプリのエラー ロギングがオンになっている場合は、エラーの修正に役立つ説明的なエラー メッセージとログデータが利用できます。エラーの表示、デバッグ、修正については、Google Chat エラーのトラブルシューティングと修正をご覧ください。

クリーンアップ

このチュートリアルで使用したリソースに対して Google Cloud アカウントで課金されないようにするには、Cloud プロジェクトを削除することをおすすめします。

  1. Google Cloud コンソールで、[リソースの管理] ページに移動します。メニュー > [IAM と管理] > [リソースを管理] をクリックします。

    Resource Manager に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。