DEV Community

Cover image for Turn Google Docs Into an AI Agent Hub: Integrate ADK Agents in Google Workspace
Aryan Irani
Aryan Irani

Posted on

Turn Google Docs Into an AI Agent Hub: Integrate ADK Agents in Google Workspace

Series Roadmap:

Welcome back to the final part of our three-part tutorial series on building Google Workspace AI agents using the Agent Development Kit (ADK) and Vertex AI Agent Engine.

In the first two parts, we:
 ✅ Built an AI-powered Fact Verifier Agent using the ADK.
 ✅ Deployed it to Vertex AI Agent Engine, making it accessible via API.

Now in this third and final part, we'll connect everything together - bringing your deployed agent inside Google Docs. With a few lines of Apps Script, you'll transform a standard Google Doc into an AI-assisted editor that can analyze and fact-check content automatically using your deployed agent.

If your organization is looking to build custom Google Workspace Add-ons, integrate AI Agents with ADK, or develop agentic workflows using Gemini and Vertex AI, my team and I can help. We specialize in turning complex ideas into production-ready AI solutions for enterprise environments.
📩 Reach out to discuss your project - whether it's automating Workspace tools, enhancing data intelligence, or designing agent-driven workflows tailored to your needs.

Step1: Set Up Your Google Docs Environment

Start by opening a new or existing Google Document. From the menu, go to Extensions -> Apps Script to open the editor. We'll use this space to connect to the deployed ADK Agent. The Google Doc we are using for this tutorial contains the following contents: 

Step2: Add the Integration Code

You'll need two files in your Apps Script project for this setup:

  1. AIVertex.gs – Handles all communication with Vertex AI and the ADK Agent. 
  2. Code.gs – Controls the Google Docs interface, menus, and document actions.

Let's go through each one.

File 1: AIVertex.gs

This file handles everything related to your deployed agent - making authenticated API calls to both Vertex AI Agent Engine (for reasoning) and Gemini models (for output formatting).

const LOCATION = PropertiesService.getScriptProperties().getProperty('LOCATION');
const GEMINI_MODEL_ID = PropertiesService.getScriptProperties().getProperty('GEMINI_MODEL_ID');
const REASONING_ENGINE_ID = PropertiesService.getScriptProperties().getProperty('REASONING_ENGINE_ID');
const SERVICE_ACCOUNT_KEY = PropertiesService.getScriptProperties().getProperty('SERVICE_ACCOUNT_KEY');

const credentials = credentialsForVertexAI();

/**
 * @param {string} statement The statement to fact-check.
 */
function requestLlmAuditorAdkAiAgent(statement) {
  return UrlFetchApp.fetch(
    `https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${credentials.projectId}/locations/${LOCATION}/reasoningEngines/${REASONING_ENGINE_ID}:streamQuery?alt=sse`,
    {
      method: 'post',
      headers: { 'Authorization': `Bearer ${credentials.accessToken}` },
      contentType: 'application/json',
      muteHttpExceptions: true,
      payload: JSON.stringify({
        "class_method": "async_stream_query",
        "input": {
          "user_id": "google_sheets_custom_function_fact_check",
          "message": statement,
        }
      })
    }
  ).getContentText();
}

/**
 * @param {string} prompt The Gemini prompt to use.
 */
function requestOutputFormatting(prompt) {
  const response = UrlFetchApp.fetch(
    `https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${credentials.projectId}/locations/${LOCATION}/publishers/google/models/${GEMINI_MODEL_ID}:generateContent`,
    {
      method: 'post',
      headers: { 'Authorization': `Bearer ${credentials.accessToken}` },
      contentType: 'application/json',
      muteHttpExceptions: true,
      payload: JSON.stringify({
        "contents": [{
          "role": "user",
          "parts": [{ "text": prompt }]
        }],
        "generationConfig": { "temperature": 0.1, "maxOutputTokens": 2048 },
        "safetySettings": [
          {
            "category": "HARM_CATEGORY_HARASSMENT",
            "threshold": "BLOCK_NONE"
          },
          {
            "category": "HARM_CATEGORY_HATE_SPEECH",
            "threshold": "BLOCK_NONE"
          },
          {
            "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
            "threshold": "BLOCK_NONE"
          },
          {
            "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
            "threshold": "BLOCK_NONE"
          }
        ]
      })
    }
  );
  return JSON.parse(response).candidates[0].content.parts[0].text
}

/**
 * Gets credentials required to call Vertex API using a Service Account.
 * Requires use of Service Account Key stored with project.
 * 
 * @return {!Object} Containing the Google Cloud project ID and the access token.
 */
function credentialsForVertexAI() {
  const credentials = SERVICE_ACCOUNT_KEY;
  if (!credentials) {
    throw new Error("service_account_key script property must be set.");
  }

  const parsedCredentials = JSON.parse(credentials);

  const service = OAuth2.createService("Vertex")
    .setTokenUrl('https://oauth2.googleapis.com/token')
    .setPrivateKey(parsedCredentials['private_key'])
    .setIssuer(parsedCredentials['client_email'])
    .setPropertyStore(PropertiesService.getScriptProperties())
    .setScope("https://www.googleapis.com/auth/cloud-platform");
  return {
    projectId: parsedCredentials['project_id'],
    accessToken: service.getAccessToken(),
  }
}
Enter fullscreen mode Exit fullscreen mode

What this file does

  • Authenticates securely to Vertex AI using a Service Account key. Calls your deployed ADK Agent to analyze or fact-check the document text.
  • Uses Gemini for smart response formatting - making the results human-readable.

File 2: Code.gs

This file connects your Docs UI with the ADK logic above. It lets you trigger the audit directly from a custom Docs menu.

/**
 * Adds a custom menu in Google Docs to run the AI Audit directly.
 */
function onOpen() {
  DocumentApp.getUi()
    .createMenu('AI Audit Tools')
    .addItem('Run AI Audit', 'runAuditAndInsert')
    .addToUi();
}

/**
 * Returns the entire text content of the document.
 */
function getDocumentText() {
  const doc = DocumentApp.getActiveDocument();
  const body = doc.getBody();
  let text = body.getText();
  return text.trim();
}

/**
 * Runs the AI Audit and inserts the result as text at the end of the document.
 */
function runAuditAndInsert() {
  const docText = getDocumentText();
  const result = runAudit(docText);

  if (result) {
    const doc = DocumentApp.getActiveDocument();
    const body = doc.getBody();
    // Append the audit result as a new paragraph at the end of the document
    body.appendParagraph('AI Audit Result: ' + result);
  }
}

/**
 * Runs the AI Audit using ADK Agent and Gemini formatting.
 */
function runAudit(docText) {
  console.log('[INFO] Starting AI audit process...');
  if (!docText) {
    console.log('[WARN] No text in document.');
    return '⚠️ The document is empty. Please add some text to audit.';
  }

  // Check for excessive document length to avoid token limits
  if (docText.length > 10000) {
    console.log('[WARN] Document too long.');
    return '⚠️ Document exceeds 10,000 characters. Please shorten the text.';
  }

  console.log('[STEP] Sending text to ADK Agent...');
  const rawAudit = requestLlmAuditorAdkAiAgent(docText);

  // Check if rawAudit is an error message
  if (rawAudit.startsWith('ERROR:')) {
    console.error('[ERROR] ADK Agent returned error:', rawAudit);
    return rawAudit;
  }

  console.log('[STEP] Formatting AI response...');
  let formatted;
  try {
    formatted = requestOutputFormatting(
      `Here is a fact-checking result: ${rawAudit}.
       Summarize it. Keep the main verdict and reasoning. Remove markdown and make it concise.`
    );
  } catch (error) {
    console.error('[ERROR] Formatting failed:', error.toString());
    return `ERROR: Failed to format audit result - ${error.toString()}`;
  }

  console.log('[SUCCESS] Audit completed successfully.');
  console.log('[RESULT] Final Output:', formatted);
  return formatted;
}
Enter fullscreen mode Exit fullscreen mode

What this file does

  • Adds a custom menu in Google Docs called AI Audit Tools.
  • Grabs your document text and sends it to your ADK Agent for analysis.
  • Displays the AI-generated audit results back into the document.

Step 3: Add Script Properties

To connect your script to your deployed resources, go to:
Project Settings → Script Properties → Add Script Property

Add the following to your Script Properties
LOCATION: The region of your Vertex AI deployment us-central1 GEMINI_MODEL_ID: Gemini model to use gemini-2.5-flash-lite REASONING_ENGINE_ID: The deployed ADK Agent ID 1234567890 SERVICE_ACCOUNT_KEY: JSON key for the Service Account { "type": "service_account", ... }

Click Save script properties.

Step 4: Add the OAuth2 Library

Our Apps Script project needs the OAuth2 library for authenticating API calls.
To add it:

  1. Go to Services → Libraries
  2. Click Add a Library
  3. Enter the Script ID:

1B7FSrk5Zi6L1rS6Qm6C9q8Zs6z3jQm5iBv6-1iQ0gWA-2

Step 5: Test Your AI Agent in Google Docs

1.In the Apps Script editor, run the onOpen() function once. This will add a new AI Audit Tools menu in Google Docs.
2.Return to your Doc and click AI Audit Tools → Run AI Audit.

3.The script will send your document's text to the deployed ADK Agent for fact-checking.
4.The AI Audit Result will appear automatically at the end of your document.

Wrapping Up

You've now deployed your AI Agent, connected it to Google Docs, and seen it in action - analyzing, reasoning, and summarizing right where your content lives. What we've built here isn't just a standalone demo. It's the foundation for intelligent, agent-driven collaboration inside Google Workspace.

By combining ADK's reasoning capabilities with Gemini's generative models, we've effectively turned Google Docs into a living, thinking assistant - one that can read, audit, and refine your text with context.

But this is only the beginning. The same blueprint extends naturally across Sheets, Slides, Drive, and Gmail - anywhere you want AI to work with you, not just for you. Imagine agents that:

  • Audit financial data and flag inconsistencies in Sheets,
  • Auto-generate pitch decks and summaries in Slides,
  • Label and organize documents intelligently in Drive,
  • Or even draft and fact-check emails directly in Gmail.

This demonstration lays the groundwork for building agentic workflows that integrate seamlessly into your daily Workspace tools - turning static documents into dynamic AI collaborators.

You've just taken the first step toward the future of AI-native productivity - where every file, message, and meeting can think, reason, and evolve with you.

If you're ready to bring this level of intelligence into your own Workspace tools, we'd love to collaborate.

Top comments (0)