GEMINI LABJP
API — The deprecation of temperature, top_p, and top_k is a silent no-op rather than an error: requests still return 200 and the values are simply ignoredAUDIT — There is no runtime signal to catch it, so auditing means searching your codebase statically for the parameters, a gap developers are actively discussingCHECK — Send the same prompt several times at temperature 0 and again at 1, then compare the spread of the outputs, and you can confirm for yourself that nothing changesMODELS — Gemini 3.7 Flash scores 65.3% on DeepSWE v1.1 and 43.6% on FrontierCode 1.1 Main, with introductory pricing available through December 31, 2026SEARCH — File Search now supports multimodal search through gemini-embedding-2, so images can be embedded and searched directly without a transcription stepDEPRECATION — gemini-robotics-er-1.6-preview shuts down on August 31, four days from now, with the ER 2 line in public preview since July 30 as the migration pathAPI — The deprecation of temperature, top_p, and top_k is a silent no-op rather than an error: requests still return 200 and the values are simply ignoredAUDIT — There is no runtime signal to catch it, so auditing means searching your codebase statically for the parameters, a gap developers are actively discussingCHECK — Send the same prompt several times at temperature 0 and again at 1, then compare the spread of the outputs, and you can confirm for yourself that nothing changesMODELS — Gemini 3.7 Flash scores 65.3% on DeepSWE v1.1 and 43.6% on FrontierCode 1.1 Main, with introductory pricing available through December 31, 2026SEARCH — File Search now supports multimodal search through gemini-embedding-2, so images can be embedded and searched directly without a transcription stepDEPRECATION — gemini-robotics-er-1.6-preview shuts down on August 31, four days from now, with the ER 2 line in public preview since July 30 as the migration path
Articles/Workspace
Workspace/2026-08-27Intermediate

Meet Notes Now Covers In-Person Meetings. Decide Where They Land in Drive First

Google Meet note-taking can now start from the home screen and covers in-person meetings. Here is how to set up a single Drive intake folder before the docs scatter, and pull only the decisions into a ledger with Apps Script.

Gemini81Google MeetApps Script10Google DriveMeeting Notes

On the walk home from a meeting I would open my notes and realize I had captured maybe half of what was actually decided. After that happened enough times, I stopped taking notes in the room entirely and started reconstructing them at a coffee shop right afterward.

That reconstruction was always the task that slipped. As an indie developer there is nobody to hand note-taking to, so that particular backlog only ever grew.

An update on August 26, 2026 lets Google Meet note-taking start directly from the home screen on web and mobile. Being able to open a note-taking session without joining a call means you can also run it in a room with the other person sitting across from you.

The catch is that if you just start using it, the generated documents pile up all over Drive. You gain a record and lose the ability to find it. The thing to decide first is not how the notes get written, but where they land.

Know What Comes Out Before You Start

When a note-taking session runs, Gemini listens to the conversation and, once it ends, produces a single Google Doc saved to Drive. Three fairly different kinds of content live inside that one document.

OutputWhat it containsHow to treat it downstream
Structured summaryHeadings per topic, a few lines of context under eachRead it directly. Also the part worth feeding to a model
Action itemsBulleted who-does-whatTranscribe into whatever tracks your tasks
Full transcriptSpeech rendered verbatimInsurance for disputes. You will rarely open it

Treating all three as equally important is where this falls apart. Even a thirty-minute in-person conversation produces a substantial transcript, and handing the whole thing to the Gemini API later means paying a model to rediscover conclusions that the summary section already states plainly.

In practice you use the summary and the action items. The transcript sits there for the day someone remembers a conversation differently than you do. Drawing that line up front makes everything that follows considerably simpler.

Create One Intake Folder and Look Only at That

If you never choose a destination, the documents simply accumulate in your Drive in date order. The moment two or three projects run in parallel, filenames alone stop telling you which meeting produced which file.

What I settled on is deliberately unambitious: one intake folder, and a habit of moving the file there when the meeting ends.

Meetings/
  _inbox/          ← generated docs land here first
  2026/
    exhibition-prep/
    app-development/

The _inbox hop exists so the filing decision can be deferred. Right after a meeting there is usually somewhere else to be, and a workflow that demands a category choice in that moment does not survive contact with a busy week. A move takes seconds.

Everything automated below watches _inbox only. It picks up unfiled documents, writes decisions to a ledger, and marks them processed. Filing stays a human activity that can happen whenever, and the automation never depends on the result.

Once automation and human judgment share the same folder structure, changing one breaks the other. Keeping the entrance narrow avoids that entirely.

Pull Out the Decisions and Drop Them in a Ledger

Now for the Apps Script. It walks the documents in _inbox, sends only the summary section to the Gemini API, gets structured decisions back, and appends them to a spreadsheet.

Configuration and the entry point first.

const CONFIG = {
  // ID of the _inbox folder (the tail of its Drive URL)
  intakeFolderId: 'YOUR_FOLDER_ID',
  // ID of the ledger spreadsheet decisions accumulate in
  ledgerSheetId: 'YOUR_SHEET_ID',
  // Check the official model list for the current ID
  model: 'gemini-3.7-flash',
};
 
function collectMeetingNotes() {
  const folder = DriveApp.getFolderById(CONFIG.intakeFolderId);
  const files = folder.getFilesByType(MimeType.GOOGLE_DOCS);
  const store = PropertiesService.getScriptProperties();
 
  while (files.hasNext()) {
    const file = files.next();
    const doneKey = 'done_' + file.getId();
    if (store.getProperty(doneKey)) continue;
 
    const section = extractSummarySection(file.getId());
    if (!section) continue;
 
    const result = askGemini(section);
    appendToLedger(file, result);
    store.setProperty(doneKey, String(Date.now()));
  }
}

The processed marker lives in script properties rather than in the file because I do not want to touch the document. A meeting record should stay as it was produced, and writing a marker into the body for the convenience of a script is exactly the kind of edit that erodes that. File IDs survive folder moves, so filing later never causes a double ingest.

Next, extracting just the summary section.

function extractSummarySection(docId) {
  const body = DocumentApp.openById(docId).getBody();
  const total = body.getNumChildren();
  const HEADINGS = ['Summary', 'Overview', 'Recap'];
  const lines = [];
  let started = false;
 
  for (let i = 0; i < total; i++) {
    const el = body.getChild(i);
    const type = el.getType();
    if (type !== DocumentApp.ElementType.PARAGRAPH &&
        type !== DocumentApp.ElementType.LIST_ITEM) continue;
 
    const item = (type === DocumentApp.ElementType.PARAGRAPH)
      ? el.asParagraph()
      : el.asListItem();
    const text = item.getText().trim();
    const isHeading = item.getHeading() !== DocumentApp.ParagraphHeading.NORMAL;
 
    if (isHeading) {
      if (!started && HEADINGS.some(function (h) { return text.indexOf(h) === 0; })) {
        started = true;
        continue;
      }
      if (started) break;  // stop at the next heading
      continue;
    }
    if (started && text) lines.push(text);
  }
  return lines.length ? lines.join('\n') : null;
}

It is a plain heading-to-heading slice, nothing clever. Even so, the token volume you send drops by an order of magnitude compared with passing the whole document. Heading wording varies by locale and by how the session was run, so open one real document and check what the first heading actually says before you tune HEADINGS.

When no matching heading exists the function returns null and the caller skips the file. Forcing an unexpected document shape through the pipeline and landing half-formed rows in the ledger is worse than skipping it and noticing later.

Fix the Response Shape Before You Call the API

If decisions are going to be handled by machine afterward, there is no reason to accept free-form prose. Pin the shape with responseSchema.

function askGemini(sectionText) {
  const apiKey = PropertiesService.getScriptProperties().getProperty('GEMINI_API_KEY');
  const endpoint = 'https://generativelanguage.googleapis.com/v1beta/models/' +
    CONFIG.model + ':generateContent';
 
  const payload = {
    contents: [{
      role: 'user',
      parts: [{ text: buildPrompt(sectionText) }]
    }],
    generationConfig: {
      responseMimeType: 'application/json',
      responseSchema: {
        type: 'object',
        properties: {
          decisions: { type: 'array', items: { type: 'string' } },
          owners: { type: 'array', items: { type: 'string' } },
          due: { type: 'string' }
        },
        required: ['decisions']
      }
    }
  };
 
  const res = UrlFetchApp.fetch(endpoint, {
    method: 'post',
    contentType: 'application/json',
    headers: { 'x-goog-api-key': apiKey },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  });
 
  const code = res.getResponseCode();
  if (code !== 200) {
    throw new Error('Gemini API ' + code + ': ' + res.getContentText());
  }
  const body = JSON.parse(res.getContentText());
  return JSON.parse(body.candidates[0].content.parts[0].text);
}
 
function buildPrompt(sectionText) {
  return [
    'Below is a meeting summary. Extract only what was actually decided.',
    'Do not include proposals under consideration, deferred topics, or impressions.',
    'Fill owners in the same order as decisions, using an empty string when unknown.',
    '---',
    sectionText
  ].join('\n');
}

The absence of temperature in generationConfig is intentional. As of August 2026, temperature, top_p and top_k are deprecated. Implementations that relied on them to suppress output variance will need rewriting sooner or later, and there is no reason to bake them into code you are writing today.

That job moves to the schema and to the constraints in the prompt. Spelling out "do not include proposals under consideration" matters because summaries often place a conclusion and an open question side by side, and both get harvested as decisions if you say nothing.

Finally, the write to the ledger.

function appendToLedger(file, result) {
  const sheet = SpreadsheetApp.openById(CONFIG.ledgerSheetId).getSheets()[0];
  const decisions = result.decisions || [];
  const owners = result.owners || [];
  if (!decisions.length) return;
 
  const rows = decisions.map(function (text, i) {
    return [
      Utilities.formatDate(file.getDateCreated(), 'Asia/Tokyo', 'yyyy-MM-dd'),
      file.getName(),
      text,
      owners[i] || '',
      result.due || '',
      file.getUrl()
    ];
  });
 
  sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, rows[0].length)
       .setValues(rows);
}

Carrying the source document URL on every row is the unglamorous part that earns its keep. When a line in the ledger makes you pause and wonder whether that is really what was agreed, you can jump straight to the original. A summary is only ever a summary, and I wanted the data structure itself to say that the evidence lives elsewhere.

I run this on a time-driven trigger once a day. Nothing needs to reach the ledger the instant a meeting ends; by the next morning is plenty. If your trigger count starts creeping up, the consolidation approach in When Apps Script Time-Driven Triggers Quietly Run Out applies directly. For permissions, follow the scope design in Keeping Apps Script + Gemini Automations on Least Privilege and declare only what you need in appsscript.json.

Decide What You Tell People Before You Use It in a Room

This part probably matters more than any of the setup above.

In a video call, everyone can see on screen that notes are being taken. Across a table, the other person has no idea what the device sitting there is doing.

I made it a personal rule to say something before starting. "I keep falling behind on writing these up afterward, so would you mind if I use the note-taking feature?" is usually received without friction. When someone would rather I did not, I write by hand and that is the end of it.

Three decisions worth making in advance, so you are not weighing them mid-conversation:

  • Sharing: does the generated doc go to the other party, or stay as your own reference
  • Retention: how long the full transcript survives. Once decisions reach the ledger, the originals can be cleared on a schedule
  • Exclusions: meals with plenty of small talk, or conversations about things not yet public, are not candidates

Being recorded is not automatically welcome. Convenience is not a good enough reason to step over that.

Where to Start

Create the _inbox folder and run a note-taking session at your next meeting. Automation can wait. You need to read one generated document with your own eyes and see how its headings are actually phrased before extractSummarySection can be tuned to anything real.

On the broader question of how much of a new Workspace capability belongs inside your automation, Sheets canvas Takes the Entry Point, Not the Execution Boundary works through where the responsibility for execution should stay.

In-person records were the place my process never quite reached. Having something that reaches them is, quite simply, a relief.

Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Workspace2026-08-26
Sheets canvas Takes the Entry Point, Not the Execution Boundary
With Sheets canvas available, how much of your hand-built Apps Script can you actually retire? Sorting the answer by execution boundary, with the decision rules and a classifier script that does the inventory for you.
Workspace2026-07-15
The Table Was There, but the Rows and Columns Weren't — Preserving Docs Structure Before It Reaches Gemini
getBody().getText() flattens Google Docs tables into a column of loose values. Here is what that cost me on a 42-row ledger, the Apps Script extraction layer that keeps the structure, and the acceptance test that keeps it honest.
Workspace2026-07-13
Retiring the Poll That Waits on an Overnight Batch — An Apps Script doPost Sink for Gemini Signals
Polling a Gemini batch or long-running operation every five minutes from an Apps Script time trigger quietly stacks up UrlFetch calls and latency. Receive the webhook in doPost, treat it as an unverified signal, then confirm authoritatively and apply idempotently.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →