Google表单提交后生成唯一ID并发送邮件的脚本问题
解决Google表单提交后邮件无法获取最新生成唯一ID的问题
问题背景
已实现两个Google Apps Script:
- 表单提交后生成唯一ID(EMP前缀),存入Google Sheets并更新表单确认消息
- 表单提交后发送包含受访者姓名和唯一ID的欢迎邮件
但邮件中的唯一ID始终为空,原因是ID生成并写入表格的操作晚于邮件触发时机,导致读取表格时ID还未被写入。
解决思路
将两个独立的触发器逻辑合并到同一个onFormSubmit函数中,确保先生成并写入唯一ID,再读取ID发送邮件,从根本上避免时序问题。
修改后的完整代码
const EMP = { HEADER: "EMP_HEADER", PREFIX: "EMP", LENGTH: 5, } class App{ constructor(){ this.ss = SpreadsheetApp.getActive() this.sheet = this.getLinkedSheet() if (!this.sheet) { throw Error(`此表格未关联任何表单。`) } this.form = FormApp.openByUrl(this.sheet.getFormUrl()) this.message = this.form.getConfirmationMessage() this.empRegex = new RegExp(`${EMP.PREFIX}[\\d]{${EMP.LENGTH}}`, 'gi') } createEmpByNumber(number){ return EMP.PREFIX + (10 ** EMP.LENGTH + number).toString().slice(-EMP.LENGTH) } getLinkedSheet(){ return this.ss.getSheets().find(sheet => sheet.getFormUrl()) } getEmpFromConfirmationMessage(){ const message = this.form.getConfirmationMessage() const results = message.match(this.empRegex) if (!results) throw Error(`当前确认消息中未找到符合格式的EMP编号,正则规则:${this.empRegex}`) return results[0] } createNextEmp(currentEmp){ const nextEmpNumber = Number(currentEmp.replace(EMP.PREFIX, "")) + 1 return this.createEmpByNumber(nextEmpNumber) } saveCurrentEmp(emp, rowStart){ const [headers] = this.sheet.getDataRange().getDisplayValues() let empHeaderIndex = headers.indexOf(EMP.HEADER) if (empHeaderIndex === -1) { empHeaderIndex = headers.length this.sheet.getRange(1, empHeaderIndex + 1).setValue(EMP.HEADER) } this.sheet.getRange(rowStart, empHeaderIndex + 1).setValue(emp) } updateConfirmationMessage(nextEmp){ const message = this.message.replace(this.empRegex, nextEmp) this.form.setConfirmationMessage(message) } sendWelcomeEmail(e, empId) { const name = e.namedValues["Name"][0]; const email = e.namedValues["Email address"][0]; const recipient = email; const subject = "欢迎加入ABC"; const alias = GmailApp.getAliases(); const template = HtmlService.createTemplateFromFile('messagebody'); template.name = name; template.code = empId; const emailToSend = template.evaluate().getContent(); const sendOptions = alias.length > 0 ? {from: alias[0], htmlBody: emailToSend} : {htmlBody: emailToSend}; GmailApp.sendEmail(recipient, subject, emailToSend, sendOptions); } run(e){ const {rowStart} = e.range // 1. 获取当前EMP编号 const currentEmp = this.getEmpFromConfirmationMessage() // 2. 保存到表格 this.saveCurrentEmp(currentEmp, rowStart) // 3. 更新确认消息的下一个编号 const nextEmp = this.createNextEmp(currentEmp) this.updateConfirmationMessage(nextEmp) // 4. 发送包含当前EMP编号的邮件 this.sendWelcomeEmail(e, currentEmp) } } function onFormSubmit(e) { new App().run(e) }
关键修改点
- 合并触发器逻辑:删除原有的两个独立
onFormSubmit函数,统一到一个入口函数,确保执行顺序可控 - 直接传递ID:生成
currentEmp后直接作为参数传入邮件发送函数,无需再从表格读取,彻底避免时序问题 - 修复数组取值:
e.namedValues返回的是数组,需取第一个元素[0],避免模板中显示数组对象 - 增加异常处理:发送邮件时判断别名是否存在,避免无别名时报错
邮件模板(保持原内容不变)
<div dir="ltr"> <p>Hola <?= name ?>, <br> </p> <p style="text-align:justify"> <br> </p> <p style="text-align:justify">Te damos la bienvenida a ABC. <br>Revisaremos tus datos y nos pondremos en contacto contigo para coordinar tu entrevista.</p> <p>Tu código para referir amigos es:</p> <p><b><font color="#0000ff"><?= code ?></font></b>.</p> <p style="text-align:justify">No olvides invitar a un amigo a registrarse. <br> </p> <p><span style="font-size:10px"><em><a href="https://example.com/pdf/terms">Aplican términos y condiciones</a></em></span></p> <p><span style="font-size:10px"><em>--</em></span></p> <p><span style="font-size:10px"><em>Equipo de ABC</em></span> <br><span style="font-size:10px"><em>"Reinventamos"</em><br><em><a href="mailto:info@example.com">info@abc.com<br></a></em></span></p> <p><span style="font-size:10px"><em><a href="https://example.com/assets/dist/images/Logo-go.png"><img alt="Logo" src="https://example.com/assets/dist/images/Logo-go.png" width="160" height="70" style="text-align: center; float: left; margin-right: 0px;"></a></em></span></p> <div><font color="#1155cc"><span style="font-size:10px"><i><br></i></span></font></div> <div><font color="#1155cc"><span style="font-size:10px"><i><br></i></span></font> <p> <br> </p> </div> <p> <br> </p> </div>
注意事项
- 确保表单的确认消息中已存在符合格式的EMP编号(如
EMP00001),否则脚本会抛出错误 - 测试时需提交表单触发
onFormSubmit触发器,手动运行函数会因缺少e参数报错 - 确保脚本拥有Gmail和Spreadsheet的授权权限
内容的提问来源于stack exchange,提问作者Darkoder
相关产品推荐
相关产品推荐

