DocumentApp.openById() fails with “Service unavail

2019-08-29 03:29发布

I am trying to read the contents of a spreadsheet which contains some folderId, fileName and targetFile and then based on the data entered in the spreadsheet.

I am finding the latest fileId in the drive for the same fileName as multiple files with the same name are getting added into the folder daily (this is done by the function mostRecentFiIeInFolder) and then I am trying to copy the contents of the latest file with ID dociIdSource into a different file with ID docIdTarget (which is done by the function docCopy).

But when I tried Implementing this using DocumentApp, I am getting a weird error which says

Service unavailable: Docs

for the code var baseDoc = DocumentApp.openById(docID);.

May I know where I am going wrong?

// Test function to call applyDocCopytoList.
function test(){
  applyDocCopytoList();
}

// Read the values from the spreadsheet.
function applyDocCopytoList(){
  var originalSpreadsheet = SpreadsheetApp.openById('sheet Id goes here').getSheetByName("sheet name goes here");
  var getRange = originalSpreadsheet.getDataRange();
  var data = originalSpreadsheet.getDataRange().getValues();
  for (var i = 1; i < data.length; i++) {
    var folderId = data[i][1];
    var fileName = data[i][2];
    var targetFile = data[i][3];

    Logger.log('****************Record No: ' + i);
    Logger.log('folderId: ' + data[i][1]);
    Logger.log('fileName: ' + data[i][2]);
    Logger.log('targetFile: ' + data[i][3]);

    var latestFileId = mostRecentFiIeInFolder(folderId, fileName);
    if(latestFileId!= undefined){
      docCopy(latestFileId, targetFile);
    }
  }
}


// Log the id of the latest file with a particular name in the folder.
function mostRecentFiIeInFolder(folderId, fileName) {
  var folder = DriveApp.getFolderById(folderId);
  Logger.log(folder);
  var files = DriveApp.getFilesByName(fileName);
  Logger.log(fileName);
  var result = [];
  // Checks whether the given file is in the folder or not
  if(!files.hasNext()){
    Logger.log('No such file in the folder with the given name');
  }
  else{
    while (files.hasNext()) {
      var file = files.next();
      result.push([file.getDateCreated(), file.getId()]);
    }
    Logger.log('************All the file ids with the same file name and their dates created************');  
    Logger.log(result);
    result.sort(function (x, y){
      var xp = x[0];// get first element in inner array
      var yp = y[0];
      return xp == yp ? 0 : xp > yp ? -1 : 1;// choose the sort order, here its in descending order of created date
    });    
    var id = result[0][1];
    Logger.log(id);
    return id;
  }
}

// Copy the contents of the latest file in the target file.
function docCopy(dociIdSource, docIdTarget){
  Logger.log('The file with id: ' + dociIdSource + ' will be copied to the target id: ' + docIdTarget);

  var docID = docIdTarget;
  var baseDoc = DocumentApp.openById(docID); //Service unavailable: Docs error is thrown for this line of code
  var body = baseDoc.getBody();

  var otherBody = DocumentApp.openById(dociIdSource).getBody();
  var totalElements = otherBody.getNumChildren();
  for( var j = 0; j < totalElements; ++j ) {
    var element = otherBody.getChild(j).copy();
    var type = element.getType();
    if( type == DocumentApp.ElementType.PARAGRAPH )
      body.appendParagraph(element);
    else if( type == DocumentApp.ElementType.TABLE )
      body.appendTable(element);
    else if( type == DocumentApp.ElementType.LIST_ITEM )
      body.appendListItem(element);
    else if( type == DocumentApp.ElementType.INLINE_IMAGE )
      body.appendImage(element);
    else if( type == DocumentApp.ElementType.TEXT ) 
      body.setText(element); 
    else
      throw new Error("According to the doc this type couldn't appear in the body: " + type);
  }
}

1条回答
该账号已被封号
2楼-- · 2019-08-29 03:59

Note that your mostRecentFiIeInFolder function never actually uses the folder, and doesn't ever check that the files are of the correct type - i.e., are actually Google Docs files. Thus if your searched name should have found nothing (i.e. there is no recent file with that name in your target folder), but you had some alternate file elsewhere in your Drive, one that is not a Google Docs file, your script will find it and treat it as something it is not.

The solution is to restrict your search to your desired folder, and again by actual Google Docs mimetype:

function testIt() {
  var folderIds = [
    "", // Search all of Drive
    "123428349djf8234", // Search that specific folder
  ];
  // Log (in Stackdriver) the file id of the most recently created Google Docs file with the name "some name" in the various folders:
  folderIds.forEach(function (folderId) {
    console.log(getMostRecentFileIdWithName("some name", folderId, MimeType.GOOGLE_DOCS));
  });
}

function getMostRecentFileIdWithName(fileName, folderId = "", mimeType = "") {
  // If a folder was given, restrict the search to that folder. Otherwise, search with
  // DriveApp. (Throws an error if the folderId is invalid.)
  var parent = folderId ? DriveApp.getFolderById(folderId) : DriveApp;

  // I assume your fileName variable does not contain any unescaped single-quotes.
  var params = "name='" + fileName + "'";
  // If a mimetype was given, search by that type only, otherwise search any type.
  if (mimeType)
    params += " and mimeType='" + mimeType + "'";
  var matches = parent.searchFiles(params),
      results = [];

  // Collect and report results.
  while (matches.hasNext())
    results.push(matches.next());
  if (!results.length)
    throw new Error("Bad search query \"" + params + "\" for folder id = '" + folderId + "'.");

  // Sort descending by the creation date (a native Date object).
  // (a - b sorts ascending by first column).
  results.sort(function (a, b) { return b.getDateCreated() - a.getDateCreated(); });
  return results[0].getId();
}

You can read more about the acceptable search parameters in the Drive REST API documentation, and more about the Apps Script native implementation in the DriveApp documentation.

查看更多
登录 后发表回答