Тайм-ауты Google Script - PullRequest
       13

Тайм-ауты Google Script

1 голос
/ 13 мая 2019

Проблема:

Функция импорта importXLSXtoGsheet() истекает, прежде чем она сможет обработать все 52 файла XLSX, я получил ошибку: Exception: Time-out: https://www.googleapis.com/batch/drive/v3 at [unknown function](Code:63) at Do(Code:8) at importXLSXtoGsheet(Code:71)

Если я запускаю функцию с 1 файлом в папке importXLS, она работает правильно.

Объяснение сценария:

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

  1. В конце дня все файлы собираются в одну папку (gsheetFolder) и преобразуются в файлы XLSX, используяfunction collectAndExportXLS.

Эти файлы вечером копируются на локальный сервер (с использованием пакетного сценария и синхронизации диска), который обновляет другую информацию в файле и копируется обратно в importXLSXfolder.

Утром запускается функция importXLSXtoGsheet и преобразует все файлы XLSX в папке importXLSXfolder в файлы Gsheet в gsheetFolder. После этого sortGsheetFiles запускается, сортируя и перемещая каждый Gsheetфайл в одной из 52 папок (с использованием списка массивов из текущей электронной таблицы).

Другие действия включают очистку папок с помощью функции deleteFolder.

Script:

var gsheetFolder = '###';
var XLSXfolder = '###';
var importXLSXfolder = '###';

// Modified
function deleteFolder(folderId) {
  var url = "https://www.googleapis.com/drive/v3/files?q='" + folderId + "'+in+parents+and+trashed%3Dfalse&fields=files%2Fid&access_token=" + ScriptApp.getOAuthToken();
  var res = UrlFetchApp.fetch(url);
  var obj = JSON.parse(res.getContentText());
  var reqs = obj.files.map(function(e) {return {method: "DELETE", endpoint: "https://www.googleapis.com/drive/v3/files/" + e.id}});
  var requests = {batchPath: "batch/drive/v3", requests: reqs};
  if (requests.requests.length > 0) BatchRequest.Do(requests);
}

// Added
function deleteFiles(files) {
  var reqs = files.map(function(e) {return {method: "DELETE", endpoint: "https://www.googleapis.com/drive/v3/files/" + e.id}});
  var requests = {batchPath: "batch/drive/v3", requests: reqs};
  if (requests.requests.length > 0) BatchRequest.Do(requests);
}

// Added
function getValuesFromSpreadsheet() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];
  return sheet.getRange("A2:B53").getValues();
}

// Modified
function sortGsheetFiles() {
  var url = "https://www.googleapis.com/drive/v3/files?q='" + gsheetFolder + "'+in+parents+and+mimeType%3D'" + MimeType.GOOGLE_SHEETS + "'+and+trashed%3Dfalse&fields=files(id%2Cname)&access_token=" + ScriptApp.getOAuthToken();
  var res = UrlFetchApp.fetch(url);
  var obj = JSON.parse(res.getContentText());
  var values = getValuesFromSpreadsheet();
  var reqs = values.reduce(function(ar, e) {
    for (var i = 0; i < obj.files.length; i++) {
      if (obj.files[i].name == e[0]) {
        ar.push({
          method: "PATCH",
          endpoint: "https://www.googleapis.com/drive/v3/files/" + obj.files[i].id + "?addParents=" + e[1] + "&removeParents=" + gsheetFolder,
        });
        break;
      }
    }
    return ar;
  }, []);
  var requests = {batchPath: "batch/drive/v3", requests: reqs};
  if (requests.requests.length > 0) BatchRequest.Do(requests);
  deleteFolder(importXLSXfolder);
}

// Modified
function importXLSXtoGsheet(){
  deleteFolder(XLSXfolder);
  var url = "https://www.googleapis.com/drive/v3/files?q='" + importXLSXfolder + "'+in+parents+and+mimeType%3D'" + MimeType.MICROSOFT_EXCEL + "'+and+trashed%3Dfalse&fields=files(id%2Cname)&access_token=" + ScriptApp.getOAuthToken();
  var res = UrlFetchApp.fetch(url);
  var obj = JSON.parse(res.getContentText());
  var reqs = obj.files.map(function(e) {return {
      method: "POST",
      endpoint: "https://www.googleapis.com/drive/v3/files/" + e.id + "/copy",
      requestBody: {mimeType: MimeType.GOOGLE_SHEETS, name: e.name + ".xlsx", parents: [gsheetFolder]},
    }
  });
  var requests = {batchPath: "batch/drive/v3", requests: reqs};
  if (requests.requests.length > 0) BatchRequest.Do(requests);
  deleteFolder(importXLSXfolder);
}

