я могу увеличить скорость обработки UrlFetchApp.fetch () в цикле - PullRequest
0 голосов
/ 05 марта 2019

2 У меня есть веб-форма, и я использую лист Google для массовых отправлений.

Код отлично работает для нескольких записей, но когда я добавляю 1000 - 2000 записей, я вижу, что время обработки составляеточень долго, и для запуска и завершения скрипта требуется очень много времени.Время ожидания истекло.

Можно ли как-нибудь увеличить скорость, обновив код?

В настоящее время для каждого адреса электронной почты выполняется цикл, и я думаю, что это вызывает проблему..

Вот мой текущий код:

     //sheet refers to the sheet that includes email list (email list includes "Email" as a column header
    //paramValueSheet refers to the sheet that includes parameters values

var SENT_TAG = 'SEND_CONFIRMED';
var sheet = SpreadsheetApp.getActive().getSheetByName('EmailAddressSheet');
var paramValueSheet = SpreadsheetApp.getActive().getSheetByName('ParameterValuesSheet');

    function myFunction() {

    var startRow = 2; // First row of data to process 
    var getlastrow_emailList =   sheet.getLastRow() - 1;
    var numRows = getlastrow_emailList; // Number of rows to process
    var dataRange = sheet.getRange(startRow, 1, numRows, 2);

     // Fetch values for each row in the Range.
       var data = dataRange.getValues();

        var value1 = paramValueSheet.getRange("A1").getValue();
        var value2 = paramValueSheet.getRange("A2").getValue();


    //  for (i in data) {   
         for (var i = 0; i < data.length; ++i) {
          var row = data[i];
        var emailAddress = row[0];  // First column 
        var emailSent = row[1]; // Second column


       if (emailSent != SEND_CONFIRMED) { // Prevents sending duplicates  

         var url = "https://www.SiteNameGoesHere.com/form?id=123456"; 
        UrlFetchApp.fetch(url +'&EMAIL=' + encodeURIComponent(emailAddress) + '&PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2));

           sheet.getRange(startRow + i, 2).setValue(SENT_TAG);
          // Flush to make sure the cell is updated right away in case the script is interrupted
          SpreadsheetApp.flush();
       } 

      }

    //form submission
     var response = UrlFetchApp.fetch("https://www.FORM_URL_HERE.com/form?process=submit");

    }

ОБНОВЛЕНИЕ 1:

Чтобы реализовать UrlFetchApp.fetchAll() для оптимизации процесса, нижеэто обновленный код, который я использую:

  //sheet refers to the sheet that includes email list (email list includes "Email" as a column header
    //paramValueSheet refers to the sheet that includes parameters values

var SENT_TAG = 'SEND_CONFIRMED';
var sheet = SpreadsheetApp.getActive().getSheetByName('EmailAddressSheet');
var paramValueSheet = SpreadsheetApp.getActive().getSheetByName('ParameterValuesSheet');

    function myFunction() {

    var startRow = 2; // First row of data to process 
    var getlastrow_emailList =   sheet.getLastRow() - 1;
    var numRows = getlastrow_emailList; // Number of rows to process
    var dataRange = sheet.getRange(startRow, 1, numRows, 2);

     // Fetch values for each row in the Range.
       var data = dataRange.getValues();

        var value1 = paramValueSheet.getRange("A1").getValue();
        var value2 = paramValueSheet.getRange("A2").getValue();

        var rqs = [];
        var ranges = [];
        for (var i = 0; i < data.length; ++i) {
          var row = data[i];
          var emailAddress = row[0];
          var emailSent = row[1];
          if (emailSent != SEND_CONFIRMED) {  // Should SEND_CONFIRMED be "SEND_CONFIRMED" or SENT_TAG?
            var url = "https://www.SiteNameGoesHere.com/form?id=123456"; 
            var req = UrlFetchApp.fetch(url +'&EMAIL=' + encodeURIComponent(emailAddress) + '&PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2));
            SpreadsheetApp.getUi().alert(req);
            rqs.push(req);
            ranges.push("B" + (startRow + i)); // Modified
          }
        }
        UrlFetchApp.fetchAll(rqs);
        sheet.getRangeList(ranges).setValue(SENT_TAG); // Modified
        SpreadsheetApp.flush();



    }

Этот обновленный код вызывает следующую ошибку:

"bad value" в строке UrlFetchApp.fetchAll (rqs);

Чтобы устранить проблему, вы можете видеть, что я добавил предупреждение в этот обновленный код:

SpreadsheetApp.getUi().alert(req);

В окне предупреждения отображается значение, подобное этому:

<!DOCTYPE html><html lang="en" class="no-js" data-reactroot=""><head><meta..so on..

, который сообщает мне, что код попадает на страницу формы, а страница отображается, UrlFetchApp.fetchAll(rqs); - вот что вызывает проблему.

ОБНОВЛЕНИЕ 2:

В целях тестирования я попытался обновить следующую строку в цикле кода UPDATE 1:

var req = UrlFetchApp.fetch(url +'&EMAIL=' + encodeURIComponent(emailAddress) + '&PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2));

доis:

var req = UrlFetchApp.getRequest(url +'&EMAIL=' + encodeURIComponent(emailAddress) + '&PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2));

* В основном с использованием getRequest ()

В этом случае окно предупреждения SpreadsheetApp.getUi().alert(req); показывает мне это значение [object Object]

Ив этот раз появляется новая ошибка:

var req = UrlFetchApp.getRequest(url +'&EMAIL=' + encodeURIComponent(emailAddress) + '&PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2));

Ошибка говорит:

Attribute provided with invalid value: Header:X-Forwarded-For

Выполнение сценария даже не достигает UrlFetchApp.fetchAll(rqs);, как в обновлении 1.

Я действительно надеюсь, что это имеет смысл, и если я могу получить некоторую помощь?

1 Ответ

0 голосов
/ 07 марта 2019

Как насчет этой модификации?

Точки модификации:

  • В вашем скрипте URL объявлен как url +'EMAIL=' + encodeURIComponent(emailAddress) + 'PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2).В этом случае это делается следующим образом.
    • https://www.FORM_URL_HERE.com/form?&EMAIL={emailAddress}PARAM1={value1}&PARAM2={value2}
    • В этой модификации это изменяется следующим образом.
    • https://www.FORM_URL_HERE.com/form?EMAIL={emailAddress}&PARAM1={value1}&PARAM2={value2}
  • setValue() isиспользуется снаружи цикла for.Таким образом, стоимость процесса может быть уменьшена.
  • В этой модификации rqs.push(UrlFetchApp.getRequest(...)); ... } , предложенный tehhowch , использовался для создания объекта запроса для метода fetchAll.

Модифицированный скрипт:

Пожалуйста, замените цикл for for (var i = 0; i < data.length; ++i) {...} на следующий скрипт и попробуйте снова.

var rqs = [];
var ranges = [];
for (var i = 0; i < data.length; ++i) {
  var row = data[i];
  var emailAddress = row[0];
  var emailSent = row[1];
  if (emailSent != SEND_CONFIRMED) {  // Should SEND_CONFIRMED be "SEND_CONFIRMED" or SENT_TAG?
    var url = "https://www.FORM_URL_HERE.com/form?";
    var req = UrlFetchApp.getRequest(url +'EMAIL=' + encodeURIComponent(emailAddress) + '&PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2));
    rqs.push(req);
    ranges.push("B" + (startRow + i)); // Modified
  }
}
UrlFetchApp.fetchAll(rqs);
sheet.getRangeList(ranges).setValue(SENT_TAG); // Modified
SpreadsheetApp.flush();

Примечание:

  • В вашемscript, paramValueSheet, SEND_CONFIRMED из if (emailSent != SEND_CONFIRMED) { и AudienceList не объявлены.Хотя я думал, что они могут быть объявлены в другом месте, пожалуйста, подтвердите их еще раз.
  • О SEND_CONFIRMED из if (emailSent != SEND_CONFIRMED) {, SEND_CONFIRMED должно быть "SEND_CONFIRMED" или SENT_TAG?

Ссылки:

Я не уверен насчет спецификации API, которую вы используете.И в моей среде, также я не уверен, работает ли запрос к конечной точке.Об этом, пожалуйста, подтвердите в вашей среде.Я извиняюсь за эту ситуацию.

Редактировать 1:

Из вашего комментария было обнаружено, что работает следующий скрипт.

var url = "https://www.FORM_URL_HERE.com/form?";
UrlFetchApp.fetch(url +'&EMAIL=' + encodeURIComponent(emailAddress) + 'PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2));

В этом случае URL-адрес

https://www.FORM_URL_HERE.com/form?&EMAIL={emailAddress}PARAM1={value1}&PARAM2={value2}

Если это отражено в измененном сценарии, измените его следующим образом.

С:
var req = UrlFetchApp.getRequest(url +'EMAIL=' + encodeURIComponent(emailAddress) + '&PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2));
Кому:
var req = UrlFetchApp.getRequest(url +'&EMAIL=' + encodeURIComponent(emailAddress) + 'PARAM1=' + encodeURIComponent(value1) + '&PARAM2=' + encodeURIComponent(value2));

Если это изменение не сработало,пожалуйста, подтвердите все значения emailAddress, value1 и value2.А также, возможно, потребуется учесть ограничение количества одновременных обращений к веб-форме.

Редактировать 2:

Если вы хотите запросить URL-адрес, разделив запросы, пожалуйста, измените вышесценарий к следующему сценарию.

От:

UrlFetchApp.fetchAll(rqs);

Кому:

var numberInRequest = 100; // Number of URLs requested in one request.
var loop = Math.ceil(reqs.length / numberInRequest);
for (var i = 0; i < loop; i++) {
  UrlFetchApp.fetchAll(rqs.splice(0, numberInRequest)); Modified
}
  • Здесь, если вы хотите запрашивать каждые 100 запросов, пожалуйста, установитеnumberInRequest до 100.
...