google-apps-scriptgoogle-drive-api

Overwrite an Image File with Google Apps Script


Can I overwrite an image file with Google Apps Script? I've tried:

file.setContent(newBlobImage);
file.replace(newBlobImage);

Neither of those work. .setContent() will delete whatever data was in the file, and it looks like maybe it just writes the variable name as text, or something like that. I'm assuming that both .setContent() and .replace() are meant for text documents, and maybe that's why they don't work.

If it were a text file, or a spreadsheet, I might be able to clear it, then append new content.

I can trash the file, then create a new one, but I'd rather not if there is some other way.

If I write a file with the same name, it won't overwrite the existing file, it creates a another file with the same name.

The only way I've been able to trash the file is with DocsList and the only success I've had with creating an image file is with DriveApp. So I have to trash the file with DocsList, then create another file with DriveApp.

Well, I've figured out how to delete the file without sending it to the trash, so I won't need to clean out the trash later. The Google Drive SDK inside of Apps Script has a remove method that didn't send the file to trash, it's just gone.

var myFolder = DriveApp.getFolderById('3Bg2dKau456ySkhNBWB98W5sSTM');

thisFile = myFolder.getFilesByName(myFileName);

while (thisFile.hasNext()) {
  var eachFile = thisFile.next();
  var idToDLET = eachFile.getId();
  Logger.log('idToDLET: ' + idToDLET);

  var rtrnFromDLET = Drive.Files.remove(idToDLET);
};

So, I'm combining the DriveApp service and the DriveAPI to delete the file without sending it to the trash. The DriveAPI .remove needs the file ID, but I don't have the file ID, so the file gets looked up by name, then the file ID is retrieved, then the ID is used to delete the file. So, if I can't find a way to overwrite the file, I can at least delete the old file without it going to the trash.

I just noticed that the DriveAPI service has a Patch and an Update option.

.patch(resource, fileId, optionalArgs)

Google Documentation Patch Updates file metadata.

The resource arg is probably the metadata. The fileId is self explanatory. I'm guessing that the optionalArgs are parameters that follow the HTTP Request Patch semantics? I don't know.

It looks like both Patch and Update will update data. Update is a PUT request that will

clears previously set data if you don't supply optional parameters.

According to the documentation. So it's safer to use a Patch request because any parameters that are missing are simply ignored. I haven't tried it yet, but maybe this is the answer.

I'm getting an error with Patch, so I'll try Update:

.update(resource, fileId, mediaData)

That has a arg for mediaData in the form of a blob. And I think that is what I need. But I'm not sure what the resource parameter needs. So I'm stuck there.


Solution

  • An image file can be overwritten with Google Apps Script and the DriveAPI using the update() method:

    .update(File resource, String fileId, Blob mediaData)
    

    Where file resource is:

    var myFileName = 'fileName' + '.jpg';
    
    var file = {
      title: myFileName,
      mimeType: 'image/jpeg'
    };
    

    I'm getting the file ID with the DriveApp service, and the Blob is what was uploaded by the user.

    In order to use DriveAPI, you need to add it through the Resources, Advanced Google Services menu. Set the Drive API to ON.

    var allFilesByName,file,myFolder,myVar,theFileID,thisFile;
       //Define var names without assigning a value
    
    file = {
      title: myFileName,
      mimeType: 'image/jpeg'
    };
    
    myFolder = DriveApp.getFolderById('Folder ID');
    
    allFilesByName = myFolder.getFilesByName(myFileName);
    
    while (allFilesByName.hasNext()) {
      thisFile = allFilesByName.next();
      theFileID = thisFile.getId();
      //Logger.log('theFileID: ' + theFileID);
      
      myVar = Drive.Files.update(file, theFileID, uploadedBlob);
    };