Google 表单脚本在收到表单回复时通过电子邮件发送
Google sheets script to email when form response received
我有一个 sheet https://docs.google.com/spreadsheets/d/1NcCZ5Y7YrL63e2i6osQC28MOG3_Mq4fLPUANFrxxYNE/edit#gid=725463476 有多个表单供它使用。我需要一个脚本,当收到新响应时,它会从不同的 sheet 中提取数据并通过电子邮件发送。我将需要一个脚本,我可以为每个不同的表单响应修改它。因此,如果可能的话,有一个 sheet 可以观看,并且 sheet 可以从脚本中调用的形式提取数据,这样我就可以为每个不同的脚本更改脚本中的 sheet 名称。我的真实 sheet 中大约有 7 或 8 个这样的东西。我可能还需要一些 html 吗?也许它可以从 sheet 中提取 colors/size/bold 等?如果不是,我将需要知道如何添加字体 size/color/bold,如果无法从 sheet 中提取字体,我将需要知道如何添加字体,我将需要基于通过和失败这两个词的条件颜色。绿色表示通过,红色表示失败。我会进出 sheet 随意在 sheet 等上留下笔记。这只是一个示例,所以请输入。希望在 sheet 中与可以帮助我的人聊天!
谢谢!
斯蒂芬
从 Google 表单提交发送电子邮件
这是一个可用于创建触发器的菜单,它一次只允许创建一个触发器。
function coopermenu() {
SpreadsheetApp.getUi().createMenu('Cooper Menu')
.addItem('Create Trigger', 'createFormSubmitTrigger')
.addToUi();
}
这将设置您的触发器
function createFormSubmitTrigger(funcname) {
var funcname=funcname||'form1Submit';
if(!isTrigger(funcname)) {
ScriptApp.newTrigger(funcname).forSpreadsheet(SpreadsheetApp.getActive()).onFormSubmit().create();
}
}
这是触发 运行 以及您的升级请求的函数:
function form1Submit(e) {
Logger.log(JSON.stringify(e));
Logger.log('Sheet: %s',e.range.getSheet().getName());
var sheetname=e.range.getSheet().getName();
switch(sheetname) {
case 'Form Responses 1':
if(e.values && e.values[1] && e.values[2]) {
var html='<table>';
html+=Utilities.formatString('<tr><td>%s</td><td colspan="2">%s</td></tr>','To:',getGlobal('form1Email'));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',' ',' ' );//empty line
html+=Utilities.formatString('<tr><td>%s</td><td colspan="2">%s</td></tr>','Subject:',getGlobal('form1Subject'));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',' ',' ' );//empty line
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','TimeStamp:',e.values[0]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','Location:',e.values[1]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','Name:',e.values[2]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[3]),RoG(e.values[3]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[4]),RoG(e.values[4]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[5]),RoG(e.values[5]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[6]),RoG(e.values[6]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[7]),RoG(e.values[7]));
html+='</table>';
Logger.log(html);
GmailApp.sendEmail(getGlobal('form1Email'), getGlobal('form1Subject'), '', {htmlBody:html});
}
break;
case 'Form Responses 2':
if(e.values && e.values[1] && e.values[2]) {
var html='<table>';
html+=Utilities.formatString('<tr><td>%s</td><td colspan="2">%s</td></tr>','To:',getGlobal('form2Email'));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',' ',' ' );//empty line
html+=Utilities.formatString('<tr><td>%s</td><td colspan="2">%s</td></tr>','Subject:',getGlobal('form2Subject'));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',' ',' ' );//empty line
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','TimeStamp:',e.values[1]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','Location:',e.values[0]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','Name:',e.values[2]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[3]),RoG(e.values[3]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[5]),RoG(e.values[5]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[6]),RoG(e.values[6]));
html+='</table>';
Logger.log(html);
GmailApp.sendEmail(getGlobal('form2Email'), getGlobal('form2Subject'), '', {htmlBody:html});
}
break;
}
}
function RoG(s) {
if(s) {
if(s=='Pass') {
return '<span style="color:#00ff00;font-weight:bold">Pass</span';
}else if(s=='Fail') {
return '<span style="color:#ff0000;font-weight:bold">Fail</span>';
}
}
return s;
}
function RoGpf(s) {
if(s) {
if(s=='Pass') {
return '<span style="color:#00ff00;font-weight:bold">Pass/Fail</span';
}else if(s=='Fail') {
return '<span style="color:#ff0000;font-weight:bold">Pass/Fail</span>';
}
}
return s;
}
这些是我使用的一些实用程序:
triggers.gs:
//Filename: triggers.gs
function deleteTrigger(triggerName){
var triggers=ScriptApp.getProjectTriggers();
for (var i=0;i<triggers.length;i++){
if (triggerName==triggers[i].getHandlerFunction()){
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
function isTrigger(funcName){
var r=false;
if(funcName){
var allTriggers=ScriptApp.getProjectTriggers();
for(var i=0;i<allTriggers.length;i++){
if(funcName==allTriggers[i].getHandlerFunction()){
r=true;
break;
}
}
}
return r;
}
function deleteAllTriggers(){
var triggers=ScriptApp.getProjectTriggers();
for (var i=0;i<triggers.length; i++){
ScriptApp.deleteTrigger(triggers[i]);
}
}
function showMeProjectTriggers(){
var html='';
var br='<br />';
var triggers=ScriptApp.getProjectTriggers();
for(var i=0;i<triggers.length;i++){
var name=triggers[i].getHandlerFunction();
html+=br + 'triggers[' + i + '] = ' + name;
}
html+=br + '<input type="button" value="Close" onClick="google.script.host.close();" />';
var userInterface=HtmlService.createHtmlOutput(html).setWidth(800).setHeight(450);
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Project Handler Functions');
}
globals.gs
function getGlobals(){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
var rg=sh.getRange(1,1,sh.getLastRow(),2);
var vA=rg.getValues();
var g={};
for(var i=0;i<vA.length;i++){
g[vA[i][0]]=vA[i][1];
}
return g;
}
function setGlobals(dfltObj){
var dfltH=Object.keys(dfltObj).length;
if(dfltObj){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
var rg=sh.getRange(1,1,dfltH,2);
var vA=rg.getValues();
for(var i=0;i<dfltH;i++){
vA[i][1]=dfltObj[vA[i][0]];
}
rg.setValues(vA);
}
}
function getGlobal(name){
return getGlobals()[name];
}
function setGlobal(name,value){
var curObj=getGlobals();
if(!curObj.hasOwnProperty(name)) {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
sh.appendRow([name,value])
}else{
curObj[name]=value;
setGlobals(curObj);
}
}
function cleanGlobals() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
if(sh.getLastColumn()>2) {
sh.getRange(1,3,sh.getLastRow(),sh.getLastColumn()-2).clearContent();
}
var rg=sh.getRange(1,1,sh.getLastRow(),2);
var vA=rg.getValues();
for(var i=0;i<vA.length;i++) {
if(!vA[i][0] || !vA[i][1]) {
var userInterface=HtmlService.createHtmlOutput('Globals Sheet Requires Maintenance...Do it know.' + ' Check Row ' + Number(i + 1));
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Global Maintenance Required');
break;
}
}
}
说明
- 创建 globals.gs 并粘贴全局脚本。
- 创建 triggers.gs 并粘贴触发器脚本。
- 创建 cooper.gs 并粘贴到其他脚本中。我这样做是因为其他人正在研究代码,他们只是删除了我的脚本并改写了他们的脚本。在我看来不是很友善。
- 创建全局 Sheet。 A1='form1Subject', A2='form1Email', B1='Your Subject', B2='Your email'.
- 进入脚本编辑器和 运行 coopermenu(),这将为您提供一个权限对话框。您需要授权才能 运行 脚本。它会为您计算出所有范围。
- 然后转到新菜单并按创建触发器。一次只能创建一个。
- 转到实时表格并填写一份
- 阅读您的电子邮件,它看起来类似于下图。
- 由于我们一直遇到虚假 formSubmits 的问题,我使用以下逻辑来防止它们
if(e.values && e.values[1] && e.values[2]) {
这意味着必须填写您的姓名和位置问题才能收到电子邮件。
我更改了您要求的间距,现在的电子邮件是这样的。
我有一个 sheet https://docs.google.com/spreadsheets/d/1NcCZ5Y7YrL63e2i6osQC28MOG3_Mq4fLPUANFrxxYNE/edit#gid=725463476 有多个表单供它使用。我需要一个脚本,当收到新响应时,它会从不同的 sheet 中提取数据并通过电子邮件发送。我将需要一个脚本,我可以为每个不同的表单响应修改它。因此,如果可能的话,有一个 sheet 可以观看,并且 sheet 可以从脚本中调用的形式提取数据,这样我就可以为每个不同的脚本更改脚本中的 sheet 名称。我的真实 sheet 中大约有 7 或 8 个这样的东西。我可能还需要一些 html 吗?也许它可以从 sheet 中提取 colors/size/bold 等?如果不是,我将需要知道如何添加字体 size/color/bold,如果无法从 sheet 中提取字体,我将需要知道如何添加字体,我将需要基于通过和失败这两个词的条件颜色。绿色表示通过,红色表示失败。我会进出 sheet 随意在 sheet 等上留下笔记。这只是一个示例,所以请输入。希望在 sheet 中与可以帮助我的人聊天!
谢谢! 斯蒂芬
从 Google 表单提交发送电子邮件
这是一个可用于创建触发器的菜单,它一次只允许创建一个触发器。
function coopermenu() {
SpreadsheetApp.getUi().createMenu('Cooper Menu')
.addItem('Create Trigger', 'createFormSubmitTrigger')
.addToUi();
}
这将设置您的触发器
function createFormSubmitTrigger(funcname) {
var funcname=funcname||'form1Submit';
if(!isTrigger(funcname)) {
ScriptApp.newTrigger(funcname).forSpreadsheet(SpreadsheetApp.getActive()).onFormSubmit().create();
}
}
这是触发 运行 以及您的升级请求的函数:
function form1Submit(e) {
Logger.log(JSON.stringify(e));
Logger.log('Sheet: %s',e.range.getSheet().getName());
var sheetname=e.range.getSheet().getName();
switch(sheetname) {
case 'Form Responses 1':
if(e.values && e.values[1] && e.values[2]) {
var html='<table>';
html+=Utilities.formatString('<tr><td>%s</td><td colspan="2">%s</td></tr>','To:',getGlobal('form1Email'));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',' ',' ' );//empty line
html+=Utilities.formatString('<tr><td>%s</td><td colspan="2">%s</td></tr>','Subject:',getGlobal('form1Subject'));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',' ',' ' );//empty line
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','TimeStamp:',e.values[0]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','Location:',e.values[1]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','Name:',e.values[2]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[3]),RoG(e.values[3]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[4]),RoG(e.values[4]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[5]),RoG(e.values[5]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[6]),RoG(e.values[6]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[7]),RoG(e.values[7]));
html+='</table>';
Logger.log(html);
GmailApp.sendEmail(getGlobal('form1Email'), getGlobal('form1Subject'), '', {htmlBody:html});
}
break;
case 'Form Responses 2':
if(e.values && e.values[1] && e.values[2]) {
var html='<table>';
html+=Utilities.formatString('<tr><td>%s</td><td colspan="2">%s</td></tr>','To:',getGlobal('form2Email'));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',' ',' ' );//empty line
html+=Utilities.formatString('<tr><td>%s</td><td colspan="2">%s</td></tr>','Subject:',getGlobal('form2Subject'));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',' ',' ' );//empty line
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','TimeStamp:',e.values[1]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','Location:',e.values[0]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td><strong>%s</strong></td></tr>',' ','Name:',e.values[2]);
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[3]),RoG(e.values[3]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[5]),RoG(e.values[5]));
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',' ',RoGpf(e.values[6]),RoG(e.values[6]));
html+='</table>';
Logger.log(html);
GmailApp.sendEmail(getGlobal('form2Email'), getGlobal('form2Subject'), '', {htmlBody:html});
}
break;
}
}
function RoG(s) {
if(s) {
if(s=='Pass') {
return '<span style="color:#00ff00;font-weight:bold">Pass</span';
}else if(s=='Fail') {
return '<span style="color:#ff0000;font-weight:bold">Fail</span>';
}
}
return s;
}
function RoGpf(s) {
if(s) {
if(s=='Pass') {
return '<span style="color:#00ff00;font-weight:bold">Pass/Fail</span';
}else if(s=='Fail') {
return '<span style="color:#ff0000;font-weight:bold">Pass/Fail</span>';
}
}
return s;
}
这些是我使用的一些实用程序:
triggers.gs:
//Filename: triggers.gs
function deleteTrigger(triggerName){
var triggers=ScriptApp.getProjectTriggers();
for (var i=0;i<triggers.length;i++){
if (triggerName==triggers[i].getHandlerFunction()){
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
function isTrigger(funcName){
var r=false;
if(funcName){
var allTriggers=ScriptApp.getProjectTriggers();
for(var i=0;i<allTriggers.length;i++){
if(funcName==allTriggers[i].getHandlerFunction()){
r=true;
break;
}
}
}
return r;
}
function deleteAllTriggers(){
var triggers=ScriptApp.getProjectTriggers();
for (var i=0;i<triggers.length; i++){
ScriptApp.deleteTrigger(triggers[i]);
}
}
function showMeProjectTriggers(){
var html='';
var br='<br />';
var triggers=ScriptApp.getProjectTriggers();
for(var i=0;i<triggers.length;i++){
var name=triggers[i].getHandlerFunction();
html+=br + 'triggers[' + i + '] = ' + name;
}
html+=br + '<input type="button" value="Close" onClick="google.script.host.close();" />';
var userInterface=HtmlService.createHtmlOutput(html).setWidth(800).setHeight(450);
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Project Handler Functions');
}
globals.gs
function getGlobals(){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
var rg=sh.getRange(1,1,sh.getLastRow(),2);
var vA=rg.getValues();
var g={};
for(var i=0;i<vA.length;i++){
g[vA[i][0]]=vA[i][1];
}
return g;
}
function setGlobals(dfltObj){
var dfltH=Object.keys(dfltObj).length;
if(dfltObj){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
var rg=sh.getRange(1,1,dfltH,2);
var vA=rg.getValues();
for(var i=0;i<dfltH;i++){
vA[i][1]=dfltObj[vA[i][0]];
}
rg.setValues(vA);
}
}
function getGlobal(name){
return getGlobals()[name];
}
function setGlobal(name,value){
var curObj=getGlobals();
if(!curObj.hasOwnProperty(name)) {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
sh.appendRow([name,value])
}else{
curObj[name]=value;
setGlobals(curObj);
}
}
function cleanGlobals() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
if(sh.getLastColumn()>2) {
sh.getRange(1,3,sh.getLastRow(),sh.getLastColumn()-2).clearContent();
}
var rg=sh.getRange(1,1,sh.getLastRow(),2);
var vA=rg.getValues();
for(var i=0;i<vA.length;i++) {
if(!vA[i][0] || !vA[i][1]) {
var userInterface=HtmlService.createHtmlOutput('Globals Sheet Requires Maintenance...Do it know.' + ' Check Row ' + Number(i + 1));
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Global Maintenance Required');
break;
}
}
}
说明
- 创建 globals.gs 并粘贴全局脚本。
- 创建 triggers.gs 并粘贴触发器脚本。
- 创建 cooper.gs 并粘贴到其他脚本中。我这样做是因为其他人正在研究代码,他们只是删除了我的脚本并改写了他们的脚本。在我看来不是很友善。
- 创建全局 Sheet。 A1='form1Subject', A2='form1Email', B1='Your Subject', B2='Your email'.
- 进入脚本编辑器和 运行 coopermenu(),这将为您提供一个权限对话框。您需要授权才能 运行 脚本。它会为您计算出所有范围。
- 然后转到新菜单并按创建触发器。一次只能创建一个。
- 转到实时表格并填写一份
- 阅读您的电子邮件,它看起来类似于下图。
- 由于我们一直遇到虚假 formSubmits 的问题,我使用以下逻辑来防止它们
if(e.values && e.values[1] && e.values[2]) {
这意味着必须填写您的姓名和位置问题才能收到电子邮件。
我更改了您要求的间距,现在的电子邮件是这样的。