// Modified
function ConvertBackToXLS(fileList) {
  var token = ScriptApp.getOAuthToken();
  var reqs1 = fileList.map(function(e) {return {
      method: "GET",
      url: "https://docs.google.com/spreadsheets/export?id=" + e.id + "&exportFormat=xlsx&access_token=" + token,
    }
  });
  var res = UrlFetchApp.fetchAll(reqs1);
  var reqs2 = res.map(function(e, i) {
    var metadata = {name: fileList[i].name, parents: [XLSXfolder]};
    var form = FetchApp.createFormData(); // Create form data
    form.append("metadata", Utilities.newBlob(JSON.stringify(metadata), "application/json"));
    form.append("file", e.getBlob());
    var url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart";
    return {url: url, method: "POST", headers: {Authorization: "Bearer " + token}, body: form};
  });
  FetchApp.fetchAll(reqs2);
}

// Modified
function collectAndExportXLS() {
  deleteFolder(gsheetFolder);
  var values = getValuesFromSpreadsheet();
  var reqs1 = values.reduce(function(ar, e) {
    if (e[0] && e[1]) {
      ar.push({
        method: "GET",
        endpoint: "https://www.googleapis.com/drive/v3/files?q='" + e[1] + "'+in+parents+and+trashed%3Dfalse&fields=files(id%2Cname)",
      });
    }
    return ar;
  }, []);
  var resForReq1 = BatchRequest.Do({batchPath: "batch/drive/v3", requests: reqs1});
  var temp = resForReq1.getContentText().split("--batch");
  var files = temp.slice(1, temp.length - 1).map(function(e) {return JSON.parse(e.match(/{[\S\s]+}/g)[0])});
  var fileList = files.reduce(function(ar, e) {return ar.concat(e.files.map(function(f) {return f}))}, []);
  ConvertBackToXLS(fileList);
  deleteFiles(fileList);
}

1 Ответ

1 голос
/ 14 мая 2019

О вашем вопросе я могу понять, как показано ниже.

  • Когда importXLSXtoGsheet() запускается с 52 файлами, возникает ошибка.
  • Когда importXLSXtoGsheet() запускается с меньшимчем в 13 файлах, ошибки не возникает.
  • Другие функции, кроме importXLSXtoGsheet(), работают нормально.

Если мое понимание правильное, в качестве одного из обходных путей он определяет максимальное число для обработкифайлы один раз.Когда это отражается на importXLSXtoGsheet() вашего скрипта, модифицированный скрипт выглядит следующим образом.

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

function importXLSXtoGsheet(){
  deleteFolder(XLSXfolder);
  var url = "https://www.googleapis.com/drive/v3/files?q='" + importXLSXfolder + "'+in+parents+and+mimeType%3D'" + MimeType.MICROSOFT_EXCEL + "'+and+trashed%3Dfalse&fields=files(id%2Cname)&access_token=" + ScriptApp.getOAuthToken();
  var res = UrlFetchApp.fetch(url);
  var obj = JSON.parse(res.getContentText());

  // I modified below script.
  var n = 10; // Maximum number.
  var files = [];
  var len = obj.files.length;
  for (var i = 0; i < len; i++) {
    files.push(obj.files.splice(0, n));
    len -= n - 1;
  }
  files.forEach(function(f) {
    var reqs = f.map(function(e) {return {
        method: "POST",
        endpoint: "https://www.googleapis.com/drive/v3/files/" + e.id + "/copy",
        requestBody: {mimeType: MimeType.GOOGLE_SHEETS, name: e.name + ".xlsx", parents: [gsheetFolder]},
      }
    });
    var requests = {batchPath: "batch/drive/v3", requests: reqs};
    if (requests.requests.length > 0) BatchRequest.Do(requests);
  });
  deleteFolder(importXLSXfolder);
}

Примечание:

  • В этомПример сценария, 10 файлов обрабатываются каждый пакетный запрос.Если вы хотите изменить это, пожалуйста, измените var n = 10;.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...