У меня есть форма Google, которая используется для отслеживания рабочих развертываний. Форма связана с листом, а лист связан со сценарием, который запускается при отправке формы. Когда форма отправлена, мой скрипт анализирует ответы, чтобы получить «Изменить URL», чтобы пользователи могли обновить свой ответ. Все работает как положено, за исключением того, что по какой-то причине я получаю несколько копий форм и листов на диске, которые каким-то образом создаются автоматически.
Эта функция вызывается при отправке формы:
Пространство имен проекта
function sendEmail(sheet, to, subject, senderName, replyTo, template, cc, bcc, logEmails) {
if (logEmails) {
console.log({
"Requestor" : to,
"Subject" : subject,
"Sender" : senderName,
"Reply To" : replyTo,
"cc" : cc,
"bcc" : bcc,
"template" : template
});
}
else {
aneis.sendEmails(sheet, to, subject, senderName, replyTo, template, cc, bcc);
}
}
function testAssignMissingEditUrls() {
assignMissingEditUrls(SpreadsheetApp.getActive().getId(),"Changes","xxxxxxxx");
}
function onChangeFormSubmitted(responsesSheet, subsciberSheet, lastEditRow, logEmails) {
var htmlTemplate = HtmlService.createHtmlOutputFromFile('emailTemplate').getContent();
var requestor = lastEditRow[aneis.findColumnByHeader(responsesSheet, "Email Address")];
var changeTo = lastEditRow[aneis.findColumnByHeader(responsesSheet, "Change to")];
var subject = subjectPrefix + " - " + changeTo;
var tlName = lastEditRow[aneis.findColumnByHeader(responsesSheet, "Team Lead")];
var tlEmail = "";
if (tlName) {
tlEmail = TLtoEmail[tlName];
}
var tlApproved = lastEditRow[aneis.findColumnByHeader(responsesSheet, "Team Lead Approved?")];
var mgrApproved = lastEditRow[aneis.findColumnByHeader(responsesSheet, "Manager Approved?")];
var timestampColumn = aneis.findColumnByHeader(responsesSheet, "Timestamp");
var lastResponseTime = lastEditRow[timestampColumn];
var submittedOnColumn = aneis.findColumnByHeader(responsesSheet, "Submitted On");
var submittedByColumn = aneis.findColumnByHeader(responsesSheet, "Submitted By");
var submittedOn = lastEditRow[submittedOnColumn] || "";
var submittedBy = lastEditRow[submittedByColumn] || "";
var firstTime = !submittedBy || !submittedOn;
if (firstTime) {
aneis.assignLastFormEditUrl(responsesSheet.getParent().getId(), responsesSheet.getSheetName(), "xxxxxxxxxx");
// archive original submitter
submittedOn = lastResponseTime;
submittedBy = requestor;
var responsesDataRange = responsesSheet.getDataRange();
var responsesData = responsesDataRange.getValues();
var lastdt = (new Date(lastResponseTime)).getTime();
for (var i = 1; i < responsesData.length; i++) {
var thisTimestamp = (new Date(responsesData[i][timestampColumn])).getTime();
if (thisTimestamp == lastdt) {
responsesDataRange.getCell(i + 1, submittedOnColumn + 1).setValue(submittedOn); // 1 based indexing when setting
responsesDataRange.getCell(i + 1, submittedByColumn + 1).setValue(submittedBy); // 1 based indexing when setting
break;
}
}
// Send notification email (first time only)
var bccList = [];
var subscriberData = subsciberSheet.getDataRange().getValues();
subscriberData.forEach(function(subscriptionRow){
var email = subscriptionRow[aneis.findColumnByHeader(subsciberSheet, "Email Address")];
var emailPref = subscriptionRow[aneis.findColumnByHeader(subsciberSheet, "Email Preferences")];
if (emailPref == "When anyone submits" && email != requestor) {
bccList.push(email);
}
});
sendEmail(responsesSheet, submittedBy, subject, senderName, replyTo, htmlTemplate, [], bccList, logEmails);
}
if (tlEmail.length > 0) {
if (tlApproved == "No") {
var tlApproval_subject = "TL Approval Required - " + changeTo;
var tlApproval_htmlTemplate = HtmlService.createHtmlOutputFromFile('tlApprovalTemplate').getContent();
sendEmail(responsesSheet, tlEmail, tlApproval_subject, senderName, replyTo, tlApproval_htmlTemplate, [submittedBy], [], logEmails);
}
else if (tlApproved == "Yes" && mgrApproved == "No") {
var mgrApproval_subject = "APPROVAL REQUIRED - " + changeTo;
var mgrApproval_htmlTemplate = HtmlService.createHtmlOutputFromFile('mgrApprovalTemplate').getContent();
sendEmail(responsesSheet, mgrEmail, mgrApproval_subject, senderName, replyTo, mgrApproval_htmlTemplate, [submittedBy, tlEmail], [], logEmails);
}
else if (tlApproved == "Yes" && mgrApproved == "Yes") {
var approved_subject = "Approved - " + changeTo;
var approved_htmlTemplate = HtmlService.createHtmlOutputFromFile('approvedTemplate').getContent();
sendEmail(responsesSheet, submittedBy, approved_subject, senderName, replyTo, approved_htmlTemplate, [mgrEmail, tlEmail], [], logEmails);
}
}
}
function onPreferenceFormSubmitted() {
console.log("Preferences were updated... maybe notify the user that they updated their preferences");
}
function onFormSubmitted() {
var responsesSheet = SpreadsheetApp.getActive().getSheetByName("Changes");
var lastEditResponseRow = aneis.findMostRecentEdit(responsesSheet, "Timestamp");
var lastResponseTime = lastEditResponseRow[aneis.findColumnByHeader(responsesSheet, "Timestamp")];
var subsciberSheet = SpreadsheetApp.getActive().getSheetByName("Subscriptions");
var lastEditSubscriberRow = aneis.findMostRecentEdit(subsciberSheet, "Timestamp");
var lastSubscriberTime = lastEditSubscriberRow[aneis.findColumnByHeader(subsciberSheet, "Timestamp")];
if (lastResponseTime > lastSubscriberTime) {
onChangeFormSubmitted(responsesSheet, subsciberSheet, lastEditResponseRow);
}
else {
onPreferenceFormSubmitted();
}
Пространство имен aneis
function sendEmails(responsesSheet, requestor, subject, senderName, replyTo, htmlTemplate, ccList, bccList) {
var responsesData = responsesSheet.getDataRange().getValues();
var numRows = responsesData.length;
var headerRow = responsesData[0];
var lastEditResponseRow = findMostRecentEdit(responsesSheet, "Timestamp");
var htmlBody = fillTemplate(headerRow, lastEditResponseRow, htmlTemplate);
// make sure CC list does not also contain the requestor
var cc = [];
ccList.forEach(function(c) {
if (c && c != requestor) {
cc.push(c);
}
});
// make sure BCC list does not also contain the requestor or anyone also on the CC list
var bcc = [];
bccList.forEach(function(b){
if (b && b != requestor && cc.indexOf(b) < 0) {
bcc.push(b);
}
});
var message = {
to: requestor,
cc: cc.join(","),
bcc: bcc.join(","),
name: senderName,
replyTo: replyTo,
subject: subject,
htmlBody: htmlBody
};
console.info(message);
MailApp.sendEmail(message);
}
function findColumnByHeader(sheet, headerName) {
var headerRow = sheet.getRange("1:1").getValues()[0];
for (var i = 0; i < headerRow.length; i++) {
if (headerRow[i] == headerName) {
return i;
}
}
return -1;
}
function assignLastFormEditUrl(responsesSheetId, sheetName, formId) {
var responsesSheet = SpreadsheetApp.openById(responsesSheetId).getSheetByName(sheetName);
var form = FormApp.openById(formId);
var responsesDataRange = responsesSheet.getDataRange();
var editUrlColumn = findColumnByHeader(responsesSheet, 'Edit URL');
var timestampColumn = findColumnByHeader(responsesSheet, 'Timestamp');
var timestamp = new Date(responsesDataRange.getValues()[responsesDataRange.getLastRow() - 1][timestampColumn]).setMilliseconds(0);
// Get/set the Edit URL
var resp = form.getResponses();
for (var i = 0; i < resp.length; i++) {
var r = resp[i];
var rTimestamp = r.getTimestamp().setMilliseconds(0);
if (rTimestamp == timestamp) {
responsesDataRange.getCell(responsesDataRange.getLastRow(), editUrlColumn + 1).setValue(r.getEditResponseUrl());
break;
}
}
}
function findMostRecentEditRowIndex(responsesSheet, timestampColumnName) {
var responsesData = responsesSheet.getDataRange().getValues();
var tsCol = findColumnByHeader(responsesSheet, timestampColumnName);
var mostRecentRow = 0;
var mostRecentDate = new Date("01-01-1900");
responsesData.forEach(function(row, index) {
if (index === 0) {
// Skip the header!
return;
}
var date = new Date(row[tsCol]);
if (date > mostRecentDate) {
mostRecentDate = date;
mostRecentRow = index;
}
});
return mostRecentRow;
}
function fillTemplate(fieldsList, valuesList, template) {
var retVal = template;
fieldsList.forEach(function(field, index) {
var field = "[" + field + "]";
var fieldValue = "" + valuesList[index];
if (field != "[Edit URL]") {
fieldValue = updateHtmlWithWebLinks(fieldValue);
}
var fieldMacro = new RegExp(getRegExpEscaped(field), "gm");
retVal = retVal.replace(fieldMacro, fieldValue);
});
return retVal;
}
function getRegExpEscaped(inputString) {
return inputString.replace("[","\\[").replace("]","\\]").replace("(","\\(").replace(")","\\)").replace("?","\\?").replace(".","\\.").replace("*","\\*");
}
function updateHtmlWithWebLinks(inputHtml) {
var reWeb = new RegExp("(https{0,1}.*)", "gm");
return inputHtml.replace(reWeb, function(s) {
return '<a href="' + s + '">' + s + '</a>';
});
}
Что может быть причиной этого?