- 示例工程
- 人工智能
- 大模型
【免费下载链接】cookbook
Examples and guides for using the Gemini API
本指南围绕当前仓库中 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"); }流程分三步:
- 把
userQuery(注释中保留了三种示例指令)与WORKSPACE_TOOLS一起交给callGeminiWithTools; - 模型返回
functionCall,包含name与args; - 根据
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
相关推荐
如何用Gemini API实现Google Workspace自动化:终极指南
如何用Gemini API实现Google Workspace自动化:终极指南 想要彻底告别重复的办公任务吗?Gemini API与Google Workspa
示例工程人工智能大模型如何用Google Apps Script Samples快速实现Google Workspace集成
想要快速掌握Google Workspace集成开发?Google Apps Script Samples项目为你提供了完美的入门指南!这个JavaScript
示例工程Microsoft 激活脚本(MAS)实战指南:四条激活路线怎么选,10 分钟搞定
Microsoft 激活脚本(MAS)实战指南:四条激活路线怎么选,10 分钟搞定 系统右下角挂着"未激活"水印、Word 一打开就只读——这类事多数能用几分钟
操作系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考