Google Apps Script刷新Slides链接图表 万次调用后失效问题
故障背景
我们为非营利组织搭建的公共信息展示最初采用循环播放的Google Slides演示文稿,静态内容展示效果符合预期;动态内容为从Google Sheet(通过API自动填充数据)拉取的实时天气类文本图表,通过Google Apps Script设置每分钟执行一次刷新操作更新动态内容——设置每分钟刷新的核心原因是其中一个动态模块为实时时钟,这是当时我们找到的在Google Slides中实现实时时钟的唯一可行方案。
该方案上线初期运行稳定,但连续运行一整周(每分钟1次调用,累计约10000次调用)后,嵌入的链接图表会加载失败,显示三角形感叹号标识,提示「Image could not be loaded」。手动重新嵌入图表无法解决问题,此时整个Google Slides演示文稿会进入类似损坏的状态,无法继续用于公开展示。我们最初的临时修复方案是创建演示文稿副本,重新配置刷新触发器后即可恢复正常,但每周手动维护演示文稿的人力成本较高。
最初使用的图表刷新脚本
function refreshCharts(){ var gotSlides = SlidesApp.getActivePresentation().getSlides(); for (var i = 0; i < gotSlides.length; i++) { var slide = gotSlides[i]; var sheetsCharts = slide.getSheetsCharts(); for (var k = 0; k < sheetsCharts.length; k++) { var shChart = sheetsCharts[k]; shChart.refresh(); } } }
替换后的信息亭技术栈
考虑到Slides方案的维护成本问题,后续已完全放弃Google Slides方案,针对信息亭场景改用如下轻量技术栈实现:
- 编写HTML5脚本实现PNG/JPG格式幻灯片轮播,支持在整秒时刻强制刷新动态内容
- 采用Linux cron定时脚本,从系统获取时间、从公开免费API获取天气/天文时间数据,通过ImageMagick工具将动态文本叠加到PNG底图上
- 使用Linux轻量http-server承载HTML5幻灯片服务,投屏到Chromecast显示器,无需部署Apache等重型Web服务
- 将定时音频公告模块从HTML5脚本中拆分,转为独立MP3文件直接投屏到专用音频类Chromecast/扬声器播放
- 静态内容PNG幻灯片统一存储在Google Photos相册中,通过Chromecast的Ambient模式实现静态内容自动轮播
旧方案中曾使用的卫星云图插入代码
以下是旧Slides方案中曾正常运行的、通过Google App Script获取卫星云图网站截图并插入指定幻灯片的代码示例(需注册对应服务API密钥),近期重新测试时该代码已报错无法运行:
function insertGeoSphereScreenshot() { var siteUrl = "https://geosphere.ssec.wisc.edu/#coordinate:-1491254,4621696;zoom:5.3;idle_hide:1"; var pageSpeedApiKey = "(private)"; var url = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=" + encodeURIComponent(siteUrl) + "&key=" + pageSpeedApiKey; var res = UrlFetchApp.fetch(url).getContentText() var obj = JSON.parse(res); //var imgData = obj.lighthouseResult.audits['final-screenshot'].details.data; // 低分辨率版本 var imgData = obj.lighthouseResult.audits['full-page-screenshot'].details['screenshot'].data; var strImage = imgData.replace(/^data:image\/[a-z]+;base64,/, ""); var blob = Utilities.newBlob(Utilities.base64Decode(strImage), "image/jpeg", "sample.jpeg"); var slide = SlidesApp.getActivePresentation().getSlides()[3]; var images = slide.getImages(); var image1 = images[0]; image1.remove(); var position = {left:0, top: 0}; //var size = {width: 1350, height: 940}; //var size = {width: 675, height: 470}; //var size = {width: 570, height: 400}; // 适配效果较好 var size = {width: 700, height: 400}; slide.insertImage(blob, position.left, position.top, size.width, size.height); }
旧Slides方案故障的核心原因是Google Slides会为每次嵌入资源更新保存文件历史版本,每分钟一次的高频刷新运行一周会产生上万条冗余版本记录,触发文件内部资源索引损坏或存储阈值限制,最终出现图片加载失败的报错。手动复制文稿本质是清空了所有冗余历史版本,所以能临时恢复。如果仍需沿用Slides方案,可直接在脚本中增加每周自动生成新文稿副本、迁移内容、绑定触发器、删除旧文稿的逻辑,无需手动每周操作。
内容的提问来源于stack exchange,提问作者morden thriftstore

