HomeAbout MeBook a Call

Build a Real Time Meeting Summarizer with Gemini and Google Workspace

By Vo Tu Duc
May 21, 2026
Build a Real Time Meeting Summarizer with Gemini and Google Workspace

That familiar dread after a call is the “post-meeting tax” killing your team’s momentum. It’s time to stop manually deciphering notes and start automatically turning conversations into action.

image 0

The Post-Meeting Productivity Bottleneck

The virtual confetti has settled, the video call has ended, and a familiar sense of dread creeps in. You’re left with a scattered collection of cryptic notes, a hazy memory of who agreed to what, and the looming task of synthesizing an hour of complex conversation into something coherent and actionable. This is the post-meeting tax—a hidden cost on our time, focus, and momentum. It’s the “meeting after the meeting,” where productivity grinds to a halt as we manually piece together summaries, delegate tasks from memory, and chase down clarifications. This manual, error-prone process is a fundamental bottleneck in modern collaboration.

From Manual Notes to Automated Intelligence

For decades, the solution to this problem was manual and deeply flawed. The frantic scramble to type notes while simultaneously trying to participate divides our attention and diminishes the quality of our contributions.

image 1

What if we could delegate this entire cognitive burden to a system designed for it? This is the leap we’re about to make: from simple transcription—just words on a page—to genuine, automated intelligence. We aim to build a system that doesn’t just hear, but understands. It will parse the nuances of conversation, identify key themes, and extract concrete outcomes, freeing up the human participants to do what they do best: connect, create, and solve complex problems.

Our Goal: A Real-Time Summarizer Powered by Gemini

In this article, we are architecting an intelligent agent that effectively attends our meetings for us. Our goal is to build a system that captures a meeting’s audio stream and, by the time the call ends, has already produced a comprehensive, structured summary.

This isn’t just a raw transcript. We’re aiming for a polished, multi-faceted document containing:

  • A concise executive summary: The key highlights and purpose of the meeting at a glance.

  • Key Decisions: A bulleted list of all major decisions made, including the context or rationale behind them.

  • Action Items: A structured table of tasks, clearly assigned to individuals with any mentioned deadlines.

The engine driving this transformation is Google’s Gemini model. Its advanced reasoning, massive context window, and multimodal capabilities make it uniquely suited to understand the nuanced, free-flowing nature of human conversation and distill it into valuable, structured information. The summary isn’t generated hours later; it’s ready the second you click “Leave meeting.”

The Tech Stack At a Glance

