Build a Chat app with Google Cloud Functions

This page explains how to create and interact with a Chat app using Google Cloud Functions.

To build the app, you write and deploy a Cloud Function that the app uses to process a response to a message event from Google Chat. The response is a card that displays the sender's name and avatar image, as demonstrated in the following image:

Chat app responding with a card featuring the sender's display name and avatar
image

Objectives

  • Set up your environment.
  • Create and deploy a Cloud Function.
  • Publish the app to Google Chat.
  • Test the app.

Prerequisites

Set up the environment

Before using Google APIs, you need to turn them on in a Google Cloud project. You can turn on one or more APIs in a single Google Cloud project.
  • In the Google Cloud console, enable the Google Chat API, Cloud Build API, Cloud Functions API, and Cloud Pub/Sub API.

    Enable the APIs

Create and deploy a Cloud Function

Create and deploy a Cloud Function that generates a Chat card with the sender's display name and avatar image. When the Chat app receives a message, it runs the function and responds with the card.

To create and deploy the function for your Chat app, complete the following steps:

Node.js

  1. In the Google Cloud console, go to the Cloud Functions page:

    Go to Cloud Functions

    Make sure that the project for your Chat app is selected.

  2. Click Create Function.

  3. On the Create function page, set up your function:

    1. In Function name, enter "QuickStartChatApp".
    2. In Trigger type, select HTTP.
    3. Under Authentication, select Allow unauthenticated invocations.

      For more information about authentication in Google Workspace, see Authenticate and authorize Chat apps and API requests.

    4. Click Save.

    5. Click Next.

  4. In Runtime, select Node.js 10.

  5. In Source code, select Inline Editor.

  6. In Entry point, delete the default text and enter helloChat.

  7. Replace the contents of index.js with the following code:

    node/avatar-bot/index.js
    /**
     * Google Cloud Function that responds to messages sent from a
     * Hangouts Chat room.
     *
     * @param {Object} req Request sent from Hangouts Chat room
     * @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 is meant to be used in a Hangouts Chat ' +
          'Room.');
      }
    
      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},
      };
    
      const avatarSection = {
        widgets: [
          avatarWidget,
          avatarImageWidget,
        ],
      };
    
      return {
        cardsV2: [{
          cardId: 'avatarCard',
          card: {
            name: 'Avatar Card',
            header: cardHeader,
            sections: [avatarSection],
          }
        }],
      };
    }

  8. Click Deploy.

Python

  1. In the Google Cloud console, go to the Cloud Functions page:

    Go to Cloud Functions

    Make sure that the project for your Chat app is selected.

  2. Click Create Function.

  3. On the Create function page, set up your function:

    1. In Function name, enter "QuickStartChatApp".
    2. In Trigger type, select HTTP.
    3. Under Authentication, select Allow unauthenticated invocations.

      For more information about authentication in Google Workspace, see Authenticate and authorize Chat apps and API requests.

    4. Click Save.

    5. Click Next.

  4. In Runtime, select Python 3.10.

  5. In Source code, select Inline Editor.

  6. In Entry point, delete the default text and enter hello_chat.

  7. Replace the contents of main.py with the following code:

    python/avatar-bot/main.py
    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) -> Mapping[str, Any]:
      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 = {
          "cardsV2": [
              {
                  "cardId": "avatarCard",
                  "card": {
                      "name": "Avatar Card",
                      "header": header,
                      "sections": [avatar_section],
                  },
              }
          ]
      }
    
      return cards
    
    

  8. Click Deploy.

Java

  1. In the Google Cloud console, go to the Cloud Functions page:

    Go to Cloud Functions

    Make sure that the project for your Chat app is selected.

  2. Click Create Function.

  3. On the Create function page, set up your function:

    1. In Function name, enter "QuickStartChatApp".
    2. In Trigger type, select HTTP.
    3. Under Authentication, select Allow unauthenticated invocations.

      For more information about authentication in Google Workspace, see Authenticate and authorize Chat app and API requests.

    4. Click Save.

    5. Click Next.

  4. In Runtime, select Java 11.

  5. In Source code, select Inline Editor.

  6. In Entry point, delete the default text and enter HelloChat.

  7. Rename src/main/java/com/example/Example.java to src/main/java/HelloChat.java.

  8. Replace the contents of HelloChat.java with the following code:

    java/avatar-bot/src/main/java/HelloChat.java
    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;
    import java.util.List;
    
    public class HelloChat 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("message")) {
          response.getWriter().write("Hello! This function must be called from Google Chat.");
          return;
        }
    
        JsonObject sender = body.getAsJsonObject("message").getAsJsonObject("sender");
        String displayName = sender.has("displayName") ? sender.get("displayName").getAsString() : "";
        String avatarUrl = sender.has("avatarUrl") ? sender.get("avatarUrl").getAsString() : "";
        Message message = createMessage(displayName, avatarUrl);
    
        response.getWriter().write(gson.toJson(message));
      }
    
      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("previewLink");
        cardWithId.setCard(card);
    
        Message message = new Message();
        message.setCardsV2(List.of(cardWithId));
    
        return message;
      }
    }

  9. Replace the contents of pom.xml with the following code:

    java/avatar-bot/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>cloudfunctions</groupId>
      <artifactId>http-function</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <properties>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>com.google.cloud.functions</groupId>
          <artifactId>functions-framework-api</artifactId>
          <version>1.0.1</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 11 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. Click Deploy.

The Cloud Functions page opens, and your function appears with a deployment progress indicator next to the function name. When the progress indicator disappears and a checkmark appears, your function is deployed.

Publish the app to Google Chat

After the Cloud Function is deployed, follow these steps to turn it into a Google Chat app:

  1. In the Google Cloud console, click Menu > Cloud Functions.

    Go to Cloud Functions

    Make sure that the project for which you enabled Cloud Functions is selected.

  2. In the list of functions, click QuickStartChatApp.

  3. On the Function details page, click Trigger.

  4. Under Trigger URL, copy the URL.

  5. Search for "Google Chat API" and click Google Chat API.

  6. Click Manage.

  7. Click Configuration and set up the Google Chat app:

    1. In App name, enter Quickstart App.
    2. In Avatar URL, enter https://developers.google.com/chat/images/quickstart-app-avatar.png.
    3. In Description, enter Quickstart app.
    4. Under Functionality, select Receive 1:1 messages, Join spaces and group conversations, and Log errors to Cloud Logging.
    5. Under Connection settings, select App URL and paste the URL for the Cloud Function trigger into the box.
    6. Under Permissions, select Specific people and groups in your domain and enter your email address.
  8. Click Save.

The app is ready to receive and respond to messages on Google Chat.

Test your Chat app

To test your Chat app, send the app a direct message:

  1. Open Google Chat.
  2. To send a direct message to the app, click Start a chat , and in the window that appears, click Find apps.
  3. In the Find apps dialog, search for "Quickstart App".
  4. To open a direct message with the app, find the Quickstart App and click Add > Chat.
  5. In the direct message, type Hello and press enter.

The app returns a card with your display name and avatar picture.

Next steps

To troubleshoot and debug your Chat app, refer to these pages:

  • As you build the Chat app, you might need to debug it by reading the app's error logs. To read the logs, in the Google Cloud console, go to the Logs Explorer.
  • Troubleshoot.

To add more functionality to your Chat app, refer to these guides:

  • Create interactive cards — Card messages support a defined layout, interactive UI elements like buttons, and rich media like images. Use card messages to present detailed information, gather information from users, and guide users to take a next step.
  • Support slash commands — Slash commands let you register and advertise specific commands that users can give your app by typing a command that begins with a forward slash (/), like /help.
  • Launch dialogs — Dialogs are windowed, card-based interfaces that your app can open to interact with a user. Multiple cards can be strung together sequentially, which helps users complete multi-step processes, like filling in form data.

To learn more about the Google Chat API, view the reference documentation.