You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Apps Script的code.gs中获取邮件内点击按钮的值问题

问题描述

我正尝试实现一个简单的审批工作流:用户提交表单后,系统发送包含审批(Approved)和拒绝(Declined)按钮的邮件,我需要在code.gs中获取点击的按钮值,且点击后显示操作已记录的确认消息。但按照现有方案无法实现,请问我哪里出错了?应该如何获取按钮值?

原代码

mail.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <p>&nbsp;</p>
    <p>&nbsp;</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:&nbsp;</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);
}
}
错误分析
  1. 函数嵌套问题:doGet和getButton被定义在SendMail函数内部,导致这两个函数无法被外部调用(邮件中的前端脚本尝试调用google.script.run.getButton时会找不到该函数)。
  2. 邮件环境限制:邮件客户端的安全策略会阻止google.script.run这类跨域脚本执行,Google Apps Script的客户端API仅能在其托管的网页环境中运行,无法在邮件里生效。
  3. 缺少请求关联标识:没有为每个审批请求生成唯一ID,无法将点击操作与具体的审批请求绑定,后续无法更新对应请求的状态。
解决方案

通过Web App作为中转处理审批请求,具体实现如下:

修正后的代码

mail.html(替换为带Web App链接的按钮)

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <p>&nbsp;</p>
    <p>&nbsp;</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:&nbsp;</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>");
  }
}

部署说明

  1. 在Google Apps Script编辑器中,点击右上角「部署」→「新部署」。
  2. 类型选择「Web应用」,执行选择「我」,访问权限根据需求选择:
    • 若允许匿名审批,选「任何人,甚至匿名」;
    • 若需验证审批人身份,选「任何人」(需用户登录Google账号)。
  3. 点击「部署」,复制生成的Web App URL,确保SendMail函数中ScriptApp.getService().getUrl()能正确获取该地址。

内容的提问来源于stack exchange,提问作者Sthefania Moreno Reina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:55:18