google-apps-script - 表单完成时多次发送相同的电子邮件。触发BUG?
问题描述
我们有一个谷歌表格,我们提供给客户填写。完成后,它会向他们发送一封包含一些详细信息的电子邮件。问题是当客户使用它时,它会向客户发送相同的电子邮件 1 到 5 次。(当我们尝试在办公室重新创建问题时,不会发生这种情况)。
我们已将原因缩小到与表单配对的 Google 工作表中的触发器存在问题。
对于表格的每一次完成,触发器会以 0~3 秒的间隔关闭几次。(电子邮件日志的图像https://drive.google.com/file/d/1j72nmR_uEMt3WTROSN534NulhkzJuiOv/view?usp=sharing)
我们认为这是 GAS 触发器的错误。我们试图从 Gsuite 获得支持,但他们显然不处理这类事情。
有任何想法吗?
这是代码的副本
//オリジナルデータ取得
var Original_Data =
//オリジナル ソート データ取得
var Original_Data_sorted =
var TimeStamp_CellNo = 1;
var Request_CellNo = 2;
var RequestName_CellNo = 3;
var StudentID_CellNo = 4;
var ComfirmationNumber_CellNo = 5;
var CancelName_CellNo = 6;
var AddName_CellNo = 7;
var AddDate_CellNo = 8;
var AddStartTime_CellNo = 9;
var AddDuration_CellNo = 10;
var RescheComfirmationNumber_CellNo = 11;
var RescheName_CellNo = 12;
var RescheDate_CellNo = 13;
var RescheStartTime_CellNo = 14;
var RescheDuration_CellNo = 15;
var Adress_CellNo = 16;
var AddDuration_Calc_CellNo = 17;
var AddStartTime_Plantext_CellNo = 18;
var AddEndTime_CellNo = 19;
var RescheDuration_Calc_CellNo = 20;
var RescheStartTime_Plantext_CellNo = 21;
var RescheEndTime_CellNo = 22;
function Request_Reply_Operation() {
//最新情報を取得
var Request_Input_Form = SpreadsheetApp.openById("blah blah").getSheetByName("Request Input Form");
var Request_List = SpreadsheetApp.openById("blah blah").getSheetByName("Request List");
const NumOfLines = Request_Input_Form.getLastRow();
var loop_cnt = 0;
var temp_date;
var temp_start;
var temp_end;
var temp_formula;
var temp_cellNo;
var to;
var subject;
var body;
var RequestName;
var ComfirmationNumber;
var Student_ID;
//レッスン終了時間算出の式を挿入
Request_Input_Form.getRange(NumOfLines,
AddStartTime_CellNo).setNumberFormat("h:mm");
Request_Input_Form.getRange(NumOfLines,
RescheStartTime_CellNo).setNumberFormat("h:mm");
temp_formula = "=SUM(J" + NumOfLines + ")/1440";
temp_cellNo = "Q"+NumOfLines;
Request_Input_Form.getRange(temp_cellNo).setValue(temp_formula);
Request_Input_Form.getRange(temp_cellNo).setNumberFormat("h:mm");
temp_formula = "=TEXT(I" + NumOfLines + ",\"h:mm\")";
temp_cellNo = "R"+NumOfLines;
Request_Input_Form.getRange(temp_cellNo).setValue(temp_formula);
temp_formula = "=TEXT(SUM(I" + NumOfLines + ",Q" + NumOfLines + "),\"h:mm\")";
temp_cellNo = "S"+NumOfLines;
Request_Input_Form.getRange(temp_cellNo).setValue(temp_formula);
temp_formula = "=SUM(O" + NumOfLines + ")/1440";
temp_cellNo = "T"+NumOfLines;
Request_Input_Form.getRange(temp_cellNo).setValue(temp_formula);
Request_Input_Form.getRange(temp_cellNo).setNumberFormat("h:mm");
temp_formula = "=TEXT(N" + NumOfLines + ",\"h:mm\")";
temp_cellNo = "U"+NumOfLines;
Request_Input_Form.getRange(temp_cellNo).setValue(temp_formula);
temp_formula = "=TEXT(SUM(N" + NumOfLines + ",T" + NumOfLines + "),\"h:mm\")";
temp_cellNo = "V"+NumOfLines;
Request_Input_Form.getRange(temp_cellNo).setValue(temp_formula);
//タイムスタンプ
var TimeStamp = new Date(Request_Input_Form.getRange(NumOfLines, TimeStamp_CellNo).getValue());
//アドレスを取得
var Adress = Request_Input_Form.getRange(NumOfLines, Adress_CellNo).getValue();
//リクエストを見る
var Request = Request_Input_Form.getRange(NumOfLines, Request_CellNo).getValue();
////データベースから予約情報を取得
var ReservationValues = Original_Data_sorted.getRange('A1:Q').getValues();
var ReservationSize = Original_Data_sorted.getLastRow();
if(Request == "レッスンキャンセル"){
////リクエスト生成
RequestName = Request_Input_Form.getRange(NumOfLines, CancelName_CellNo).getValue();
ComfirmationNumber = Request_Input_Form.getRange(NumOfLines, ComfirmationNumber_CellNo).getValue();
for(loop_cnt = 0; loop_cnt < ReservationSize; loop_cnt++){
if(ReservationValues[loop_cnt][0] == ComfirmationNumber){
//講師の種類
Logger.log(ReservationValues[loop_cnt][9]);
//レッスンの種類
Logger.log(ReservationValues[loop_cnt][10]);
}
}
//Cancel
Request_List.appendRow([
Utilities.formatDate( TimeStamp, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm'),
"Cancel",
ComfirmationNumber,
RequestName,
"",
"",
""
]);
////メール文生成
to = Adress;
Logger.log(body);
}else if(Request == "レッスン追加"){
////リクエスト生成
temp_date = new Date(Request_Input_Form.getRange(NumOfLines,
AddDate_CellNo).getValue());
//temp_start = new Date(Request_Input_Form.getRange(NumOfLines,
AddStartTime_CellNo).getValue());
temp_start = Request_Input_Form.getRange(NumOfLines,
AddStartTime_Plantext_CellNo).getValue()
//temp_end = new Date(Request_Input_Form.getRange(NumOfLines,
AddEndTime_CellNo).getValue());
temp_end = Request_Input_Form.getRange(NumOfLines,
AddEndTime_CellNo).getValue();
RequestName = Request_Input_Form.getRange(NumOfLines,
AddName_CellNo).getValue();
Request_List.appendRow([
Utilities.formatDate( TimeStamp, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm'),
"Add",
"",
RequestName,
Utilities.formatDate( temp_date, 'Asia/Tokyo', 'yyyy/MM/dd'),
temp_start,
temp_end
]);
////メール文生成
to = Adress;
Logger.log(body);
}else if(Request == "レッスンキャンセルと追加"){
////リクエスト生成
temp_date = new Date(Request_Input_Form.getRange(NumOfLines,
RescheDate_CellNo).getValue());
//temp_start = new Date(Request_Input_Form.getRange(NumOfLines,
RescheStartTime_CellNo).getValue());
temp_start = Request_Input_Form.getRange(NumOfLines,
RescheStartTime_Plantext_CellNo).getValue()
//temp_end = new Date(Request_Input_Form.getRange(NumOfLines,
RescheEndTime_CellNo).getValue());
temp_end = Request_Input_Form.getRange(NumOfLines,
RescheEndTime_CellNo).getValue();
RequestName = Request_Input_Form.getRange(NumOfLines,
RescheName_CellNo).getValue();
ComfirmationNumber = Request_Input_Form.getRange(NumOfLines,
RescheComfirmationNumber_CellNo).getValue();
for(loop_cnt = 0; loop_cnt < ReservationSize; loop_cnt++){
if(ReservationValues[loop_cnt][0] == ComfirmationNumber){
//講師の種類
Logger.log(ReservationValues[loop_cnt][9]);
//レッスンの種類
Logger.log(ReservationValues[loop_cnt][10]);
}
}
//Cancel
Request_List.appendRow([
Utilities.formatDate( TimeStamp, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm'),
"Cancel",
ComfirmationNumber,
RequestName,
"",
"",
""
]);
//Add
Request_List.appendRow([
Utilities.formatDate( TimeStamp, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm'),
"Add",
"",
RequestName,
Utilities.formatDate( temp_date, 'Asia/Tokyo', 'yyyy/MM/dd'),
temp_start,
temp_end
]);
////メール文生成
to = Adress;
Logger.log(body);
}else{//予約状況確認
RequestName =Request_Input_Form.getRange(NumOfLines,
RequestName_CellNo).getValue();
var StudentID = Request_Input_Form.getRange(NumOfLines,
StudentID_CellNo).getValue();
var String = "";
for(loop_cnt = 0; loop_cnt < ReservationSize; loop_cnt++){
//Logger.log(ReservationValues[loop_cnt][16]);
//if((ReservationValues[loop_cnt][5] == RequestName)&&
(ReservationValues[loop_cnt][16] == StudentID)){
if(ReservationValues[loop_cnt][16] == StudentID){
temp_date = new Date(ReservationValues[loop_cnt][2]);
temp_start = new Date(ReservationValues[loop_cnt][3]);
temp_end = new Date(ReservationValues[loop_cnt][4]);
String = String
+ "予約番号:"
+ ReservationValues[loop_cnt][0]
+ " >> "
+ Utilities.formatDate( temp_date, 'Asia/Tokyo', 'yyyy/MM/dd')
+ " "
+ Utilities.formatDate( temp_start, 'Asia/Tokyo', 'HH:mm')
+ "~"
+ Utilities.formatDate( temp_end, 'Asia/Tokyo', 'HH:mm')
+ "\r\n";
}
}
////予約情報からメール文生成
to = Adress;
Logger.log(body);
}
var log_sheet =
SpreadsheetApp.openById("blah blah").getSheetByName("mail_log");
var emailQuotaRemaining = MailApp.getRemainingDailyQuota();
Logger.log("Remaining email quota: " + emailQuotaRemaining);
var temp_log = "Remaining email quota: " + emailQuotaRemaining;
var now = new Date();
log_sheet.appendRow([now,temp_log,to]);
GmailApp.sendEmail(to, subject, body); //メールを送信
}
解决方案
虚假的 onFormSubmit 触发器
你应该看看这个问题。我的猜测是你得到了虚假的触发器。我得到了很多,我在这里讨论了消除它们的方法。我今天刚做了一个表格,也有同样的问题。
这是我今天早上使用的脚本。
function sendMeAMessage(e) {
var quota=Number(getGlobal('msgquota'));
if(e.values && e.values[1] && e.values[2] && e.values[3] && e.values[4] && quota>0) {
var data=e.namedValues;
var html=Utilities.formatString('You have received a message from: <br />Name: <strong>%s</strong><br />Email: <strong>%s</strong><br />Subject: <strong>%s</strong><br />Message:<br /><strong>%s</strong><br />Time: <strong>%s</strong><br />Quota: <strong>%s</strong>',data.Name,data.Email,data.Subject,data.Message,data.Timestamp,quota-1);
GmailApp.sendEmail('receipient','Message from Google Form','', {htmlBody:html});
setGlobal('msgquota',quota-1);
}
}
您只需要至少有一个必需的问题,因为幸运的是虚假触发器似乎没有回答任何问题。
如果这不是问题,我很抱歉打扰您。
推荐阅读
- javascript - 从多选表单数据到 API 请求再到数据库更新的 POST 请求的最有效方法
- ssh - 用柏树发送远程命令
- syntax - Kusto Query - 使用 case() 和 range() 对结果进行分组
- javascript - 自动切换回的材质切换组件或更好的解决方案
- html - 模态中的日期时间选择器将无法正常工作
- python - 从字符串中提取一些字母并在 Python 中添加连字符
- javascript - 如何在 JavaScript 中表示浮点数?
- elasticsearch - Elasticsearch - 存储库异常
- javascript - 如何命名 JSON 对象并将其写入 .json 文件?
- javascript - 角度编程导航 - 为什么路由器不在提供者数组中