El sistema que configuré hace lo siguiente:

  • un usuario envía un formulario
  • Se envía un correo electrónico de confirmación con un enlace para editar la respuesta (hasta ahora todo bien)
  • en el formulario, hay una pregunta de 'fecha de vencimiento'
  • un script de disparo escanea estas fechas cada día
  • cuando llega la fecha de vencimiento, envía un correo electrónico recordatorio (esto también ocurre correctamente, pero)
  • en este correo electrónico recordatorio, el enlace de edición se repite, para que el usuario no tenga que buscar el correo anterior

Lamentablemente, este enlace se envió incorrectamente. En lugar de vincular a la respuesta adecuada, proporciona el vínculo a la respuesta que se editó (envió) en último lugar.

Aquí está el guión:

function sendReminderEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;  // First row of data to process
var numRows = sheet.getLastRow()-1;   // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
// Fetch values for each row in the Range.
var data = dataRange.getValues();
//Logger.log(data)

var form = FormApp.openById("IDremovedByMe");
var formResponses = form.getResponses();
var r = formResponses.length-1;
var editURL = formResponses[r].getEditResponseUrl();
//Get the Edit URL

for (i in data) {
  var row = data[i];
  var date = new Date();
  date.setHours(0);
  date.setMinutes(0);
  date.setSeconds(0);
  //Logger.log(date);
  var sheetDate = new Date(row[13]);
 //Logger.log(sheetDate);
 var Sdate = Utilities.formatDate(date,'GMT+0100','yyyy:MM:dd')
 var SsheetDate = Utilities.formatDate(sheetDate,'GMT+0100', 'yyyy:MM:dd')
     Logger.log(Sdate+' =? '+SsheetDate)
        if (Sdate == SsheetDate){
          var sendTo = row[4];  // Collect email address from the fourth column (number value is always -1).
          var sendMe = "xyzabcloremipsum@gmail.com";  // Enter the email address where you wish to receive a notification about a reminder sent.
          var sendername = "Auto Formbot"; // Name displayed as the sender.
          var myname = "Formbot"; // Name displayed as the sender to you.
          var messageTo = "Based on the data you entered, the '" +row[6] +"' project with the ID: " +row[1] +" has ended.\n\nPlease mark it as 'Completed' and update the details as soon as it's convenient for you.\n\nYou can edit your data by using the following link:\n" +  editURL + "\n\nThank you for your time.\n\n\nWith kind regards,\nFormbot";
          var messageMe = "The '" +row[6] +"' project with the ID: " +row[1] +" has finished today.\n\nA reminder email has been sent to " +row[4] +".\n\nYou can edit the data by using the following link:\n" +  editURL + "\n\n\nSincerely,\nFormbot";
          // Above is the column (number value is always -1) selected for activity name display.
          var subjectTo = "Please update the '" +row[6] +"' activity data.";
          var subjectMe = "An activity has finished today [ID: " +row[1] +"].";
          MailApp.sendEmail(sendTo, subjectTo, messageTo, {name: sendername});
          MailApp.sendEmail(sendMe, subjectMe, messageMe, {name: myname});
            }    
   }
  }

El problema es obviamente en esta parte:

var form = FormApp.openById("IDremovedByMe");
var formResponses = form.getResponses();
var r = formResponses.length-1;
var editURL = formResponses[r].getEditResponseUrl();

Simplemente no estoy seguro de cómo explicar el guión cómo obtener la respuesta adecuada.

Tal vez mi enfoque es incorrecto, ¿tal vez debería decirle al script que escanee la base de datos del formulario en lugar de la hoja de cálculo vinculada? ¿Alguna idea sobre cómo hacer eso?

0
mozzribo 6 mar. 2017 a las 14:43

2 respuestas

La mejor respuesta

Entonces, elegí insertar las URL directamente en la hoja de respuestas y hacer referencia a ellas desde allí.

Utilicé el script encontrado aquí.

