在Apps Script的code.gs中获取邮件内点击按钮的值问题
问题描述
我正尝试实现一个简单的审批工作流:用户提交表单后,系统发送包含审批(Approved)和拒绝(Declined)按钮的邮件,我需要在code.gs中获取点击的按钮值,且点击后显示操作已记录的确认消息。但按照现有方案无法实现,请问我哪里出错了?应该如何获取按钮值?
原代码
mail.html
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <p> </p> <p> </p> <h1 style="text-align: center;">New Request - URL Addition Allow list Fortinet</h1> <p style="text-align: center;">A new request for allowing a new URL has been submitted: </p> <p style="text-align: center;">The user {{mail}} has requested the addition of the following URL: <strong>{{url}}</strong></p> <p style="text-align: center;"> <button id="Approved" onclick="buttonClick(this)">Approved</button> <button id="Declined" onclick="buttonClick(this)">Declinedtest</button> </p> <script> function buttonClick(button) { alert("You clicked "+button.id); google.script.run.getButton(button.id); } </script> </body> </html>
Code.gs
function SendMail(e) { const res=e.response; const respuestas=res.getItemResponses(); const email=res.getRespondentEmail(); const mail=respuestas[0].getResponse(); const url=respuestas[1].getResponse(); /*Logger.log(mail+url)*/ const mensaje="The user "+mail+" has requested the addition of the following URL: "+url+"." var textoHTML= HtmlService.createHtmlOutputFromFile("mail2").getContent(); textoHTML = textoHTML.replace("{{mail}}",mail) textoHTML = textoHTML.replace("{{url}}",url) GmailApp.sendEmail(mail,"URL Add request",mensaje,{htmlBody:textoHTML}) function doGet(e) { return HtmlService.createHtmlOutputFromFile('mail2') } function getButton(id) { Logger.log("You pressed "+id); } }
错误分析
- 函数嵌套问题:
doGet和getButton被定义在SendMail函数内部,导致这两个函数无法被外部调用(邮件中的前端脚本尝试调用google.script.run.getButton时会找不到该函数)。 - 邮件环境限制:邮件客户端的安全策略会阻止
google.script.run这类跨域脚本执行,Google Apps Script的客户端API仅能在其托管的网页环境中运行,无法在邮件里生效。 - 缺少请求关联标识:没有为每个审批请求生成唯一ID,无法将点击操作与具体的审批请求绑定,后续无法更新对应请求的状态。
解决方案
通过Web App作为中转处理审批请求,具体实现如下:
修正后的代码
mail.html(替换为带Web App链接的按钮)
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <p> </p> <p> </p> <h1 style="text-align: center;">New Request - URL Addition Allow list Fortinet</h1> <p style="text-align: center;">A new request for allowing a new URL has been submitted: </p> <p style="text-align: center;">The user {{mail}} has requested the addition of the following URL: <strong>{{url}}</strong></p> <p style="text-align: center;"> <a href="{{webAppUrl}}?action=Approved&requestId={{requestId}}" target="_blank" style="padding: 8px 16px; background: #4CAF50; color: white; text-decoration: none; border-radius: 4px;">Approved</a> <a href="{{webAppUrl}}?action=Declined&requestId={{requestId}}" target="_blank" style="padding: 8px 16px; background: #f44336; color: white; text-decoration: none; border-radius: 4px; margin-left: 10px;">Declined</a> </p> </body> </html>
Code.gs(全局函数+Web App处理逻辑)
// 处理表单提交并发送审批邮件 function SendMail(e) { const res = e.response; const respuestas = res.getItemResponses(); const mail = respuestas[0].getResponse(); const url = respuestas[1].getResponse(); // 生成唯一请求ID,用于关联审批操作 const requestId = Utilities.getUuid(); // 将请求信息存入表格(需先创建名为"Requests"的工作表,列顺序:ID、申请人邮箱、URL、提交时间、状态) const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Requests'); sheet.appendRow([requestId, mail, url, new Date(), 'Pending']); const mensaje = `The user ${mail} has requested the addition of the following URL: ${url}.`; // 获取部署后的Web App URL const webAppUrl = ScriptApp.getService().getUrl(); let textoHTML = HtmlService.createHtmlOutputFromFile("mail.html").getContent(); textoHTML = textoHTML.replace("{{mail}}", mail) .replace("{{url}}", url) .replace("{{webAppUrl}}", webAppUrl) .replace("{{requestId}}", requestId); GmailApp.sendEmail(mail, "URL Add request", mensaje, {htmlBody: textoHTML}); } // Web App入口,处理审批请求并返回确认页面 function doGet(e) { const action = e.parameter.action; const requestId = e.parameter.requestId; if (action && requestId) { // 更新对应请求的审批状态 const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Requests'); const data = sheet.getDataRange().getValues(); for (let i = 1; i < data.length; i++) { if (data[i][0] === requestId) { sheet.getRange(i+1, 5).setValue(action); break; } } // 返回操作确认页面 return HtmlService.createHtmlOutput(` <!DOCTYPE html> <html> <body style="text-align: center; margin-top: 50px;"> <h2>操作已记录</h2> <p>你的${action}操作已成功保存,页面将在3秒后关闭。</p> <script>setTimeout(() => window.close(), 3000)</script> </body> </html> `); } else { return HtmlService.createHtmlOutput("<h2>无效请求</h2>"); } }
部署说明
- 在Google Apps Script编辑器中,点击右上角「部署」→「新部署」。
- 类型选择「Web应用」,执行选择「我」,访问权限根据需求选择:
- 若允许匿名审批,选「任何人,甚至匿名」;
- 若需验证审批人身份,选「任何人」(需用户登录Google账号)。
- 点击「部署」,复制生成的Web App URL,确保
SendMail函数中ScriptApp.getService().getUrl()能正确获取该地址。
内容的提问来源于stack exchange,提问作者Sthefania Moreno Reina
相关产品推荐
相关产品推荐

