This tutorial shows you how to publish AI agents to Google Workspace as Google Workspace add-ons, using Apps Script or HTTP endpoints. After your publish your add-on, your users can interact with the AI agents within their workflows.
Google has released a comprehensive new tutorial that demonstrates how to bridge the gap between complex AI agents and the daily workflows of Google Workspace users. The Travel Concierge sample uses the Agent Development Kit (ADK) to deploy a conversational, multi-agent AI directly into the Google Workspace platform.
While many AI demos focus on standalone chat interfaces, this solution stands out by implementing the agent as a Google Workspace Add-on. This means the AI isn’t just a browser tab; it is a helpful sidebar accessible directly within Gmail, Calendar, Drive, Docs, Sheets, and Slides, as well as a fully functioning Google Chat app.
Key Features for Developers
The sample provides a robust blueprint for developers looking to build “agentic” workflows. Key capabilities include:
Multi-Agent Architecture: The solution uses Vertex AI to manage a “Travel Concierge” that orchestrates sub-agents for specific tasks, utilising tools like the Google Maps Platform Places API and Google Search Grounding.
Context Awareness: In applications like Gmail, the agent can read the context of the currently selected email to help plan trips based on actual correspondence.
Rich User Interfaces: The add-on moves beyond simple text, utilising the Card framework to display rich widgets and interactive elements.
Cross-Platform Persistence: User sessions are managed by Vertex AI, ensuring that a conversation started in Google Chat can be seamlessly continued in a Google Doc sidebar.
Flexible Implementation
The Apps Script implementation demonstrates how to connect a standard Workspace Add-on to the powerful Vertex AI backend using UrlFetchApp. It serves as an excellent reference for handling synchronous execution limits and rendering complex agent responses within the constraints of the Add-on sidebar.
Whether you are looking to build a travel planner or a complex enterprise assistant, this sample provides the architectural patterns needed to bring your AI agents to where your users actually work.
How to build a server-less crawler using Google Apps Script to create a unified knowledge base for AI-assisted development.
The Goal: A Unified Context for Gemini
When building Google Workspace add-ons, particularly those using newer features like Workspace Flows, the documentation is often spread across dozens of nested pages. While excellent for browsing, this structure presents a challenge when working with Large Language Models (LLMs) like Gemini.
The primary motivation for this project was to create a single, consolidated “Knowledge Doc” containing the complete technical specification for Workspace Flows. By feeding this unified document into Gemini, I can:
Control the Context: Ensure the model answers based on the specific, official documentation rather than outdated training data or hallucinated APIs.
Accelerate Development: Ask complex architectural questions (“How do I build a flow that integrates X and Y?”) and get answers grounded in the full API reference without the latency of multiple web searches.
Bridge the Knowledge Gap: Work effectively with brand-new products and services that haven’t yet been absorbed into the LLM’s core training set.
This article details how I built the tool to create this document—a server-less crawler that runs entirely within Google Apps Script. If you are less concerned about the how and more about the end result here is the [Shared] Google Workspace Flows Guide
The Technical Challenge: Apps Script vs. The DOM
My initial plan was straightforward:
Fetch the HTML of each documentation page.
Parse it into Markdown (using a library like Turndown or Showdown).
Convert that Markdown into a Google Doc.
However, I hit a major roadblock immediately. Most JavaScript parsing libraries rely on the DOM (window, document, DOMParser). Google Apps Script runs in a server-side environment (similar to a Node.js runtime but without standard packages) where no DOM exists. Libraries like Turndown crashed instantly with ReferenceError: document is not defined.
The Solution: A Hybrid HTML Pipeline
Instead of fighting to make a browser library work on the server, I pivoted to a hybrid approach:
Cheerio for Parsing: I used the Cheerio library (which parses HTML using pure JavaScript strings, no DOM required) to “clean” the content.
Direct HTML Injection: Instead of converting to Markdown (which lost formatting for tables and images), I switched to the Google Drive API which can natively convert HTML files into Google Docs.
This pipeline proved superior because it preserved:
Code Blocks:<pre> tags with specific formatting.
Tables: Complex data tables rendered perfectly.
Images:<img> tags with absolute URLs were automatically fetched and embedded by Google Drive.
Important Note: This script was developed and tested specifically for Google Workspace Flows documentation. Web scraping inherently carries the risk that the target website’s HTML structure may change over time. Other documentation sites will use different CSS classes and HTML structures. While the core logic (crawling + HTML cleaning + Docs conversion) remains valid, you will need to inspect the source of your target site and update the Cheerio selectors (like .devsite-article-body or .devsite-book-nav) to match its specific layout.
Step 1: The Crawler
First, we needed to find all the relevant pages. Traversing the DOM tree proved fragile—class names change, and nesting levels vary.
The robust solution was Path Filtering. We fetch the main navigation bar and simply filter for any link that starts with our target root URL.
functionextractLinksByPath(html, rootUrl) {
const $ = Cheerio.load(html);
const links = newSet();
$('.devsite-book-nav a').each(function() {
let href = $(this).attr('href');
if (href) {
if (href.startsWith('/')) href = CONFIG.BASE_URL + href;
if (href.startsWith(rootUrl) && !href.includes('#')) links.add(href);
}
});
returnArray.from(links);
}
Step 2: The HTML Cleaner
We couldn’t just dump the raw page HTML into a Doc; it would include navigation bars, “Feedback” buttons, and footer links. We used Cheerio to strip these out.
We also encountered a specific challenge with Definition Lists (<dl>, <dt>, <dd>). Google Docs doesn’t have a native “Definition List” element, so they often flattened into messy text.
The fix was to transform them into semantic HTML paragraphs with inline styling to force the visual layout we wanted:
Even with clean HTML, the Google Docs converter can be stubborn. It sometimes ignores semantic headings (<h1>) or allows images to overflow the page width.
To fix this, we added a post-processing step. After the HTML file is converted to a Google Doc, we open it with DocumentApp to programmatically enforce styles and constraints.
Fixing Headings: We scan for our specific “Title” styling (24pt Bold) and force the Heading 1 style.
functionapplyHeadingsToDoc(docId) {
const doc = DocumentApp.openById(docId);
const body = doc.getBody();
const paragraphs = body.getParagraphs();
paragraphs.forEach(p => {
const text = p.getText();
if (text.length === 0) return;
const fontSize = p.getAttributes().FONT_SIZE;
const isBold = p.getAttributes().BOLD;
// If it looks like a H1 (24pt + Bold), make it a H1!if (fontSize >= 24 && isBold) {
p.setHeading(DocumentApp.ParagraphHeading.HEADING1);
}
});
doc.saveAndClose();
}
Resizing Images: We also scan for images wider than the standard page width (e.g., 600px) and scale them down to fit, ensuring the document layout remains printable and clean.
Once generated, this document becomes the cornerstone of my development workflow:
Consolidate: I run the script to pull the latest documentation into a fresh Google Doc.
Enrich: I use tools like Gemini Deep Research to find community patterns, or architectural best practices and paste them directly into the same doc.
Contextualise: This single document is then uploaded to Gemini (or another LLM workspace), providing a focused, hallucination-resistant context for answering questions and generating code.
By combining the UrlFetchApp for crawling, Cheerio for parsing, and the Drive API for document generation, we built a custom scraping pipeline in under 200 lines of code without spinning up a single server. If you’d like to make your own feel free to copy this script project which comes with a compiled Apps Script friendly version of Cheerio
Google Workspace Flows is currently available as part of the Gemini Alpha program for Google Workspace customers. If you don’t have access to Workspace Flows you will need to request access via your Google Workspace Administrator.
As developers, we often find ourselves building complex automations to glue different services together. But with the introduction of Google Workspace Flows, Google is handing some of that power directly to business users, allowing them to string together tasks—like summarising emails or posting to Chat—without writing a single line of code.
But where does that leave us? Right in the driver’s seat.
While Flows provides a “no-code” interface for users, it offers a robust “code” backend for us. Developers can extend the platform by building custom steps, in Google Apps Script. These steps act as reusable building blocks that users can drop into their flows to perform specific, business-critical tasks that aren’t available out of the box.
If you have an existing Google Workspace Add-on, you can even extend its functionality to include these Flows steps. Since Google Workspace Flows is currently part of the Gemini Alpha program, custom steps are intended for internal use and testing within your own Google Workspace organization rather than public distribution. You can deploy them as test deployments or private add-ons for your domain, but a public listing is not yet supported.
Here is a high-level overview of how it works and where to find the documentation to get started.
The Anatomy of a Step
Building a custom step in Apps Script isn’t too dissimilar from building an Editor Add-on, but there are specific architectural differences to be aware of. A step essentially consists of three parts:
The Definition (Manifest): You define the step’s identity, required inputs, and expected outputs in the appsscript.json file.
The Configuration (UI): You build a card interface (using CardService) that allows the user to configure the step when they add it to their flow.
The Execution (Logic): You write the actual function that processes the inputs and returns the outputs.
Key Capabilities
The documentation provided by Google is comprehensive. Here are the key areas you should explore to understand what is possible:
1. Configuration Cards & Variables
Unlike a static settings page, configuration cards in Flows are dynamic. You can build cards that accept input variables from previous steps. For example, if a user has a “New Email” trigger, your step can ingest the email body as a variable.
2. Passing Data
Your step doesn’t just run in isolation; it talks to the rest of the flow. By defining output variables, your script can return data (like a calculated value or a file ID) that subsequent steps can use.
3. Robust Validation
To ensure users don’t break your script with bad data, Flows supports two types of validation. You can use Client-side validation (using Common Expression Language, or CEL) for instant feedback on the UI, or Server-side validation for complex checks against external databases.
4. Handling Complexity
For more advanced use cases, simple strings and integers might not be enough. The platform supports Custom Resources for grouping complex data structures (like a CRM lead object) and Dynamic Variables for inputs that change based on context (like selecting a specific question from a Google Form).
Getting Started
If you are part of the Gemini Alpha program and want to get your hands dirty, the best place to start is the Quickstart guide. It walks you through building a simple calculator step that takes two numbers and an operator to output a result.
A fact-check custom function for Google Sheets to be used as a bound Apps Script project powered by a Vertex AI agent and Gemini model.
This sample demonstrates how you can use two powerful types of AI resources directly into your Google Sheets spreadsheets
A new tutorial published by Google’s Pierrick Voulet, while ostensibly about creating a fact-checking tool in Google Sheets, offers something more valuable to developers: a clear framework for integrating powerful, multi-step Vertex AI Agents into Google Workspace solutions.
While the example is a FACT_CHECK custom function, the underlying architecture caught my eye as it provides a blueprint for connecting Google Workspace applications with the sophisticated reasoning capabilities of custom AI agents.
The Core Architectural Pattern
The solution uses Google Apps Script as a bridge between the user-facing application (Google Sheets) and the backend AI services on Google Cloud.
When a user calls the custom function, the script authenticates with a service account and makes a call to a deployed Vertex AI Agent. This agent then performs its multi-step reasoning. The result is then optionally passed to a Gemini model for final formatting before being returned to the Sheet.
This pattern is highly adaptable for various use cases, allowing developers to bring advanced Agentic AI into your own solutions.
Key Components for Developers
For developers looking to adapt this framework, the tutorial outlines the essential components:
A configured Google Cloud Project with the Vertex AI API enabled.
A deployed ADK Agent on the Vertex AI Agent Engine.
An Apps Script project using a service account for secure, server-to-server authentication with Google Cloud.
The provided Apps Script code (Code.gs and AiVertex.js) serves as a robust starting point, handling the API calls to both the reasoning agent and a Gemini model for final output formatting.
Ultimately, the fact-checking tool serves as an excellent proof of concept. The true value for the developer community, however, lies in the architectural blueprint it provides. This tutorial offers a clear model for integrating multi-step AI reasoning into Google Workspace add-ons, opening the door to a new class of intelligent applications.
As of February 20, 2025, the Rhino runtime is deprecated. Scripts running on Rhino will continue to function until January 31, 2026, after which they will no longer execute. Please migrate your scripts to the V8 runtime before this date. Refer to Migrate scripts to the V8 runtime.
Attention Google Workspace Developers!
A recent email to Google Workspace administrators announced the upcoming retirement of the Rhino runtime for Apps Script. As also highlighted in the Apps Script release notes, all Apps Script projects still using the Rhino runtime must be migrated to the V8 runtime by January 31, 2026, to avoid execution issues.
What this means for Workspace Developers:
If you are a Workspace developer, even if you don’t have an administrator role, it’s crucial to check your Apps Script projects for Rhino runtime usage. The email to administrators included a CSV file listing affected projects, with details such as:
Script URL, Script ID, Last Updated: Identifies the specific script.
Creator Email, Owner Email: Identifies the script’s originators.
Incompatibility Reason: Explains why the script needs migration.
Execution Count: Shows how often the script is used.
Additional Information: Includes opt-out status, library dependencies, etc.
Suggested Actions for Developers:
Non-Admins: You might want to contact your Workspace administrator to find out if any of your or your colleague Apps Script projects are on the list of affected scripts and ask for guidance on the migration process.
Third-Party Developers: You may want to proactively reach out to your customers to inform them of the upcoming changes, offer assistance with the migration, and ensure their scripts are updated before the deadline to prevent any disruption in their services.
Workspace Admins: Review the CSV file to identify your affected scripts, prioritize migrating scripts with high usage first to minimize user disruption, and understand the specific issues that need to be addressed in each script.
Important Considerations:
Google provides a migration guide and support resources to assist with the transition. In particular, it is worth noting that:
For Apps Script web apps and Google Workspace Add-ons “[You] must create a new version of the script with the V8 adjustments. To make the V8 version available to users, you must re-publish the script with this version.”
When updating standalone scripts to run on the V8 runtime, “you need to provide users at least view access to the script in order for the script’s triggers to work properly.”
It’s also important to note that while the V8 runtime generally offers performance advantages, there have been some reports of specific instances where performance with JDBC connectors might not be as efficient as in the Rhino runtime.
So don’t delay, start migrating your Apps Script projects today!
You can apply to join the Google Workspace Developer Preview Program to get early access to certain features. Features in developer preview have already completed early development phases, so they’re ready for implementation. This program gives you the chance to shape the final stages of feature development with feedback, get pre-release support, and have your integration ready for public use on launch day.
The Google Workspace Developer Preview Program (DPP) gives you early access to new features. If you are developing Google Workspace products and solutions, it’s a great way to stay ahead of the curve and provide feedback before feature release. Anyone can apply to join the DPP, just follow the source link, but note that you can’t enroll with a gmail.com account.
New Google Chart Card UI has just been added for buttons, chips, collapsible sections, and overflow menus. These additions extend the capability of Google Chat, allowing the possibility for users to interact with external tools and services without leaving the chat and continually having to context switch.
The public documentation page includes a list of all active developer previews. While these pages don’t offer visuals of the features, existing DPP members received a nice set of visuals in the email update. This example includes chips and a customizable control button for a collapsible section:
I’d highly recommend registering for the DPP so you can see what is coming in Google Workspace.
To subscribe to events using Apps Script, you can now use the Advanced Google Workspace Events service.
In the May 02, 2024 Google Apps Script release notes it was announced that a new Advanced Google Workspace Events service is available to let developers use the Google Workspace Events API directly in Google Apps Script. The Google Workspace Events API is a relatively new API, which was released to developer preview in January, 2024. The Google Workspace Events API uses a subscription model to handle resource changes. When you create a subscription, you specify the target resource (such as a Google Chat space or Google Meet meeting space) and the event types that you want to subscribe to. The API then sends notifications to your specified endpoint whenever an event occurs for that resource and event type.
In the case of the new Advanced Google Workspace Events service the linked documentation includes samples for using the new service with Google Chat. It’s worth noting that the Advanced Google Workspace Events service is designed specifically on managing subscriptions to events. While it lets you to control the flow of information and manage event subscriptions in your Apps Script projects, the actual processing and handling of event data occurs separately.
The linked documentation page provides sample code as well as outlines all the prerequisites.
This tutorial shows how to make a Google Chat app that answers questions based on conversations in Chat spaces with generative AI powered by Vertex AI with Gemini. The Chat app uses the Google Workspace Events API plus Pub/Sub to recognize and answer questions posted in Chat spaces in real time, even when it isn’t mentioned.
Here is another great tutorial from the Google Chat DevRel team, this time showcasing how the Google Workspace Events API and some new Google Chat UI elements can be used to turn a Chat space into a Gemini Pro powered knowledge base.
The sample solution will let you consume your Chat space message history into a Firestore database. The Chat app is an intelligent agent that can then monitor for new questions and make suggestions using Gemini to generate content based on the previous messages.
This tutorial shows how to make a Google Chat app that a team can use to manage projects in real time. The Chat app uses Vertex AI to help teams write user stories (which represent features of a software system from the point of view of a user for the team to develop) and persists the stories in a Firestore database.
A recent episode of Totally Unscripted delved into “going beyond basic bots”, highlighting a couple of Google Chat app tutorials from the Google Developer documentation. One example, the “project management” Chat App, is worth mentioning in a Pulse post.
While this example uses Google Cloud Functions instead of Google Apps Script, as discussed in the episode, both approaches share many similarities. Deploying the project management app involves several steps, but I believe it’s a worthwhile investment to learn how to combine different solutions for building Google Workspace integrations. For developers seeking to expand their Google Workspace Add-on capabilities, this example serves as a valuable reference.
If you’re interested in using Firestore for data management but prefer Google Apps Script, Justin Poehnelt’s post on “Using Firestore in Apps Script.” is a great resource. This post provides a basic Firestore wrapper and links to other relevant Apps Script/Firestore libraries.
The v3 of the Google Drive API has actually been around for a number of years launched on December 14, 2015. One of the reasons Google introduced version 3 was it came with performance improvements.
My impression is that the gap between the v2 and v3 has narrowed over the years with minor release updates, but there are still some areas where you can get more from the v3 API. One example reported by Kanshi Tanaike is to query Google Drive files by createdTime.
Google provide a Drive API v2 & v3 comparison guide, which highlights the main differences between the two versions of the API. To use v3 in your Apps Script project when you enable the Advanced Service for Drive you can select the version number.