function injectEditURLs() {
  // Form ID:
  var form = FormApp.openById('IDremovedByMe');

  // Name of the (main) sheet and NOT the Sheet file name where the URLs will appear:
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Responses');

  var data = sheet.getDataRange().getValues();
  var urlCol = 11; // The number of the column in which the URL will be inserted; A = 1, B = 2 etc.
  var responses = form.getResponses();
  var timestamps = [], urls = [], resultUrls = [];

  for (var i = 0; i < responses.length; i++) {
    timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
    urls.push(responses[i].getEditResponseUrl());
  }
  for (var j = 1; j < data.length; j++) {

    resultUrls.push([data[j][0]?urls[timestamps.indexOf(data[j][0].setMilliseconds(0))]:'']);
  }
  sheet.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);  
}

Luego solo lo mencioné (y eliminé los bits innecesarios) en el script de recordatorio por correo electrónico con:

" + row[n] +"

Así que ahora se ve y funciona más o menos así:

function sendReminderEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;  // First row of data to process
var numRows = sheet.getLastRow()-1;   // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
// Fetch values for each row in the Range.
var data = dataRange.getValues();
//Logger.log(data)

for (i in data) {
  var row = data[i];
  var date = new Date();
  date.setHours(0);
  date.setMinutes(0);
  date.setSeconds(0);
  //Logger.log(date);
  var sheetDate = new Date(row[13]);
 //Logger.log(sheetDate);
 var Sdate = Utilities.formatDate(date,'GMT+0100','yyyy:MM:dd')
 var SsheetDate = Utilities.formatDate(sheetDate,'GMT+0100', 'yyyy:MM:dd')
     Logger.log(Sdate+' =? '+SsheetDate)
        if (Sdate == SsheetDate){
          var sendTo = row[4];  // Collect email address from the fourth column (number value is always -1).
          var sendMe = "xyzabcloremipsum@gmail.com";  // Enter the email address where you wish to receive a notification about a reminder sent.
          var sendername = "Auto Formbot"; // Name displayed as the sender.
          var myname = "Formbot"; // Name displayed as the sender to you.
          var messageTo = "Based on the data you entered, the '" +row[6] +"' project with the ID: " +row[1] +" has ended.\n\nPlease mark it as 'Completed' and update the details as soon as it's convenient for you.\n\nYou can edit your data by using the following link:\n" + row[10] + "\n\nThank you for your time.\n\n\nWith kind regards,\nFormbot";
          var messageMe = "The '" +row[6] +"' project with the ID: " +row[1] +" has finished today.\n\nA reminder email has been sent to " +row[4] +".\n\nYou can edit the data by using the following link:\n" +  row[10] + "\n\n\nSincerely,\nFormbot";
          // Above is the column (number value is always -1 because A=0) selected for activity name display.
          var subjectTo = "Please update the '" +row[6] +"' activity data.";
          var subjectMe = "An activity has finished today [ID: " +row[1] +"].";
          MailApp.sendEmail(sendTo, subjectTo, messageTo, {name: sendername});
          MailApp.sendEmail(sendMe, subjectMe, messageMe, {name: myname});
            }    
   }
  }
1
mozzribo 26 abr. 2017 a las 12:44

Su propia idea sobre el escaneo desde la base de datos de formularios es la opción más viable. Aquí hay un fragmento de código, de la página de documentación del formulario de Google que hace exactamente eso:

// Open a form by ID and log the responses to each question.
 var form = FormApp.openById('1234567890abcdefghijklmnopqrstuvwxyz');
 var formResponses = form.getResponses();
 for (var i = 0; i < formResponses.length; i++) {
   var formResponse = formResponses[i];
   var itemResponses = formResponse.getItemResponses();
   for (var j = 0; j < itemResponses.length; j++) {
     var itemResponse = itemResponses[j];
     Logger.log('Response #%s to the question "%s" was "%s"',
         (i + 1).toString(),
         itemResponse.getItem().getTitle(),
         itemResponse.getResponse());
   }
 }

Aquí está el enlace a esa página: https://developers.google. com / apps-script / reference / forms / item-response

Básicamente, obtendrá las respuestas del formulario usando form.responses (), luego recorra cada respuesta y obtenga la fecha de vencimiento y verifique que la fecha de vencimiento sea la misma que hoy. Luego envíe la URL de edición para esa respuesta en particular.

Espero que esto ayude, todo lo mejor

0
Jack Brown 6 mar. 2017 a las 15:07