To bring this vision to life, we’ll orchestrate a suite of powerful Google Cloud and Workspace services. Think of it as a digital assembly line for productivity, where each component plays a critical role. Here’s a high-level overview of the tools we’ll be wiring together:

  • Audio Source ← Google Meet: The starting point. We’ll devise a method to securely capture the audio from our live meeting for processing.

  • Transcription ← Google Cloud Speech-to-Text: The “ears” of our system. This service will provide a highly accurate, real-time transcription of the spoken conversation, including speaker diarization (identifying who said what).

  • Orchestration ← Google Cloud Functions: The central nervous system. This serverless function will act as the glue, receiving the transcript data, passing it to the AI model, and directing the final output.

  • Intelligence ← Gemini API (via [Building Self Correcting Agentic Workflows with Building Self-Correcting Agentic Workflows with Vertex AI](https://votuduc.com/building-self-correcting-agentic-workflows-with-vertex-ai-p-20260321542526)): The “brain” of the operation. We will send the full meeting transcript to Gemini with a carefully crafted prompt, instructing it to summarize, extract decisions, and identify action items.

  • Output ← Google Docs API: The final report. Our Cloud Function will use the Workspace APIs to automatically create a new Google Doc, format the summary from Gemini, and save it in a designated Drive folder for easy sharing.

Solution Architecture: How It All Connects

Before we dive into the code, let’s zoom out and look at the blueprint for our real-time summarizer. This isn’t a single, monolithic application but rather a clever orchestration of several powerful Google services, with [AI Powered Cover Letter [Automated Job Creation in Real Time Jobber and Google Sheets Integration from Gmail](https://votuduc.com/Automated-Job-Creation-in-Jobber-from-Gmail-p115606) Engine](https://votuduc.com/AI-Powered-Cover-Letter-Automated Quote Generation and Delivery System for Jobber-Engine-p111092) acting as the central conductor and Gemini as the brain. The entire workflow is designed to be serverless, efficient, and deeply integrated within the [Automatically create new folders in Google Drive, generate templates in new folders, fill out text automatically in new files, and save info in [Automated Web Scraping with [Multilingual Text-to-Speech Tool with SocialSheet Streamline Your Social Media Posting 123](https://votuduc.com/Multilingual-Text-to-Speech-Tool-with-Google-Workspace-p809282)](https://votuduc.com/Automated-Web-Scraping-with-Google-Sheets-p292968)](https://workspace.google.com/marketplace/app/auto_create_folder_and_files/430076014869) ecosystem you already use.

The data flows in a logical sequence:

  1. Capture: Google Meet generates a live transcript and saves it directly into a Google Doc.

  2. Poll & Process: A time-driven Genesis Engine AI Powered Content to Video Production Pipeline periodically reads the new content from the Google Doc.

  3. Summarize: The script sends the raw transcript to the Gemini 3.5 Pro API for analysis and summarization.

  4. Deliver: Once the meeting concludes, the script takes the final summary from Gemini, formats it, and emails it to the attendees using the Gmail API.

Let’s break down each of these stages in more detail.

Capturing Live Transcriptions with the Google Docs API

The foundation of our system is the raw data: the meeting transcript. Fortunately, Google Meet has a built-in feature that transcribes meeting audio and saves it to a Google Doc in real-time. This provides us with a structured, timestamped, and continuously updated data source without needing to build a complex audio ingestion pipeline.

Our role isn’t to create this transcript, but to consume it. This is where the Google Docs API, accessed via Apps Script’s native DocumentApp service, comes into play. Our script will be granted permission to read the contents of the specific document linked to the meeting. It will periodically poll this document—say, every few minutes—to fetch the entire text body. By comparing the current text with the text from the previous check, it can identify new conversational chunks to process. This polling mechanism turns a static document into a dynamic, live feed for our summarization engine.

Real-Time Processing and Summarization with Gemini 3.5 Pro

This is where the magic happens. Once our Apps Script has a fresh chunk of the transcript, it needs to make sense of it. Simply appending text isn’t enough; we need intelligent summarization. We will make a direct API call from our Apps Script to the Gemini 3.5 Pro model.

Why Gemini 3.5 Pro?

  • Massive Context Window: It can handle very long transcripts without losing track of the conversation’s context from beginning to end. This is crucial for multi-hour meetings.

  • Speed and Efficiency: It provides a rapid response, which is essential for a “real-time” feel.

  • Advanced Reasoning: It excels at extracting not just the gist of a conversation but also key entities like decisions, action items, and unresolved questions.

The script will package the entire transcript into a carefully crafted prompt. The [Prompt Engineering for Reliable Autonomous Workspace Agents for Reliable Autonomous Workspace Agents](https://votuduc.com/prompt-engineering-for-reliable-autonomous-workspace-agents-p-20260319404106) here is key to getting high-quality results. We won’t just ask it to “summarize this.” Instead, we’ll instruct it to perform specific tasks.

Here is a conceptual example of what our system prompt might look like:


You are an expert meeting assistant. Your task is to analyze the provided meeting transcript and generate a concise, structured summary.

From the transcript, you MUST extract the following information and format your response in Markdown:

1.  **Executive Summary:** A brief, one-paragraph overview of the entire meeting's purpose and outcome.

2.  **Key Decisions Made:** A bulleted list of all concrete decisions that were agreed upon. If no decisions were made, state "No key decisions were made."

3.  **Action Items:** A bulleted list of all tasks assigned to individuals. Each item must be prefixed with the assignee's name (e.g., "- [Alex] Complete the Q3 budget report.").

4.  **Open Questions:** A list of any topics or questions that were left unresolved and require follow-up.

Analyze the full transcript provided to ensure your summary is comprehensive and accurate.

The model’s structured response (in Markdown, as requested) is then sent back to our Apps Script, ready for the final delivery stage.

Automating Delivery via Apps Script and the Gmail API

The final piece of the puzzle is delivering the polished summary to the right people. [Architecting Multi Tenant AI Workflows in Building Modular Agentic Apps Script with Gemini Function Calling](https://votuduc.com/architecting-multi-tenant-ai-workflows-in-google-apps-script-p-20260321290501) serves as the ultimate Automated Work Order Processing for UPS glue. Running on Google’s infrastructure, it can be triggered by time, events, or manual execution.

Once the meeting is over and the final summary has been generated by Gemini, our script will use the built-in GmailApp service. This service provides a simple yet powerful way to compose and send emails directly from our script, acting on behalf of the user who authorized it.

The script will perform these final steps:

  1. Identify Recipients: It can integrate with the Google Calendar API to fetch the attendee list from the original meeting event.

  2. Format the Email: It will construct a professional-looking HTML email. The subject line will be clear (e.g., “Meeting Summary: Project Phoenix Sync”), and the body will contain the clean, Markdown-formatted summary received from Gemini.

  3. Send: With a single GmailApp.sendEmail() call, the summary is dispatched to all attendees, ensuring everyone is on the same page, even if they couldn’t attend.

This entire end-to-end process, from live transcription in a Doc to an AI-generated summary in your inbox, is fully automated, creating a seamless and powerful productivity tool within the AC2F Streamline Your Google Drive Workflow environment.

Prerequisites and Initial Setup

Before we dive into the code, we need to lay the groundwork. This involves setting up a Google Cloud project to manage our APIs and configuring our Apps Script environment where our logic will live. This is a critical step; a proper foundation prevents a world of headaches later on.

Configuring Your Google Cloud Project

While Apps Script can run in a simplified, default environment, connecting it to a standard Google Cloud Platform (GCP) project unlocks powerful capabilities, including access to the Gemini API. It also provides a centralized place for managing permissions and monitoring usage.

  1. Create a New Google Cloud Project

If you don’t already have one you’d like to use, start by creating a new project.

  • Navigate to the Google Cloud Console.

  • In the top navigation bar, click the project selector dropdown and select “NEW PROJECT”.

  • Give your project a descriptive name, such as Gemini-Meeting-Summarizer. The project ID will be automatically generated.

  • Click “CREATE”.

  1. Enable Billing for Your Project

The Gemini API is a premium service. While Google Cloud offers a generous free tier, you must have a billing account linked to your project to use it.

  • In the Cloud Console, open the navigation menu (the “hamburger” icon) and select “Billing”.

  • Follow the prompts to either link an existing billing account or create a new one.

  • Ensure the billing account is associated with your Gemini-Meeting-Summarizer project.

  1. Link Your Apps Script to the GCP Project

Now, we need to tell our Apps Script project to use the standard GCP project we just configured instead of its default, hidden one.

  • Open your Apps Script project.

  • Click on the Project Settings (gear icon ⚙️) in the left-hand sidebar.

  • Scroll down to the “Google Cloud Platform (GCP) Project” section.

  • Click “Change project”.

  • Paste your GCP Project Number (you can find this on your Google Cloud Console Dashboard) into the text field.

  • Click “Set project”. You’ll be asked to confirm; proceed with the confirmation.

Enabling Necessary APIs Docs Gmail and Gemini

With our project configured, we need to grant it permission to access the specific Google services our script will use. Think of this as flipping the power switches for each tool in our toolkit.

Navigate to “APIs & Services” > “Library” in your Google Cloud Console. You’ll use the search bar to find and enable each of the following APIs.

  1. Google Docs API

This API is essential for programmatically creating and editing the Google Docs that will hold our meeting summaries.

  • Search for Google Docs API.

  • Select it from the results and click “ENABLE”.

  1. Gmail API

We’ll use the Gmail API to access meeting details or transcripts sent to your inbox.

  • Search for Gmail API.

  • Select it and click “ENABLE”.

  1. Vertex AI API

This is the main event. The Vertex AI API is the gateway to Google’s powerful suite of AI models, including Gemini. This is how our script will send prompts and receive summaries.

  • Search for Vertex AI API.

  • Select it and click “ENABLE”. It may take a few minutes to provision.

After enabling these, your project is now authorized to use the core services required for our summarizer.

Setting Up Your Apps Script Environment

Finally, let’s get our actual script file ready. This involves creating the project and modifying its manifest file to declare the permissions (OAuth scopes) our script will request from the user.

  1. Create a Standalone Apps Script Project
  • Navigate to script.google.com.

  • Click ”+ New project” in the top-left corner.

  • Give your project a name by clicking on “Untitled project”. A good name would be Real Time Meeting Summarizer.

  1. Configure the appsscript.json Manifest File

The manifest is a critical configuration file that defines our script’s behavior and required permissions.

  • In the Apps Script editor, click the Project Settings (gear icon ⚙️).

  • Check the box that says “Show ‘appsscript.json’ manifest file in editor”.

  • Return to the Editor view. You will now see an appsscript.json file.

  • Replace the entire content of that file with the following JSON. This explicitly lists the permissions our script will need to function.


{

"timeZone": "America/New_York",

"dependencies": {},

"exceptionLogging": "STACKDRIVER",

"runtimeVersion": "V8",

"oauthScopes": [

"https://www.googleapis.com/auth/script.scriptapp",

"https://www.googleapis.com/auth/documents",

"https://www.googleapis.com/auth/gmail.readonly",

"https://www.googleapis.com/auth/cloud-platform"

]

}

  • timeZone: Adjust this to your local timezone.

  • oauthScopes: This is the most important part. We are telling Google that our script needs permission to:

  • Run as a script (script.scriptapp).

  • Access Google Docs (documents).

  • Read Gmail messages (gmail.readonly).

  • Connect to Google Cloud services, like Vertex AI (cloud-platform).

Save the manifest file (Ctrl+S or Cmd+S). With these steps complete, our entire environment is configured and ready for us to start building the core logic.

Step 1 Capturing the Live Transcription Stream

The foundation of our real-time summarizer is its ability to access the meeting’s conversation as it happens. Google Meet offers a fantastic feature that transcribes a meeting in real-time and saves it directly to a Google Doc. Our first task is to tap into this data stream. We will use Automating Technical Debt Audits in Apps Script with AI Agents, a serverless JavaScript platform tightly integrated with Automated Client Onboarding with Google Forms and Google Drive., to read the content of this transcription document as it updates. This approach is efficient, secure, and requires no external servers.

Authenticating with the Google Docs API

Before we can write any code, our script needs permission to read Google Docs files. Google Apps Script simplifies this process immensely. Unlike a standalone application that would require a complex OAuth 2.0 flow, Apps Script manages authentication based on the user who authorizes and runs the script.

When you use a built-in service like DocumentApp, Apps Script automatically identifies the necessary permissions (scopes). The very first time you run a function that accesses user data, Google will present a consent screen. By granting permission on this screen, you authorize the script to act on your behalf, securely connecting it to the Google Docs API without you having to manage API keys or client secrets.

There are no manual setup steps required for authentication itself. You simply write the code, run it, and approve the permission request when prompted. The script will then execute with the necessary authorization.

Creating an Apps Script Function to Read Document Content

Now, let’s write the core function to retrieve the text from our transcription document. We’ll use the DocumentApp service, which is the standard, high-level way to interact with Google Docs in Apps Script.

  1. Navigate to script.google.com to open the Apps Script editor.

  2. Create a new project and give it a name like “Gemini Meeting Summarizer”.

  3. Replace the boilerplate code in the Code.gs file with the following function:


/**

* Reads and returns the entire text content of a Google Doc.

*

* @param {string} documentId The unique ID of the Google Document.

* @return {string | null} The full text content of the document, or null on error.

*/

function getTranscriptionText(documentId) {

if (!documentId) {

console.error("Document ID was not provided.");

return null;

}

try {

// Open the document using its ID

const doc = DocumentApp.openById(documentId);

// Get the main body of the document

const body = doc.getBody();

// Return all the text within the body as a single string

const fullText = body.getText();

return fullText;

} catch (e) {

// Log any errors, e.g., if the document doesn't exist or permissions are denied

console.error("Failed to read document: " + e.toString());

return null;

}

}

/**

* A helper function to test our primary function from the editor.

*/

function testGetTranscription() {

// IMPORTANT: Replace this placeholder with the ID of a real Google Doc you can access.

// The ID is found in the document's URL:

// docs.google.com/document/d/DOCUMENT_ID/edit

const testDocId = 'YOUR_DOCUMENT_ID_HERE';

const text = getTranscriptionText(testDocId);

if (text !== null) {

console.log("Successfully read document content:");

console.log(text);

}

}

This code defines a simple yet powerful function, getTranscriptionText. It takes a documentId as input, uses DocumentApp.openById() to access the file, and returns its entire text content with getBody().getText(). The test function allows you to run it directly from the editor to verify it’s working.

Implementing a Trigger to Poll for Updates

A meeting transcript is a living document. We can’t just read it once; we need to check it repeatedly for new content. This process is called polling. Sending the entire transcript to our summarization model every time would be incredibly inefficient. Instead, we’ll implement a smarter polling mechanism that only processes the new text added since the last check.

We’ll use two key Apps Script features:

  1. Time-driven Triggers: To automatically run our polling function on a set schedule.

  2. Properties Service: A simple key-value store to save state between executions, allowing us to remember what text we’ve already processed.

First, add the following code to your Code.gs file. This function will manage the state and identify new text.


// --- Add this code to your existing Code.gs file ---

// Store the ID of the document you want to monitor at the top for easy access.

// This will be the document created by Google Meet for transcription.

const TRANSCRIPTION_DOC_ID = 'YOUR_TRANSCRIPTION_DOC_ID_HERE';

/**

* Polls the transcription document for new text and processes it.

* This is the function our trigger will execute.

*/

function pollForUpdates() {

// Use ScriptProperties to store state between runs

const properties = PropertiesService.getScriptProperties();

const lastProcessedText = properties.getProperty('lastProcessedText') || '';

const currentText = getTranscriptionText(TRANSCRIPTION_DOC_ID);

if (currentText === null) {

console.error("Halting poll due to error reading document.");

return; // Exit if there was an error

}

// Check if new text has been added

if (currentText.length > lastProcessedText.length) {

// Isolate the newly added text

const newText = currentText.substring(lastProcessedText.length);

console.log("New transcription segment found:");

console.log(newText);

// =================================================================

// PLACEHOLDER: In the next step, we will send `newText`

// to the Gemini API for summarization.

// =================================================================

// Update the property with the full current text for the next run

properties.setProperty('lastProcessedText', currentText);

} else if (currentText.length < lastProcessedText.length) {

// This can happen if the doc is manually edited or reset.

// We'll reset our state to match the document.

console.warn("Document content has shrunk. Resetting processing state.");

properties.setProperty('lastProcessedText', currentText);

}

// If lengths are the same, do nothing.

}

/**

* A utility function to manually reset the stored state.

* Useful for debugging or restarting the summarization process.

*/

function resetState() {

PropertiesService.getScriptProperties().deleteProperty('lastProcessedText');

console.log("Stored processing state has been reset.");

}

With the code in place, let’s set up the trigger:

  1. In the Apps Script editor, click the Triggers icon (looks like a clock) in the left sidebar.

  2. Click the + Add Trigger button in the bottom-right corner.

  3. Configure the trigger with the following settings:

  • Choose which function to run: pollForUpdates

  • Choose which deployment should run: Head

  • Select event source: Time-driven

  • Select type of time-based trigger: Minutes timer

  • Select minute interval: Every minute

  1. Click Save.

You will be prompted to authorize the script again, this time for the permissions required to run automatically in the background. Once saved, your pollForUpdates function will execute every minute, check the Google Doc for new text, and log any new transcription segments it finds. We now have a reliable stream of the meeting’s conversation, ready to be fed into our AI model.

Step 2: Generating Summaries with Gemini 3.5 Pro

With our transcript in hand, we’ve reached the core of our project: transforming raw conversation into structured, intelligent insights. This is where the magic of Gemini 3.5 Pro comes into play. Its large context window is perfect for handling lengthy meeting transcripts, and its JSON mode is a game-changer for getting predictable, structured output that our application can easily work with.

Structuring the Prompt for Effective Summarization

The quality of your summary is directly proportional to the quality of your prompt. A well-crafted prompt acts as a precise set of instructions for the model, guiding it to produce the exact output format you need. We’ll use a combination of a system prompt and a user prompt.

The system prompt sets the stage. It tells Gemini its role, the context, and the rules it must follow. Critically, we will instruct it to respond only in a specific JSON format. This eliminates the need for messy string parsing and makes our output reliable.

Here is the system prompt we’ll use. Notice how we define a clear JSON schema with fields for a title, a concise summary, key decisions, and a list of action items with assigned owners.


const SYSTEM_PROMPT = `

You are an expert meeting summarizer. Your task is to analyze a meeting transcript and provide a structured summary in JSON format.

The user will provide the full meeting transcript.

Based on the transcript, you MUST generate a JSON object with the following schema:

&#123;

"title": "A concise, engaging title for the meeting.",

"summary": "A 3-5 sentence paragraph summarizing the key topics and outcomes of the meeting.",

"key_decisions": [

"A list of key decisions made during the meeting."

],

"action_items": [

&#123;

"owner": "The name of the person assigned the task. If no one is explicitly assigned, use 'Unassigned'.",

"task": "A clear description of the action item."

&#125;

],

"sentiment": "A single word describing the overall sentiment of the meeting (e.g., 'Positive', 'Neutral', 'Constructive', 'Tense')."

&#125;

Do not include any text, explanations, or markdown formatting before or after the JSON object. Your entire response must be a single, valid JSON object.

`;

The user prompt is much simpler. It will just be the raw meeting transcript we captured in the previous step. By separating the instructions (system) from the data (user), we create a clean and effective request.

Calling the Gemini API from Apps Script with the Transcript

Now, let’s write the Apps Script function to send our transcript and prompt to the Gemini API. This involves constructing an HTTP POST request using Apps Script’s built-in UrlFetchApp service.

First, ensure you have your Gemini API key stored securely, for instance, using Apps Script’s Properties Service. For this example, we’ll assume it’s stored in a variable API_KEY.

Create a new function, generateSummary, which will take the transcript text as an argument.


// Add this function to your Code.gs file

/**

* Generates a meeting summary using the Gemini API.

* @param {string} transcript The full meeting transcript text.

* @return {object|null} The parsed JSON summary object, or null on failure.

*/

function generateSummary(transcript) {

const API_KEY = "YOUR_GEMINI_API_KEY"; // Replace with your actual API key

const API_ENDPOINT = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent?key=" + API_KEY;

// The payload combines our system prompt and the user-provided transcript

const payload = {

"contents": [

{

"role": "user",

"parts": [

{ "text": SYSTEM_PROMPT },

{ "text": transcript }

]

}

],

"generationConfig": {

"response_mime_type": "application/json", // Enable JSON Mode

"temperature": 0.5,

"maxOutputTokens": 2048

},

"safetySettings": [ // Adjust safety settings as needed for your use case

{

"category": "HARM_CATEGORY_HATE_SPEECH",

"threshold": "BLOCK_MEDIUM_AND_ABOVE"

},

{

"category": "HARM_CATEGORY_DANGEROUS_CONTENT",

"threshold": "BLOCK_MEDIUM_AND_ABOVE"

},

{

"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",

"threshold": "BLOCK_MEDIUM_AND_ABOVE"

},

{

"category": "HARM_CATEGORY_HARASSMENT",

"threshold": "BLOCK_MEDIUM_AND_ABOVE"

}

]

};

const options = {

'method': 'post',

'contentType': 'application/json',

'payload': JSON.stringify(payload),

'muteHttpExceptions': true // Important for handling API errors gracefully

};

try {

const response = UrlFetchApp.fetch(API_ENDPOINT, options);

const responseCode = response.getResponseCode();

const responseBody = response.getContentText();

if (responseCode === 200) {

Logger.log("Successfully received summary from Gemini API.");

// The response body itself is a JSON string, which we'll parse next

return responseBody;

} else {

Logger.log(`Error calling Gemini API. Status: ${responseCode}, Body: ${responseBody}`);

return null;

}

} catch (e) {

Logger.log(`Exception during API call: ${e.message}`);

return null;

}

}

Key things to note in this code:

  1. API_ENDPOINT: We’re targeting the gemini-1.5-pro-latest model.

  2. payload: We structure the contents to provide both the system prompt and the transcript in a single user turn. This is a common and effective pattern.

  3. generationConfig: We explicitly set response_mime_type to "application/json". This activates Gemini’s JSON mode, which forces the model to adhere to the schema we defined in our prompt.

  4. muteHttpExceptions: Setting this to true prevents our script from crashing on a non-200 response (like a 400 or 500 error). Instead, it allows our code to inspect the response code and body, enabling more robust error handling.

Parsing the JSON Response for Key Insights and Action Items

The generateSummary function returns a JSON string from the API. However, the summary data we want is nested inside this response. Our final step is to parse this string and extract the clean, structured data we asked for.

The Gemini API response has a specific structure. The actual content generated by the model is located at candidates[0].content.parts[0].text. Because we used JSON mode, the value of text will be a string that contains the JSON summary. This means we need to parse it twice!

Let’s create a helper function to handle this parsing logic.


// Add this function to your Code.gs file

/**

* Parses the raw JSON response from the Gemini API to extract the summary object.

* @param {string} apiResponseText The raw JSON string from the API call.

* @return {object|null} The parsed summary object, or null if parsing fails.

*/

function parseGeminiResponse(apiResponseText) {

if (!apiResponseText) {

Logger.log("API response text is empty. Cannot parse.");

return null;

}

try {

// First parse: Get the main API response structure

const apiResponseObject = JSON.parse(apiResponseText);

// Check for safety ratings and blocks

if (apiResponseObject.candidates && apiResponseObject.candidates[0].finishReason === 'SAFETY') {

Logger.log("Response was blocked due to safety settings.");

return null;

}

// Navigate to the generated content

const summaryJsonString = apiResponseObject.candidates[0].content.parts[0].text;

// Second parse: Get our actual summary object from the text field

const summaryObject = JSON.parse(summaryJsonString);

Logger.log("Successfully parsed summary object.");

return summaryObject;

} catch (e) {

Logger.log(`Failed to parse JSON response: ${e.message}`);

Logger.log(`Raw response received: ${apiResponseText}`);

return null;

}

}

Now you can tie it all together. You’d call generateSummary with your transcript, then pass the result to parseGeminiResponse.


// Example usage:

function processMeeting() {

const transcript = "Alice: Let's start the project kickoff... Bob: I agree, the deadline for the design mockups should be next Friday. Charlie: I can take that action item.";

const rawApiResponse = generateSummary(transcript);

const meetingSummary = parseGeminiResponse(rawApiResponse);

if (meetingSummary) {

Logger.log(`Meeting Title: ${meetingSummary.title}`);

Logger.log(`Summary: ${meetingSummary.summary}`);

meetingSummary.action_items.forEach(item => {

Logger.log(`Action Item: ${item.task} (Owner: ${item.owner})`);

});

} else {

Logger.log("Failed to generate or parse meeting summary.");

}

}

With these functions in place, we have a robust system for sending a transcript to Gemini and receiving a perfectly structured JSON object in return. We’ve successfully converted unstructured conversation into actionable data, ready to be presented to the user. In the next step, we’ll take this structured data and use it to automatically create a clean, formatted Google Doc.

Step 3 Delivering the Minutes via Gmail

With the intelligent summary from Gemini in hand, the final piece of the puzzle is delivery. A raw text file or a log entry is useful, but not actionable for the team. We need to push this summary directly into the workflow of the meeting attendees. And what’s more central to corporate workflow than email?

This is where the seamless integration of Automated Discount Code Management System services truly shines. We’ll use Google Apps Script’s native GmailApp service to format our summary into a professional HTML email and send it to all attendees automatically. No external email APIs, no complex SMTP configurations—just a few lines of code.

Formatting the Summary into a Clean HTML Email

Plain text emails are functional, but they lack the structure and readability needed for meeting minutes. A well-formatted HTML email can separate key sections, highlight action items, and present a much more professional report.

We’ll create a helper function that takes our meeting data and Gemini’s summary and constructs an HTML string. We’ll use basic inline CSS for styling to ensure maximum compatibility across different email clients (like Outlook, Apple Mail, etc.).

Gemini often returns summaries formatted with Markdown (using * for lists or ** for bold). We’ll also create a simple utility function to convert this basic Markdown into the corresponding HTML tags (&lt;ul&gt;, &lt;li&gt;, &lt;b&gt;).

Let’s add these two functions to our Code.gs script:


/**

* Converts a basic Markdown string to HTML.

* Handles bold (**text**) and unordered lists (* item).

* @param {string} markdownText The text with Markdown formatting.

* @return {string} The converted HTML string.

*/

function markdownToHtml(markdownText) {

let html = markdownText

.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>') // Bold

.replace(/^\* (.*$)/gm, '<ul><li>$1</li></ul>'); // Unordered lists

// Clean up adjacent list tags

html = html.replace(/<\/ul>\s?<ul>/g, '');

return html.replace(/\n/g, '<br />'); // Replace newlines with <br>

}

/**

* Creates a formatted HTML body for the summary email.

* @param {string} meetingTitle The title of the meeting.

* @param {string[]} attendees An array of attendee email addresses.

* @param {string} geminiSummary The AI-generated summary (in Markdown).

* @return {string} A complete HTML string for the email body.

*/

function createEmailBody(meetingTitle, attendees, geminiSummary) {

const summaryHtml = markdownToHtml(geminiSummary);

const attendeeList = attendees.join(', ');

// Using inline CSS for best email client compatibility

const htmlBody = `

<div style="font-family: Arial, sans-serif; font-size: 14px; color: #333;">

<h1 style="color: #202124; border-bottom: 1px solid #ddd; padding-bottom: 10px;">

Meeting Summary: ${meetingTitle}

</h1>

<p>

<strong>Attendees:</strong> ${attendeeList}

</p>

<h2 style="color: #202124;">

AI-Generated Minutes

</h2>

<div style="background-color: #f8f9fa; border: 1px solid #ddd; border-radius: 8px; padding: 16px; line-height: 1.6;">

${summaryHtml}

</div>

<p style="font-size: 12px; color: #888; margin-top: 20px;">

This summary was automatically generated by a Gemini-powered Google Apps Script.

</p>

</div>

`;

return htmlBody;

}

This code gives us a reusable and clean way to generate a polished email body. The markdownToHtml function handles the most common formatting we’ll get from Gemini, and createEmailBody assembles the final report.

Using the GmailApp Service to Send the Report

Now for the main event: sending the email. The GmailApp service in Apps Script makes this incredibly straightforward. We’ll use the sendEmail() method, which can take a recipient, subject, and body. More importantly, it accepts an advanced options object where we can specify the htmlBody and other fields like cc or bcc.

Let’s create the function that orchestrates this. It will take the meeting details, generate the HTML body using our previous function, and then dispatch the email.


/**

* Sends the meeting summary email to all attendees.

* @param {string} meetingTitle The title of the meeting.

* @param {string[]} attendees An array of attendee email addresses.

* @param {string} geminiSummary The AI-generated summary.

*/

function sendSummaryEmail(meetingTitle, attendees, geminiSummary) {

const recipientList = attendees.join(',');

const subject = `Meeting Minutes: ${meetingTitle}`;

// Generate the rich HTML content

const htmlContent = createEmailBody(meetingTitle, attendees, geminiSummary);

try {

GmailApp.sendEmail(recipientList, subject, '', { // Plain text body is empty

htmlBody: htmlContent,

// You could also CC a manager or a project archive address here

// cc: '[email protected]'

});

Logger.log(`Summary email sent successfully to: ${recipientList}`);

} catch (e) {

Logger.log(`Failed to send email. Error: ${e.toString()}`);

}

}

A Note on Permissions: The first time you run a function that uses GmailApp, Google will prompt you with an authorization dialog. You must grant the script permission to “Send email as you”. This is a one-time setup step required for the automation to work.

Finalizing the End-to-End Automation Script

We’ve built the individual components: fetching the transcript, summarizing with Gemini, and now, delivering the summary via Gmail. The final step is to create a main function that connects them all in the correct sequence.

This function will serve as the entry point for our entire workflow. It defines the logic flow from start to finish. For this example, we’ll use some placeholder data, but in a real-world scenario, this data would come from the Google Meet API, a Google Calendar event, or another trigger source.

Here is the complete, end-to-end script that ties everything together:


// Assume getTranscriptForLastMeeting() and summarizeWithGemini(transcript)

// functions exist from the previous steps of this tutorial.

/**

* Main function to execute the entire meeting summarization and delivery process.

*/

function processAndDeliverMeetingSummary() {

// --- STEP 1: Fetch Meeting Data (from previous steps) ---

// In a real application, you'd get this data dynamically.

const meetingData = {

title: "Q3 Project Kickoff",

attendees: ["[email protected]", "[email protected]", "[email protected]"],

transcript: "Alice: Okay, let's start the Q3 kickoff. Bob, can you give us an update on the design phase? Bob: Sure. The wireframes are complete and we are moving to high-fidelity mockups. Charlie: I've reviewed the wireframes, and I have a few concerns about the user flow for mobile."

};

if (!meetingData.transcript) {

Logger.log("No transcript found. Exiting process.");

return;

}

// --- STEP 2: Summarize with Gemini (from previous steps) ---

const geminiSummary = summarizeWithGemini(meetingData.transcript);

if (!geminiSummary) {

Logger.log("Failed to generate summary from Gemini. Exiting process.");

return;

}

Logger.log("Successfully generated summary from Gemini.");

// --- STEP 3: Deliver the Summary via Gmail (our new functions) ---

sendSummaryEmail(

meetingData.title,

meetingData.attendees,

geminiSummary

);

Logger.log("End-to-end process complete.");

}

// --- Helper functions from this step ---

function sendSummaryEmail(meetingTitle, attendees, geminiSummary) {

const recipientList = attendees.join(',');

const subject = `Meeting Minutes: ${meetingTitle}`;

const htmlContent = createEmailBody(meetingTitle, attendees, geminiSummary);

try {

GmailApp.sendEmail(recipientList, subject, '', {

htmlBody: htmlContent,

});

Logger.log(`Summary email sent successfully to: ${recipientList}`);

} catch (e) {

Logger.log(`Failed to send email. Error: ${e.toString()}`);

}

}

function createEmailBody(meetingTitle, attendees, geminiSummary) {

const summaryHtml = markdownToHtml(geminiSummary);

const attendeeList = attendees.join(', ');

const htmlBody = `

<div style="font-family: Arial, sans-serif; font-size: 14px; color: #333;">

<h1 style="color: #202124; border-bottom: 1px solid #ddd; padding-bottom: 10px;">Meeting Summary: ${meetingTitle}</h1>

<p><strong>Attendees:</strong> ${attendeeList}</p>

<h2 style="color: #202124;">AI-Generated Minutes</h2>

<div style="background-color: #f8f9fa; border: 1px solid #ddd; border-radius: 8px; padding: 16px; line-height: 1.6;">${summaryHtml}</div>

<p style="font-size: 12px; color: #888; margin-top: 20px;">This summary was automatically generated by a Gemini-powered Google Apps Script.</p>

</div>

`;

return htmlBody;

}

function markdownToHtml(markdownText) {

let html = markdownText

.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>')

.replace(/^\* (.*$)/gm, '<ul><li>$1</li></ul>');

html = html.replace(/<\/ul>\s?<ul>/g, '');

return html.replace(/\n/g, '<br />');

}

You can now run the processAndDeliverMeetingSummary function directly from the Apps Script editor to test the full workflow. Check the inboxes of your test attendees, and you should see a beautifully formatted, AI-generated summary of your meeting.

Step 4: Automating the Process with Triggers

Running the script manually from the editor is perfect for testing, but the true power of this solution lies in its ability to run without any human intervention. This is where Google Apps Script Triggers come in. Triggers are a feature that allows you to schedule your functions to run automatically, either at a specific time or in response to a specific event (like a form submission or a calendar update).

For our use case, a time-driven trigger is a simple and effective way to get started. We can set our script to run every day after work hours, processing all meetings that occurred that day.

Setting Up a Time-Driven Trigger

You can set up a trigger directly from the Apps Script editor interface.

  1. In your Apps Script project, click on the Triggers icon in the left-hand sidebar (it looks like an alarm clock).

  2. Click the + Add Trigger button in the bottom-right corner.

  3. A configuration dialog will appear. Fill it out as follows:

  • Choose which function to run: Select processAndDeliverMeetingSummary.

  • Choose which deployment should run: Leave as Head. This means it will run the latest saved version of your code.

  • Select event source: Choose Time-driven.

  • Select type of time-based trigger: Choose Day timer.

  • Select time of day: Choose a time that makes sense for your workflow, such as 5pm - 6pm to summarize the day’s meetings, or 8am - 9am to summarize the previous day’s meetings.

  • Failure notification settings: You can leave this as the default, which will notify you daily if the trigger fails.

  1. Click Save.

That’s it! You will be asked to authorize the script permissions again, this time for it to run on your behalf even when you’re not present. Once authorized, your processAndDeliverMeetingSummary function will now execute automatically every day at the time you specified, providing a truly “set it and forget it” solution for meeting minutes.

Conclusion and Next Steps

You have successfully built a powerful, end-to-end automation that leverages the generative AI capabilities of Gemini directly within the Automated Email Journey with Google Sheets and Google Analytics ecosystem. This script can fetch meeting data, intelligently summarize it, and deliver a professionally formatted report to all attendees via Gmail, saving countless hours of manual work and ensuring important information is never lost.

This project is a fantastic foundation, and there are many ways you could extend and enhance it:

  • Dynamic Data Source: Replace the hardcoded meetingData object with a dynamic source. Use the CalendarApp service to find all meetings from the past 24 hours, get their attendee lists, and find the associated transcripts.

  • Action Item Extraction: Refine the prompt sent to Gemini to specifically ask for a list of “Action Items” and “Owners”. You could then parse this section and use the Google Tasks or Google Chat API to automatically assign tasks or send reminders.

  • Google Docs Integration: Instead of just sending an email, use the DocumentApp service to create a new Google Doc for each meeting’s minutes, save it to a shared team folder, and link to it in the summary email.

  • Advanced Error Handling: Implement more robust error handling. For instance, if the Gemini API fails, you could have the script send an alert email to an administrator instead of just logging the error.

By combining the simplicity of Google Apps Script with the power of modern AI, you can create bespoke solutions that perfectly fit your team’s workflow, transforming repetitive tasks into seamless, automated processes.

The Final Code and a Live Demonstration

We’ve laid the groundwork, connected the APIs, and designed the logic. Now it’s time to assemble the final components and witness our creation come to life. This section provides the complete, ready-to-deploy code for the Google Apps Script project and walks through what you’ll see when you run it.

Reviewing the Complete Apps Script Project

Here is the full code for both the server-side logic (Code.gs) and the client-side UI (Sidebar.html). You can copy and paste these directly into your Apps Script project, replacing any placeholder content.

Code.gs (The Backend Logic)

This script handles menu creation, sidebar display, and the core functionality of communicating with the Gemini API.


// Your Google Cloud Project ID and Location

const PROJECT_ID = 'your-gcp-project-id';

const LOCATION = 'us-central1'; // e.g., 'us-central1'

/**

* Creates a custom menu in the Google Doc UI when the document is opened.

*/

function onOpen() {

DocumentApp.getUi()

.createMenu('Meeting Tools')

.addItem('Generate Summary', 'showSidebar')

.addToUi();

}

/**

* Displays the HTML sidebar in the document.

*/

function showSidebar() {

const html = HtmlService.createHtmlOutputFromFile('Sidebar')

.setTitle('Meeting Summarizer');

DocumentApp.getUi().showSidebar(html);

}

/**

* A server-side function callable from the client-side JavaScript.

* It processes the document's transcript and inserts the summary.

* @returns {string} A success or error message.

*/

function processTranscript() {

try {

const doc = DocumentApp.getActiveDocument();

const body = doc.getBody();

const transcript = body.getText();

if (transcript.trim().length < 50) {

// Basic validation to ensure there's enough text to summarize

return "Error: The document doesn't seem to contain enough text to summarize.";

}

// Construct the prompt for the Gemini API

const prompt = `

You are an expert meeting assistant. Analyze the following meeting transcript and provide a concise summary.

Your output must be in Markdown format and strictly follow this structure:

**Summary**

- A brief, neutral summary of the key discussion points and decisions made. Use bullet points for clarity.

**Action Items**

- A list of clear, actionable tasks assigned during the meeting.

- For each action item, identify the person responsible if mentioned. (e.g., "- [Alex] Finalize the Q3 budget report.")

- If no one is explicitly assigned, mark it as "- [Unassigned]".

Here is the transcript:

${transcript}

`;

// Call the Gemini API

const summaryText = callGeminiAPI(prompt);

// Prepare the summary for insertion

const header = body.insertParagraph(0, 'Meeting Summary & Action Items');

header.setHeading(DocumentApp.ParagraphHeading.HEADING1);

const summaryParagraph = body.insertParagraph(1, summaryText);

body.insertParagraph(2, '').appendHorizontalRule(); // Add a separator

// Apply some basic styling (optional)

header.setAlignment(DocumentApp.HorizontalAlignment.CENTER);

return "Success! The summary has been added to the top of your document.";

} catch (e) {

Logger.log(e.toString());

// Return a user-friendly error message

return `An error occurred: ${e.message}`;

}

}

/**

* Calls the Vertex AI Gemini API endpoint.

* @param {string} prompt The complete prompt to send to the model.

* @returns {string} The text response from the model.

*/

function callGeminiAPI(prompt) {

const accessToken = ScriptApp.getOAuthToken();

const url = `https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/gemini-1.0-pro:generateContent`;

const requestBody = {

"contents": [

{

"parts": [

{ "text": prompt }

]

}

],

"generationConfig": {

"temperature": 0.3,

"topK": 40,

"topP": 0.95,

"maxOutputTokens": 1024,

}

};

const options = {

'method': 'post',

'contentType': 'application/json',

'headers': {

'Authorization': 'Bearer ' + accessToken

},

'payload': JSON.stringify(requestBody),

'muteHttpExceptions': true // Important to catch API errors gracefully

};

const response = UrlFetchApp.fetch(url, options);

const responseCode = response.getResponseCode();

const responseBody = response.getContentText();

if (responseCode === 200) {

const jsonResponse = JSON.parse(responseBody);

// Navigate through the JSON structure to get the model's text output

return jsonResponse.candidates[0].content.parts[0].text;

} else {

Logger.log(`API Error Response: ${responseBody}`);

throw new Error(`API call failed with response code ${responseCode}. Check the logs for details.`);

}

}

Sidebar.html (The Frontend UI)

This file contains the HTML, CSS, and client-side JavaScript for the sidebar interface.


<!DOCTYPE html>

<html>

<head>

<base target="_top">

<style>

body {

font-family: 'Roboto', sans-serif;

padding: 12px;

color: #444;

}

h3 {

font-size: 16px;

margin-top: 0;

font-weight: 500;

}

p {

font-size: 13px;

line-height: 1.5;

}

button {

background-color: #4285F4;

color: white;

border: none;

padding: 10px 24px;

text-align: center;

text-decoration: none;

display: inline-block;

font-size: 14px;

margin: 4px 2px;

cursor: pointer;

border-radius: 4px;

width: 100%;

box-sizing: border-box;

}

button:disabled {

background-color: #a0a0a0;

cursor: not-allowed;

}

#status {

margin-top: 15px;

font-size: 12px;

color: #666;

min-height: 20px;

}

</style>

</head>

<body>

<h3>Generate Meeting Summary</h3>

<p>

Click the button below to analyze the entire document's text and generate a summary with action items at the top.

</p>

<button id="summarize-btn" onclick="generateSummary()">Summarize Meeting</button>

<div id="status"></div>

<script>

function generateSummary() {

const btn = document.getElementById('summarize-btn');

const statusDiv = document.getElementById('status');

// Disable button and show processing message

btn.disabled = true;

btn.textContent = 'Processing...';

statusDiv.textContent = 'Analyzing transcript. This may take a moment...';

// Call the server-side Apps Script function

google.script.run

.withSuccessHandler(onSuccess)

.withFailureHandler(onFailure)

.processTranscript();

}

function onSuccess(message) {

const btn = document.getElementById('summarize-btn');

const statusDiv = document.getElementById('status');

statusDiv.textContent = message;

// Re-enable the button

btn.disabled = false;

btn.textContent = 'Summarize Meeting';

// Optional: Close the sidebar after a short delay on success

if (message.startsWith("Success")) {

setTimeout(function() {

google.script.host.close();

}, 3000);

}

}

function onFailure(error) {

const btn = document.getElementById('summarize-btn');

const statusDiv = document.getElementById('status');

statusDiv.textContent = 'Error: ' + error.message;

// Re-enable the button

btn.disabled = false;

btn.textContent = 'Summarize Meeting';

}

</script>

</body>

</html>

Watching the Automated Summarizer in Action

With the code saved and permissions granted, the magic is ready to happen. The user experience is designed to be simple and intuitive, integrating directly into the familiar Google Docs environment.

Here’s the step-by-step flow:

  1. Open Your Transcript: Navigate to a Google Doc that contains a raw meeting transcript. After a moment, a new menu item, “Meeting Tools,” will appear in the main menu bar.

  2. Launch the Tool: Click on Meeting Tools > Generate Summary.

  3. Use the Sidebar: A sidebar will slide open on the right-hand side of your document, presenting a clean, simple interface.

  4. Initiate the Summary: Click the “Summarize Meeting” button. The button will immediately disable itself and change its text to “Processing…” to provide clear visual feedback that the script is working.

  5. Behind the Scenes: At this moment, the client-side JavaScript calls our processTranscript() function in Apps Script. The script reads the entire content of your document, wraps it in our carefully crafted prompt, and sends it securely to the Gemini API.

  6. The Result: After a few seconds, the API returns a structured Markdown summary. Our script then inserts this text at the very top of your document, complete with a main heading, bolded subheadings for “Summary” and “Action Items,” and a clean horizontal rule to separate it from the original transcript. The status message in the sidebar confirms the success, and the sidebar closes automatically.


[A GIF demonstrating the summarizer in action would be placed here, showing the menu click, sidebar interaction, and the final summary appearing in the document.]


The final output is a professional, easy-to-read summary that instantly adds value and clarity, transforming a wall of text into actionable insights.

Ideas for Customization and Future Enhancements

What we’ve built is a powerful and functional tool, but it’s also a fantastic foundation for further innovation. Here are several ideas to take this project to the next level:

  • Advanced Prompt Engineering:

  • Custom Personas: Add a dropdown in the sidebar to change the summary’s tone. Options could include “Executive Briefing” (very high-level), “Technical Deep-Dive” (focused on technical details), or “Project Manager Update” (focused on deadlines and blockers).

  • [How to build a Custom Sentiment Analysis System for Operations Feedback Using Google Forms OSD App Clinical Trial Management and Vertex AI](https://votuduc.com/How-to-build-a-Custom-Sentiment-Analysis-System-for-Operations-Feedback-Using-Google-Forms-AppSheet-and-Vertex-AI-p428528): Modify the prompt to ask Gemini to include a section on the overall sentiment of the meeting (e.g., “Positive,” “Contentious,” “Neutral”).

  • Entity Extraction: Prompt the model to identify and list all mentioned project names, deadlines, or budget figures in a separate section.

  • UI/UX Improvements:

  • Partial Selection: Update the script to check if the user has highlighted a specific portion of the text. If so, only summarize the selected text instead of the entire document.

  • Configuration in Sidebar: Add input fields to the sidebar to let the user provide more context. For example, an input for “Key Topics to Focus On” could be appended to the prompt sent to Gemini.

  • Better Status Updates: Instead of a simple text message, implement a more dynamic loading spinner for a more polished feel.

  • Deeper Workspace Integration:

  • Automated Task Creation: Parse the “Action Items” from the Gemini response and use the Google Tasks API (Tasks.Tasks.insert()) to automatically create tasks in a specific to-do list for the assigned individuals.

  • Email Distribution: Add a button to “Email Summary to Attendees.” This function could grab a list of email addresses from the document or a sidebar input, format the summary into a clean HTML email, and send it via GmailApp.

  • Centralized Reporting: Use the SpreadsheetApp service to append each meeting’s summary and action items to a central Google Sheet, creating a searchable, long-term archive of all meeting outcomes.

  • Robustness and Security:

  • Secure Credential Storage: Instead of hardcoding the PROJECT_ID, use the PropertiesService to store and retrieve such configuration values, which is a more secure and flexible practice.

  • Transcript Chunking: For extremely long meetings that might exceed Gemini’s token limit, implement logic to split the transcript into logical chunks, summarize each one, and then perform a final summary of the summaries.

Conclusion The Future of Automated Productivity

We’ve just built more than a tool; we’ve architected a new way of working. The project you’ve completed is a tangible glimpse into the future of automated productivity—a future where the drudgery of administrative tasks is delegated to intelligent agents, freeing up human capital for what it does best: strategy, creativity, and complex problem-solving. The integration of powerful models like Gemini directly into our daily digital environments isn’t just an incremental improvement; it’s a fundamental transformation of the workplace. You are now at the forefront of that change, equipped with the skills to build the next generation of intelligent applications.

Recap The Power of an Integrated Workspace Solution

Throughout this guide, we’ve witnessed the incredible synergy of the Automated Google Slides Generation with Text Replacement ecosystem. We leveraged Google Meet as our real-time data source, Google Apps Script as the nimble, serverless glue, Google Drive for persistent storage, and the Gemini API as the cognitive engine that transformed raw conversation into structured, actionable insight.

The true power lies not in any single component, but in their seamless orchestration. This isn’t just about calling an API; it’s about building a cohesive, automated workflow that lives and breathes within the environment where your work already happens. The trigger-process-output pattern we implemented—capturing an event, processing it with AI, and delivering a polished artifact—is a versatile blueprint you can now apply to countless other challenges within your organization.

Explore the ContentDrive app Ecosystem for More Tools

Building custom solutions like this meeting summarizer provides ultimate flexibility and is an invaluable skill. But what if you need to deploy powerful, pre-built automations across your team today, without writing a single line of code?

This is where the ContentDrive app ecosystem comes in. We believe in the power of integrated AI, and we’ve developed a suite of tools designed to supercharge your Automated Order Processing Wordpress to Gmail to Google Sheets to Jobber. From an AI-powered ‘Email Intent Analyzer’ that sorts your inbox for you, to a ‘Quarterly Report Synthesizer’ that pulls data from Sheets and Slides, our tools are built on the same principles you’ve learned here. They are secure, deeply integrated, and ready to deploy in minutes.

If you’re ready to take the next step, we invite you to explore the ContentDrive marketplace. Continue your journey into automated productivity, whether you choose to build the next great tool yourself or deploy a proven solution from our ecosystem. The future of work is not just coming—you’re building it.


Tags

GeminiGoogle WorkspaceAIAutomationMeeting SummarizerProductivity

Share


Previous Article
Build an Executive Decision Agent in Google Chat with Antigravity 2.0
Vo Tu Duc

Vo Tu Duc

A Google Developer Expert, Google Cloud Innovator

Stop Doing Manual Work. Scale with AI.

Hi, I'm Vo Tu Duc (Danny), a recognised Google Developer Expert (GDE). I architect custom AI agents and Google Workspace solutions that help businesses eliminate chaos and save thousands of hours.

Want to turn these blog concepts into production-ready reality for your team?
Book a Discovery Call

Table Of Contents

1
The Post-Meeting Productivity Bottleneck
2
Solution Architecture: How It All Connects
3
Prerequisites and Initial Setup
4
Step 1 Capturing the Live Transcription Stream
5
Step 2: Generating Summaries with Gemini 3.5 Pro
6
Step 3 Delivering the Minutes via Gmail
7
Step 4: Automating the Process with Triggers
8
Conclusion and Next Steps
9
The Final Code and a Live Demonstration
10
Conclusion The Future of Automated Productivity

Portfolios

AI Agentic Workflows
Cloud Engineering
AppSheet Solutions
Change Management
Strategy Playbooks
Product Showcase
Uncategorized
Workspace Automation

Related Posts

Automate Site Defect Punch Lists with Gemini and Google Chat
May 22, 2026
© 2026, All Rights Reserved.
Powered By

Quick Links

Book a CallAbout MeVolunteer Legacy

Social Media