javascriptgoogle-sheetsgoogle-apps-scriptgoogle-drive-api

Overwriting PDF File with Google Apps Scripts Causes Drive App to be unable to locate file


I have some code in Apps Script that saves a Google Sheet as a PDF.

I need to be able to update the PDF file when the form changes, without creating a new file and deleting the old one.

In theory, I think that what I have below should work. But when I make a call to the Advanced Drive Service's API, it says it cannot find the file, even though I am certain the File ID is correct and if call it in another context, e.g. to get its name, Drive seems to be able to find it.

    function replaceFile(theBlob, theFileId) 
{
  var oldFile = DriveApp.getFileById(theFileId);
  Logger.log(oldFile.getId());
  try
  {
    
    Drive.Files.update(
      {
        title: oldFile.getName(),
        mimeType: oldFile.getMimeType()
      },
      theFileId,
      theBlob,
      {
        convert: true, supportAllDrives: true
      }
    );
    
    Logger.log(Drive.Files.get('11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc', {supportsAllDrives: true}).getName());
    Logger.log("Success!");
    SpreadsheetApp.getActive().toast("PDF Updated With Success");
  }
  catch (error)
  {
    Logger.log(error);
    SpreadsheetApp.getActive().toast(error);
    
  }

}
function test1 ()
{
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var pdfBlob = spreadsheet.getAs('application/pdf');
  replaceFile(pdfBlob,"1UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc");
}

Here is the error I get:

GoogleJsonResponseException: API call to drive.files.get failed with error: File not found: 11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc.

Here is the link to the code I based mine on: How can I overwrite the old file with app script when I save the file?

As far as I can tell what I have should work.

EDIT: here is my updated script, when I retreive the file with the Drive.Files.get() function it works, but with Drive.Files.update() it says the file is not found.

function replaceFile(theBlob, theFileId) 
{
  var oldFile = DriveApp.getFileById(theFileId);
  Logger.log(oldFile.getId());
  try
  {
    
    Drive.Files.update(
  { mimeType: oldFile.getMimeType() },
    theFileId,
    theBlob,
  { supportAllDrives: true }
  );
    
    Logger.log(Drive.Files.get(theFileId, {supportsAllDrives: true}).getName());
    Logger.log("Success!");
    SpreadsheetApp.getActive().toast("PDF Updated With Success");
    
    
  }
  catch (error)
  {
    Logger.log(error);
    SpreadsheetApp.getActive().toast(error);
    
  }

}

function test1 ()
{
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  SpreadsheetApp.flush();
  var pdfBlob = spreadsheet.getAs('application/pdf');
  replaceFile(pdfBlob,"1ZuftxjH8t6WVKR-sxHl98iywhRPDHnC-");
}

Solution

  • From your showing error message GoogleJsonResponseException: API call to drive.files.get failed with error: File not found: 11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc., I guessed that the other part of your script worked.

    And, from this error message, it seems that the file of file ID 11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc is not existing at Drive.Files.get('11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc', {supportsAllDrives: true}).getName().

    When I saw your showing script, your file ID of theFileId is as follows.

    1UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc
    

    But, at Drive.Files.get('11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc', {supportsAllDrives: true}).getName(), you use the file ID as follows.

    11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc
    

    I guessed that in this case, the 1st character 1 is required to be removed. I guessed that this might be the reason for your current issue.

    If you want to use theFileId at Drive.Files.get('11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc', {supportsAllDrives: true}).getName(), how about the following modification?

    From:

    Drive.Files.get('11UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc', {supportsAllDrives: true}).getName()
    

    To:

    Drive.Files.get(theFileId, {supportsAllDrives: true}).getName()
    

    or

    Drive.Files.get('1UNOvk1qO5yR0Rs0xF3LrWaxYEgOxlRfc', {supportsAllDrives: true}).getName()
    

    Also, in order to retrieve the file name using Drive.Files.get of Drive API v3, you can also use Drive.Files.get(theFileId, {supportsAllDrives: true}).name.

    Note:

    Reference: