news 2026/10/2 1:41:47

Gemini API Cookbook 实战:用 Apps Script 与函数调用自动化 Google Workspace 任务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Gemini API Cookbook 实战:用 Apps Script 与函数调用自动化 Google Workspace 任务
  • 示例工程
  • 人工智能
  • 大模型

【免费下载链接】cookbook

Examples and guides for using the Gemini API

项目地址:https://gitcode.com/GitHub_Trending/coo/cookbook
点击查看免费下载

本指南围绕当前仓库中 Automate Google Workspace tasks with the Gemini API Codelab 的配套文件展开,完整讲解如何在 Apps Script 环境中直连 Gemini API,并组合函数调用(Function Calling)、**视觉(Vision)与文本(Text)**三大能力,实现“一句话指令 → 自动完成文档摘要、图表分析、邮件草稿与幻灯片生成”的 Workspace 自动化流水线。读完本文,你将掌握 Apps Script 中 Gemini API 的三种请求封装方式、工具(Tools)声明与分发机制,以及基于 Drive、Calendar、Gmail、Sheets、Slides 五大 Workspace 服务串联的完整实现细节。

一、案例概览:从一句自然语言到多个 Workspace 动作

本仓库的 Apps_script_and_Workspace_codelab 目录 是同名 Codelab「Automate Google Workspace tasks with the Gemini API」的最终配套文件(README 中明确说明这些是 "final, accompanying files",读者应跟随主 Codelab 学习,卡住时可直接加载本目录文件)。该工作坊曾在Google I/O 2024上展出。

其核心思路非常直观:用户只输入一句自由文本(free text input),例如:

  • "Set up a meeting at 5PM with Helen to discuss the news in the Gemini-1.5-blog.txt file."
  • "Draft an email for Mary with insights from the chart in the CollegeExpenses sheet."
  • "Help me put together a deck about water conservation."

Apps Script 便把这句话交给 Gemini API,由模型通过函数调用自动决定该执行哪个工具,随后由 Apps Script 调用真实的 Workspace 服务完成:

用户意图模型选中的工具实际执行动作
总结文档并安排会议setupMeeting读取 Drive 文件 → 生成标题与摘要 → 创建日历事件并附带文件
分析图表并起草邮件draftEmail读取表格图表 → 视觉理解图表 → 生成 Gmail 草稿并附上图表
生成演示文稿createDeck让模型产出幻灯片要点 → 调用 Slides 生成 3 页 deck 并返回 URL

这套设计把「意图理解」交给模型、把「动作执行」交给 Apps Script,是 Agent 类应用在办公场景中最典型的落地形态。整个示例由两个脚本文件实现:main.gs(入口与分发)和 utils.gs(API 封装、工具声明与业务实现)。

二、运行前提与配套素材

2.1 配套文件清单

目录内共 5 个文件,构成完整的可运行示例:

  • README.md:Codelab 说明,指明学习路径与能力范围;
  • main.gs:入口函数main()与工具分发逻辑;
  • utils.gs:Gemini 请求封装、工具声明与三个 Workspace 任务实现;
  • Gemini-blog.txt:示例文档(Gemini 1.5 发布博客正文),用于setupMeeting的文档摘要场景;
  • CollegeExpenses.xlsx:示例表格(大学开支数据),其中Sheet1含图表,用于draftEmail的图表分析场景。

2.2 API 密钥与模型端点配置

utils.gs 开头即完成了环境初始化:

const properties = PropertiesService.getScriptProperties().getProperties(); const geminiApiKey = properties['GOOGLE_API_KEY']; const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/gemini-3.7-flash:generateContent?key=${geminiApiKey}`;

要点:

  • API 密钥通过 Apps Script 的脚本属性(Script Properties)读取,键名为GOOGLE_API_KEY,而不是硬编码在代码里,避免泄露;
  • 所有请求统一走 REST 端点generateContent,当前仓库版本使用的模型为gemini-3.7-flash(v1betaAPI);如需换模型,只需修改geminiEndpoint中的模型名;
  • 从源码结构可以推断,attachFileToMeeting使用了Calendar 高级服务(Calendar.Events.list/Calendar.Events.patch),因此运行前需要在 Apps Script 项目设置中启用 Google Calendar API 高级服务;
  • 示例还定义了常量const NUM_SLIDES = 3;,用于控制生成幻灯片的页数,可在 utils.gs 中调整。

三、三种 Gemini 请求封装:文本、视觉、函数调用

utils.gs 提供了三个请求函数,分别对应 README 提到的 text、vision、function calling 三种能力。

3.1 文本生成:callGemini(prompt, temperature=0)

function callGemini(prompt, temperature=0) { const payload = { "contents": [ { "parts": [ { "text": prompt }, ] } ], "generationConfig": { "temperature": temperature, }, }; const options = { 'method' : 'post', 'contentType': 'application/json', 'payload': JSON.stringify(payload) }; const response = UrlFetchApp.fetch(geminiEndpoint, options); const data = JSON.parse(response); const content = data["candidates"][0]["content"]["parts"][0]["text"]; return content; }

该函数用UrlFetchApp.fetch以 POST 方式调用 Gemini REST 接口:

  • 请求体contents[0].parts[0].text携带用户提示词;
  • generationConfig.temperature默认0,用于让输出尽可能确定(后续对 JSON 结构化输出的解析依赖这一点);
  • 响应从candidates[0].content.parts[0].text中取出模型生成的文本。

3.2 多模态视觉:callGeminiProVision(prompt, image, temperature=0)

function callGeminiProVision(prompt, image, temperature=0) { const imageData = Utilities.base64Encode(image.getAs('image/png').getBytes()); const payload = { "contents": [ { "parts": [ { "text": prompt }, { "inlineData": { "mimeType": "image/png", "data": imageData } } ] } ], "generationConfig": { "temperature": temperature, }, }; // ... 同样的 fetch 与解析逻辑 }

与文本版本的区别在于:parts数组在文本之外追加了inlineData图像块,将图片转为PNG字节流并Base64 编码后内联提交,mimeType声明为image/png。这是 Apps Script 中无需 File API、直接把本地图表/图片交给 Gemini 视觉理解的标准做法。

3.3 函数调用:callGeminiWithTools(prompt, tools, temperature=0)

function callGeminiWithTools(prompt, tools, temperature=0) { const payload = { "contents": [ { "parts": [ { "text": prompt }, ] } ], "tools" : tools, "generationConfig": { "temperature": temperature, }, }; // ... fetch 后: const content = data["candidates"][0]["content"]["parts"][0]["functionCall"]; return content; }

注意关键差异:payload中新增tools字段,且响应读取的不是text而是functionCall。也就是说,当模型判断需要调用某个工具时,接口返回的不是生成文本,而是一个结构化的函数调用声明(含函数名与参数),交由调用方去执行真实业务。这是整个 Codelab「由模型决定下一步动作」的核心机制。

四、工具注册表WORKSPACE_TOOLS与参数声明

三个 Workspace 工具通过function_declarations统一注册在 utils.gs 的WORKSPACE_TOOLS常量中,每个声明包含name、description、parameters(类型、属性及必填项),模型据此理解可用工具及其参数契约。

4.1setupMeeting—— 在 Google Calendar 中安排会议

{ "name": "setupMeeting", "description": "Sets up a meeting in Google Calendar.", "parameters": { "type": "object", "properties": { "time": { "type": "string", "description": "The time of the meeting." }, "recipient": { "type": "string", "description": "The name of the recipient." }, "filename": { "type": "string", "description": "The name of the file." } }, "required": ["time", "recipient", "filename"] } }

4.2draftEmail—— 分析表格图表并撰写邮件

{ "name": "draftEmail", "description": "Write an email by analyzing data or charts in a Google Sheets file.", "parameters": { "type": "object", "properties": { "sheet_name": { "type": "string", "description": "The name of the sheet to analyze." }, "recipient": { "type": "string", "description": "The name of the recipient." } }, "required": ["sheet_name", "recipient"] } }

4.3createDeck—— 生成演示文稿并返回 URL

{ "name": "createDeck", "description": "Build a simple presentation deck with Google Slides and return the URL.", "parameters": { "type": "object", "properties": { "topic": { "type": "string", "description": "The topic that the presentation is about." } }, "required": ["topic"] } }

4.4 扩展点

WORKSPACE_TOOLS的末尾保留了注释// You add tools here.,即扩展本示例只需按同样的 JSON Schema 结构追加新的函数声明,并让模型知道新工具的存在——无需修改任何请求封装代码。

五、入口与分发逻辑:main()

main.gs 定义了运行入口main(),它把「自然语言 → 工具调用 → 执行」串成一条流水线:

function main() { // const userQuery = "Set up a meeting at 5PM with Helen to discuss the news in the Gemini-1.5-blog.txt file."; // const userQuery = "Draft an email for Mary with insights from the chart in the CollegeExpenses sheet."; const userQuery = "Help me put together a deck about water conservation."; var tool_use = callGeminiWithTools(userQuery, WORKSPACE_TOOLS); Logger.log(tool_use); if(tool_use['name'] == "setupMeeting") { setupMeeting(tool_use['args']['time'], tool_use['args']['recipient'], tool_use['args']['filename']); Logger.log("Your meeting has been set up."); } else if(tool_use['name'] == "draftEmail") { draftEmail(tool_use['args']['sheet_name'], tool_use['args']['recipient']); Logger.log("Check your Gmail to review the draft"); } else if(tool_use['name'] == 'createDeck') { deckURL = createDeck(tool_use['args']['topic']); Logger.log("Deck URL: " + deckURL); } else Logger.log("no proper tool found"); }

流程分三步:

  1. 把userQuery(注释中保留了三种示例指令)与WORKSPACE_TOOLS一起交给callGeminiWithTools;
  2. 模型返回functionCall,包含name与args;
  3. 根据tool_use['name']分发到对应函数,并把tool_use['args']中的参数解包传入。

这种「声明式工具 + 手写分发」的模式清晰展示了函数调用的最小闭环:模型只负责决策,真正的副作用(写日历、发邮件、建幻灯片)全部由确定性的 Apps Script 代码完成。

六、任务一:setupMeeting—— 摘要文档并创建带附件的会议

该函数对应「总结文档 + 安排会议」场景,完整实现位于 utils.gs:

function setupMeeting(time, recipient, filename) { const files = DriveApp.getFilesByName(filename); const file = files.next(); const blogContent = file.getAs("text/*").getDataAsString(); var geminiOutput = callGemini("Give me a really short title of this blog and a summary with less than three sentences. Please return the result as a JSON with two fields: title and summary. \n" + blogContent); // The Gemini model likes to enclose the JSON with ```json and ``` geminiOutput = JSON.parse(geminiOutput.replace(/```(?:json|)/g, "")); const title = geminiOutput['title']; const fileSummary = geminiOutput['summary']; const event = CalendarApp.getDefaultCalendar().createEventFromDescription(`meet ${recipient} at ${time} to discuss "${title}"`); event.setDescription(fileSummary); attachFileToMeeting(event, file, filename); }

实现要点:

  • 读取 Drive 文件:DriveApp.getFilesByName(filename)按文件名定位文件,getAs("text/*").getDataAsString()提取纯文本正文(示例中即 Gemini-blog.txt);
  • 文本摘要 + 结构化输出:把整篇博客作为提示词的一部分交给callGemini,要求返回title与summary两个 JSON 字段;代码特意处理了模型「喜欢用```json包裹 JSON」的行为,用正则```(?:json|)去掉围栏后再JSON.parse;
  • 自然语言建日历事件:CalendarApp.getDefaultCalendar().createEventFromDescription()直接把「meet Helen at 5PM to discuss "..."」这样的描述串解析成真实日历事件,再把摘要写入事件描述;
  • 附件关联:attachFileToMeeting借助 Calendar 高级服务,先通过Calendar.Events.list按iCalUID查到事件 ID,再用Calendar.Events.patch携带attachments: [{ fileUrl, title }]把 Drive 文件挂到事件上(见 utils.gs)。

七、任务二:draftEmail—— 分析图表并生成邮件草稿

该函数对应「分析图表 + 起草邮件」场景,完整实现位于 utils.gs:

function draftEmail(sheet_name, recipient) { const prompt = `Compose the email body for ${recipient} with your insights for this chart. Use information in this chart only and do not do historical comparisons. Be concise.`; var files = DriveApp.getFilesByName(sheet_name); var sheet = SpreadsheetApp.openById(files.next().getId()).getSheetByName("Sheet1"); var expenseChart = sheet.getCharts()[0]; var chartFile = DriveApp.createFile(expenseChart.getBlob().setName("ExpenseChart.png")); var emailBody = callGeminiProVision(prompt, expenseChart); GmailApp.createDraft(recipient+"@demo-email-provider.com", "College expenses", emailBody, { attachments: [chartFile.getAs(MimeType.PNG)], name: 'myname' }); }

