如何将Google Apps Script WebApp数据传输至插件并触发函数执行
方案1:用户侧属性存储+时间触发器轮询(无UI依赖、后台自动运行)
该方案完全消耗用户自身账号的配额,不会占用开发者的并发额度,全程在免费配额范围内运行:
- 修改用户自行部署的Project1 WebApp逻辑,新增公网数据缓存和轮询接口:
// 调整后的Code_1 function doPost(e) { const scriptProps = PropertiesService.getScriptProperties(); // 区分请求来源:插件轮询请求/公网数据上报请求 if (e.parameter.reqType === "poll") { // 返回暂存的未处理数据,返回后清空缓存 const pendingData = scriptProps.getProperty("pendingExternalData"); scriptProps.deleteProperty("pendingExternalData"); return ContentService.createTextOutput(pendingData || "null"); } // 公网上报data2,写入脚本属性存储 scriptProps.setProperty("pendingExternalData", JSON.stringify(e)); return HtmlService.createHtmlOutput(JSON.stringify({status: "success"})); }
- 调整Project2插件逻辑,新增自动创建轮询触发器的逻辑:
// 新增到Code_2的初始化逻辑,插件安装时自动执行 function onInstall(e) { // 清理历史重复触发器 const existTriggers = ScriptApp.getProjectTriggers(); existTriggers.forEach(trigger => { if(trigger.getHandlerFunction() === "pollNewData") ScriptApp.deleteTrigger(trigger); }); // 创建1分钟频次的后台轮询触发器 ScriptApp.newTrigger("pollNewData") .timeBased() .everyMinutes(1) .create(); } // 轮询执行逻辑 function pollNewData() { // 用户部署的Project1 WebApp地址可在插件初始化时由用户配置,存储到用户属性中 const userWebAppUrl = PropertiesService.getUserProperties().getProperty("userWebAppUrl"); if(!userWebAppUrl) return; const options = { method: "post", payload: {reqType: "poll"}, muteHttpExceptions: true }; const resp = UrlFetchApp.fetch(userWebAppUrl, options).getContentText(); if(resp !== "null") { // 拿到公网上报的data2,执行目标函数 func(JSON.parse(resp)); } }
方案优势:
- 所有配额消耗分散到每个用户自己的账号,开发者账号无并发压力,支持无上限的用户数量
- 不需要侧边栏、弹窗等UI常驻,后台触发器自动运行,无需用户保持电子表格前台打开
- 用ScriptProperties存储临时数据,不会频繁读写电子表格,不影响表格运行性能
- 完全使用Apps Script免费配额,无需额外接入其他云服务
方案2:前台短周期轮询(近实时同步,仅表格打开时生效)
如果需要低于1分钟的同步延迟,可新增前台轮询逻辑,仅在用户打开电子表格时运行:
// 新增到Code_2的菜单逻辑 function onOpen(e) { SpreadsheetApp.getUi().createMenu("插件功能") .addItem("开启实时同步", "startRealtimeSync") .addToUi(); } function startRealtimeSync() { const userWebAppUrl = PropertiesService.getUserProperties().getProperty("userWebAppUrl"); if(!userWebAppUrl) { SpreadsheetApp.getUi().alert("请先配置您的WebApp地址"); return; } // 10秒轮询一次,可根据需求调整间隔 while(true) { const options = { method: "post", payload: {reqType: "poll"}, muteHttpExceptions: true }; const resp = UrlFetchApp.fetch(userWebAppUrl, options).getContentText(); if(resp !== "null") { func(JSON.parse(resp)); } Utilities.sleep(10000); } }
方案优势:
- 同步延迟可低至秒级,满足实时性需求
- 仅在用户主动开启、表格打开时运行,不会消耗用户后台配额
内容的提问来源于stack exchange,提问作者Boris Baublys
相关产品推荐
相关产品推荐

