google-apps-scriptgoogle-drive-apithumbnailsgoogle-slides

The thumbnail of a presentation is empty immediately after it is created, saved and closed


I create a presentation, insert an image into it, save and close it. Using the Drive API I get a thumbnailLink, then a blob and from it I create a PNG file. The problem is that the file is empty and does not contain the inserted image.

Here's the code:

function toPng() {
  const folderId = "###";
  const imageUrl = "https://www.google.com/images/srpr/logo3w.png";

  var presentation = SlidesApp.create('Test');
  var prId = presentation.getId();
  // var prId = "#####";

  var slide = presentation.getSlides()[0];
  slide.insertImage(imageUrl);
  presentation.saveAndClose();
  // Utilities.sleep(60000);

  const thumbLink = Drive.Files.get(prId).thumbnailLink;
  const thumbnailURL = thumbLink.replace(/=s.+/, "=s100");

  const pngBlob = UrlFetchApp.fetch(thumbnailURL).getBlob();
  const destinationFolder = DriveApp.getFolderById(folderId);
  destinationFolder.createFile(pngBlob).setName('newFile.png');
}

If you comment out var prId = presentation.getId() and substitute the id of the previously created presentation var prId = "#####", then everything is fine, the image is in the file.

I assumed the problem was that the thumbnail takes a while to create. I added Utilities.sleep(1000), increased the delay time to 2 minutes - it didn’t help.

I would be grateful for your ideas on how to solve this problem.


Solution

  • I had the same situation with you. Unfortunately, I'm not sure whether this is the current specification or a bug. But, at that time, when Slides API was used, I noticed that the thumbnail could be obtained. So, as the current workaround, how about using Slides API? When this is reflected in your showing script, it becomes as follows.

    When you test this, please enable Slides API at Advanced Google services.

    From:

    const thumbLink = Drive.Files.get(prId).thumbnailLink;
    const thumbnailURL = thumbLink.replace(/=s.+/, "=s100");
    

    To:

    const thumbnailURL = Slides.Presentations.Pages.getThumbnail(prId, slide.getObjectId(), { "thumbnailProperties.mimeType": "PNG", "thumbnailProperties.thumbnailSize": "SMALL" }).contentUrl;
    

    Reference:

    Added 1

    About the following reply,

    Unfortunately, the workaround does not allow you to get different sizes, for example, the one stated in the post (=s100).

    When my proposed workaround is used, how about the following modification?

    Modified script:

    function toPng() {
      const folderId = "###";
      const imageUrl = "https://www.google.com/images/srpr/logo3w.png";
    
      var presentation = SlidesApp.create('Test');
      var prId = presentation.getId();
      // var prId = "#####";
    
      var slide = presentation.getSlides()[0];
      slide.insertImage(imageUrl);
      presentation.saveAndClose();
      // Utilities.sleep(60000);
    
      // const thumbLink = Drive.Files.get(prId).thumbnailLink;
      // const thumbnailURL = thumbLink.replace(/=s.+/, "=s100");
    
      const thumbnailURL = Slides.Presentations.Pages.getThumbnail(prId, slide.getObjectId(), { "thumbnailProperties.mimeType": "PNG", "thumbnailProperties.thumbnailSize": "SMALL" }).contentUrl;
      const temp = DriveApp.createFile(UrlFetchApp.fetch(thumbnailURL).getBlob());
      const url = `https://drive.google.com/thumbnail?sz=w100&id=${temp.getId()}`; // This endpoint is from https://stackoverflow.com/a/31504086
      const pngBlob = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } }).getBlob();
      Drive.Files.remove(temp.getId());
    
      const destinationFolder = DriveApp.getFolderById(folderId);
      destinationFolder.createFile(pngBlob).setName('newFile.png');
    }
    

    With this modification, when you can adjust the output image size by modifying w100.

    Added 2:

    As another approach, how about modifying as follows? I come up with another approach, just now. In this approach, the created file is copied. And, the thumbnail link is retrieved from the copied Google Slide. When I tested the following script, I confirmed that a valid thumbnail image could be obtained. Please test it.

    function toPng() {
      const folderId = "###";
      const imageUrl = "https://www.google.com/images/srpr/logo3w.png";
    
      var presentation = SlidesApp.create('Test');
      var prId = presentation.getId();
      // var prId = "#####";
    
      var slide = presentation.getSlides()[0];
      slide.insertImage(imageUrl);
      presentation.saveAndClose();
      // Utilities.sleep(60000);
      
      var temp = DriveApp.getFileById(prId).makeCopy("temp").getId();
      const thumbLink = Drive.Files.get(temp, { fields: "thumbnailLink" }).thumbnailLink;
      const thumbnailURL = thumbLink.replace(/=s.+/, "=s100");
      const pngBlob = UrlFetchApp.fetch(thumbnailURL).getBlob();
      const destinationFolder = DriveApp.getFolderById(folderId);
      destinationFolder.createFile(pngBlob).setName('newFile.png');
      Drive.Files.remove(temp);
    }