实现要点:

  • 定位并抽取图表:通过文件名找到 CollegeExpenses.xlsx,getSheetByName("Sheet1")进入工作表,getCharts()[0]取出第一张图;
  • 约束性提示词:提示词明确要求「只用图表中的信息、不做历史对比、保持简洁」,避免模型在邮件中编造图表之外的数据;
  • 视觉理解:把图表 Blob 交给callGeminiProVision,由多模态模型解读图表并生成邮件正文;
  • 草稿生成:GmailApp.createDraft在 Gmail 中创建草稿(收件人占位为@demo-email-provider.com,主题为 "College expenses"),并把图表导出为 PNG 作为附件;邮件不会自动发送,由用户在 Gmail 中复核——这是「人在回路」的合理设计。

八、任务三:createDeck—— 一句话生成演示文稿

该函数对应「生成幻灯片」场景,完整实现位于 utils.gs:

function createDeck(topic) { const prompt = `I'm preparing a ${NUM_SLIDES}-slide deck to discuss ${topic}. Please help me brainstorm and generate main bullet points for each slide. Keep the title of each slide short. Please produce the result as a valid JSON so that I can pass it to other APIs.`; var geminiOutput = callGemini(prompt, 0.4); // The Gemini model likes to enclose the JSON with ```json and ``` geminiOutput = geminiOutput.replace(/```(?:json|)/g, ""); const bulletPoints = JSON.parse(geminiOutput); // Create a Google Slides presentation. const presentation = SlidesApp.create("My New Presentation"); // Set up the opening slide. var slide = presentation.getSlides()[0]; var shapes = slide.getShapes(); shapes[0].getText().setText(topic); var body; for (var i = 0; i < NUM_SLIDES; i++) { slide = presentation.appendSlide(SlidesApp.PredefinedLayout.TITLE_AND_BODY); shapes = slide.getShapes(); // Set title. shapes[0].getText().setText(bulletPoints['slides'][i]['title']); // Set body. body = ""; for (var j = 0; j < bulletPoints['slides'][i]['bullets'].length; j++) { body += '* ' + bulletPoints['slides'][i]['bullets'][j] + '\n'; } shapes[1].getText().setText(body); } return presentation.getUrl(); }

实现要点:

  • 生成结构化大纲:提示词要求模型以合法 JSON 输出每个幻灯片的标题与要点(结构形如{ "slides": [ { "title": "...", "bullets": [...] } ] }),并将温度调到0.4(比默认 0 更具发散性,适合创意性大纲,同时仍保持 JSON 可解析);
  • 开篇页:新建演示文稿后,把topic直接写入第一张幻灯片标题;
  • 批量建页:循环NUM_SLIDES(3)次,追加TITLE_AND_BODY版式幻灯片,写入标题,并用'* '前缀把要点拼接成项目符号正文;
  • 返回链接:presentation.getUrl()返回可分享的 Slides URL,供用户在浏览器中查看与进一步编辑。

九、测试函数与二次开发扩展点

utils.gs 内置了三个轻量测试函数,便于在 Apps Script 编辑器中单独验证各能力是否打通:

function testGemini() { const prompt = "The best thing since sliced bread is"; const output = callGemini(prompt); console.log(prompt, output); } function testGeminiVision() { const prompt = "Provide a fun fact about this object."; const image = UrlFetchApp.fetch('https://storage.googleapis.com/generativeai-downloads/images/instrument.jpg').getBlob(); const output = callGeminiProVision(prompt, image); console.log(prompt, output); } function testGeminiTools() { const prompt = "Tell me how many days there are left in this month."; const tools = { "function_declarations": [ { "name": "datetime", "description": "Returns the current date and time as a formatted string.", "parameters": { "type": "string" } } ] }; const output = callGeminiWithTools(prompt, tools); console.log(prompt, output); }
  • testGemini:验证文本生成链路与 API 密钥配置;
  • testGeminiVision:从公网抓取一张乐器图片(instrument.jpg)测试多模态输入;
  • testGeminiTools:注册一个极简的datetime工具,验证函数调用链路。

对二次开发而言,最自然的扩展路径是:先在WORKSPACE_TOOLS的function_declarations里追加新工具(复用// You add tools here.位置),再在 main.gs 的分发if/else链中增加对应分支,最后在 utils.gs 中实现真实业务函数——三处各司其职,改动成本极低。

十、小结

以 Apps_script_and_Workspace_codelab 的 README 与两份.gs源码为骨架,本案例完整展示了 Gemini API 与 Google Workspace 的集成范式:

  • 接入方式:Apps Script 通过UrlFetchApp直连 REST 端点(当前仓库配置为gemini-3.7-flash),无需安装额外 SDK;
  • 三大能力:callGemini(文本)、callGeminiProVision(视觉)、callGeminiWithTools(函数调用)分别支撑文档摘要、图表分析与工具决策;
  • 工具闭环:WORKSPACE_TOOLS声明 → 模型返回functionCall→main()分发 → 真实 Workspace API 执行;
  • 结构化输出实践:多处要求模型返回 JSON,并处理了常见的```json围栏包裹问题;
  • 办公自动化场景:Calendar 会议 + 附件、Gmail 草稿 + 图表附件、Slides 演示文稿生成,均以「一句话指令」驱动。

该示例还可在本仓库的 examples 目录 中与其他 Gemini API 用例(函数调用、多模态、RAG、Agent 等)互相参照,作为构建个人「办公 AI 助手」的起点。若在运行时卡住,可直接加载本目录下的main.gs与utils.gs作为可运行参考实现。

  • 示例工程
  • 人工智能
  • 大模型

【免费下载链接】cookbook

Examples and guides for using the Gemini API

项目地址:https://gitcode.com/GitHub_Trending/coo/cookbook
点击查看免费下载
上一篇:终极指南:如何使用Gulf of Mexico(原DreamBerd)快速开发区块链智能合约
下一篇:Bopscrk 项目常见问题解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 1:39:49

超材料等效参数反演:CST仿真+Python闭环实现

简介&#xff1a;本资源是一套面向电磁仿真与超材料研究初学者的CST-MATLAB协同实践方案&#xff0c;聚焦S参数提取与结构参数反演这一关键逆问题&#xff0c;适用于高校电子/微波工程专业学生及射频仿真入门者。压缩包仅含1个核心MATLAB脚本文件&#xff08;get_S_Parameter.m…

作者头像 李华