This guide details the architecture and step-by-step process for creating a secure, scalable, and asynchronous Google Chat bot using Google Cloud Platform services. This pattern is ideal for bots that need to perform long-running tasks (over 30 seconds) without timing out in the Google Chat interface.
- Google Chat API: The service that allows applications to receive and respond to events from Google Chat.
- Cloud Run: A fully managed serverless platform used to run our containerized application code. We use two services: one to receive the initial webhook (ingestor) and one to do the processing (worker).
- Pub/Sub: A serverless, asynchronous messaging service that decouples our ingestor from our worker. This is the key to avoiding the 30-second timeout.
- IAM (Identity and Access Management): Used to create dedicated service accounts and grant fine-grained, least-privilege permissions to each component of the architecture.
- Secret Manager: Provides secure storage for sensitive data like API keys, ensuring they are not exposed in code or environment variables.
- Cloud Build & Artifact Registry: Used to build our Python code into secure, reproducible container images and store them.
- A Google Cloud project with billing enabled.
- Permissions to create and manage the resources listed above (e.g., the Owner or Editor role for the project).
- The
gcloudcommand-line tool installed and authenticated to your project. - A local environment with Python and Docker installed to create the application code and build the container images.
First, the necessary APIs must be enabled for the Google Cloud project.
- Navigate to the "APIs & Services" > "Library" section in the Google Cloud Console.
- Search for and Enable each of the following APIs:
- Cloud Build API
- Cloud Run API
- Pub/Sub API
- Secret Manager API
- Artifact Registry API
- Google Chat API
- IAM API (Identity and Access Management)
Create three dedicated service accounts to ensure a least-privilege security posture.
- Navigate to "IAM & Admin" > "Service Accounts".
- Click "+ CREATE SERVICE ACCOUNT" for each of the following:
- Service Account 1:
- Name:
chat-ingestor-sa
- Name:
- Service Account 2:
- Name:
chat-worker-sa
- Name:
- Service Account 3:
- Name:
pubsub-push-sa
- Name:
- Service Account 1:
- For each account, click "CREATE AND CONTINUE", then "DONE". Do not assign any roles at this stage.
Next, create the messaging topic and a secret for the external API key.
- Navigate to "Security" > "Secret Manager".
- Click "+ CREATE SECRET".
- Name:
your-api-key - Secret value:
my-super-secret-key-123
- Name:
- Click "CREATE SECRET".
- Navigate to "Pub/Sub" > "Topics".
- Click "+ CREATE TOPIC".
- Topic ID:
chat-events
- Topic ID:
- Click "CREATE".
Grant the necessary permissions to the service accounts.
- Go to "Pub/Sub" > "Topics", select the
chat-eventstopic. - In the info panel on the right, go to the "PERMISSIONS" tab and click "+ ADD PRINCIPAL".
- New principal:
chat-ingestor-sa@[YOUR_PROJECT_ID].iam.gserviceaccount.com - Role:
Pub/Sub Publisher
- New principal:
- Click "SAVE".
- Go to "Secret Manager", select the
dummy-api-keysecret. - In the info panel, go to the "PERMISSIONS" tab and click "+ ADD PRINCIPAL".
- New principal:
chat-worker-sa@[YOUR_PROJECT_ID].iam.gserviceaccount.com - Role:
Secret Manager Secret Accessor
- New principal:
- Click "SAVE".
- Navigate to "IAM & Admin" > "IAM".
- Find the principal ending in
-compute@developer.gserviceaccount.com. - Click the pencil icon (Edit principal) for that row.
- Click "+ ADD ANOTHER ROLE".
- Role:
Cloud Build Service Account
- Role:
- Click "SAVE".
Create a repository to store the container images.
- Navigate to "Artifact Registry".
- Click "+ CREATE REPOSITORY".
- Name:
bot-poc-repo - Format: Select
Docker. - Location Type: Select
Region(e.g.,us-central1).
- Name:
- Click "CREATE".
This service receives, validates, and forwards the event.
- Prepare the Code: On CloudShell, create a directory named
chat-ingestorand add the three corresponding files (main.py,requirements.txt,Dockerfile) from the Code in the repository. - Build the Image: From a terminal inside the
chat-ingestordirectory, run the build command:gcloud builds submit --tag [YOUR_REGION]-docker.pkg.dev/[YOUR_PROJECT_ID]/bot-poc-repo/chat-ingestor:latest
- Deploy the Service (UI):
- Navigate to "Cloud Run" and click "+ CREATE SERVICE".
- Select "Deploy one revision from an existing container image".
- Click "SELECT" and find the
chat-ingestor:latestimage. - Service name:
chat-ingestor - Authentication: Select "Allow unauthenticated invocations".
- Expand "Containers, Volumes, Networking, Security".
- Go to the "SECURITY" tab and select the
chat-ingestor-saservice account. - Go to the "CONTAINERS" tab. Under "Environment Variables", click "+ ADD VARIABLE" and add:
GCP_PROJECT: Your Project IDPUB_SUB_TOPIC:chat-events
- Click "CREATE".
- Once deployed, copy the URL it provides.
Point the Chat App to the chat-ingestor service.
- Navigate to "APIs & Services" > "Google Chat API" and click the "Configuration" tab.
- Fill in the app details (App Name, Avatar URL, Description).
- Under "Connection settings", select "HTTP endpoint URL" and paste the
chat-ingestorURL you just copied. - Under "Visibility", add the users/groups who can test the app.
- Click "SAVE".
- IMPORTAN Do not create as an Add-on, uncheck this box
This service performs the long-running task.
- Prepare the Code: Create a new directory named
chat-workerin Cloud Shell and add the three corresponding files (main.py,requirements.txt,Dockerfile) from the Code repository. - Build the Image: From a terminal inside the
chat-workerdirectory, run the build command:gcloud builds submit --tag [YOUR_REGION]-docker.pkg.dev/[YOUR_PROJECT_ID]/bot-poc-repo/chat-worker:latest
- Deploy the Service (UI):
- Navigate to "Cloud Run" and click "+ CREATE SERVICE".
- Select the
chat-worker:latestimage. - Service name:
chat-worker - Authentication: Select "Require authentication".
- Ingress control: Select "Internal".
- Expand "Containers, Volumes, Networking, Security".
- Go to the "SECURITY" tab and select the
chat-worker-saservice account. - Go to the "CONTAINERS" tab. Under "Environment Variables", click "+ ADD VARIABLE" and add:
GCP_PROJECT: Your Project IDSECRET_ID:your-api-key
- Click "CREATE".
- Once deployed, copy its URL.
Connect Pub/Sub to the internal chat-worker service.
- Navigate to the main Cloud Run services list.
- Click the checkbox on the far left of the
chat-workerrow. - An Info panel will open on the right.
- Click the "PERMISSIONS" tab and then "+ ADD PRINCIPAL".
- New principal:
pubsub-push-sa@[YOUR_PROJECT_ID].iam.gserviceaccount.com - Role:
Cloud Run Invoker
- New principal:
- Click "SAVE".
- Navigate to "IAM & Admin" > "IAM".
- Click "+ GRANT ACCESS".
- New principal:
service-[YOUR_PROJECT_NUMBER]@gcp-sa-pubsub.iam.gserviceaccount.com - Role:
Service Account Token Creator
- New principal:
- Click "SAVE".
- Navigate to "Pub/Sub" > "Topics" and click on your
chat-eventstopic. - Go to the "SUBSCRIPTIONS" tab and click "+ CREATE SUBSCRIPTION".
- Subscription ID:
chat-worker-subscription - Delivery Type: Select "Push".
- Endpoint URL: Paste the
chat-workerURL from Phase 7. - Check the box for "Enable authentication".
- Service account: Select your
pubsub-push-saservice account.
- Subscription ID:
- Click "CREATE".
- Go to Google Chat and find your bot.
- Add it to a space (this should trigger a welcome message).
- Send it a direct message (e.g., "test").
- The bot should respond asynchronously with: "Hello, [Your Name]! This is your async reply. ... Response title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit'"
- If the bot shows "not responding", check the logs for the
chat-ingestorservice. - If you don't receive a reply, check the logs for the
chat-workerservice.