0

I create a PDF and then send its information to my website so that this PDF is converted to an image file and published:

    SpreadsheetApp.flush();
    var theurl = 'https://docs.google.com/a/mydomain.org/spreadsheets/d/' +
      'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +
        '/export?format=pdf' +
          '&size=0' +
            '&portrait=true' +
              '&fitw=true' + 
                '&top_margin=0' +            
                  '&bottom_margin=0' +         
                    '&left_margin=0' +        
                      '&right_margin=0' +     
                        '&sheetnames=false&printtitle=false' +
                          '&pagenum=false' +
                            '&gridlines=false' +
                              '&fzr=FALSE' +
                                '&gid=' +
                                  'aaaaaaaaaaa';
    
    var token = ScriptApp.getOAuthToken();
    var docurl = UrlFetchApp.fetch(theurl, { headers: { 'Authorization': 'Bearer ' +  token } });
    var pdfBlob = docurl.getBlob();
    
    //...get token and Blob (do not create the file);
    
    var fileName = ss.getSheetByName("General").getRange("H2").getValue();
    
    //Access or create the 'Archives' folder;
    var folder;
    var folders = DriveApp.getFoldersByName("Archives");
    if(folders.hasNext()) {
      folder = folders.next();
    }else {
      folder = DriveApp.createFolder("Archives");
    }
    
    //Remove duplicate file with the same name;
    var existing = folder.getFilesByName(fileName);
    if(existing.hasNext()) {
      var duplicate = existing.next();
      if (duplicate.getOwner().getEmail() == Session.getActiveUser().getEmail()) {
        var durl = 'https://www.googleapis.com/drive/v3/files/'+duplicate.getId();
        var dres = UrlFetchApp.fetch(durl,{
          method: 'delete',
          muteHttpExceptions: true,
          headers: {'Authorization': 'Bearer '+token}
        });
        var status = dres.getResponseCode();
        if (status >=400) {
          
        } else if (status == 204) {
          folder.createFile(pdfBlob.setName(fileName));
        }
      }
    } else {
      folder.createFile(pdfBlob.setName(fileName));
    }
    
    Utilities.sleep(5000);
    createPostByFileName(folder, fileName);
function createPostByFileName(folder, fileName) {
  var fileIterator = folder.getFilesByName(fileName);
  if(fileIterator.hasNext()) {
    var file = fileIterator.next()
    file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW)
    name = file.getName();
    league = name.split(' ')[0];
    title = name.split(league)[1].split('.pdf')[0];
    link = file.getUrl();
    shareable = link.split('/view')[0];
    id = file.getId();
    var data = {
      'api_league_name': league,
      'title': title,
      'google_drive_id': id,
      'google_drive_url': shareable,
      'pass': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
    };
    var options = {
      'method' : 'post',
      'contentType': 'application/json',
      'payload' : JSON.stringify(data)
    };
    UrlFetchApp.fetch('https://www.xxx.com.br/api/posts', options);
  }
}

For some reason I am forced to put Utilities.sleep(5000); before calling the function that sends the PDF data to my website, because if I don't, when the website tries to convert the PDF to an image, an problem happens as if the PDF is not yet available in the folder or it generates a big slowdown until can access the file.

Obviously putting this sleep is not a professional way to solve the case, because then I can't even know why this happens.

Anyone who has had this experience, can tell me how I should proceed in a professional way?

TheMaster
  • 45,448
  • 6
  • 62
  • 85
Digital Farmer
  • 1,705
  • 5
  • 17
  • 67
  • 1
    In your situation, for example, when the file is created by Drive API instead of DriveApp, is `Utilities.sleep(5000)` required to be used? – Tanaike May 27 '22 at 23:56
  • Hi @Tanaike I've never had contact with the use via Drive API, I'll study about it to be able to convert this code to use it! – Digital Farmer May 28 '22 at 00:11
  • 1
    Thank you for replying. Although I'm not sure whether using Drive API is the direct solution to your issue, I thought that it might be worth a try. – Tanaike May 28 '22 at 00:14
  • @Tanaike Do you know any way to convert a spreadsheet page into an image? It would also help me a lot if there is any way! I saw someone talking about saving as a PDF, then throwing that PDF into a Google Docs and converting it to an image there, but he didn't explain how. – Digital Farmer May 28 '22 at 00:57
  • 1
    About the conversion from PDF to image, is this answer useful? https://stackoverflow.com/a/55152707 And, as another workaround, how about both creating and sharing a file using only Drive API? How about testing it? – Tanaike May 28 '22 at 01:04
  • @Tanaike I'm still struggling to convert DriveApp to Drive API, I believe that in a few days I'll learn how to use it and I'll do the tests, thanks for indicating the answer URL, it was useful for learning! – Digital Farmer May 28 '22 at 01:09
  • 1
    Thank you for replying. Can you wait for it? I would like to modify your script using Drive API. – Tanaike May 28 '22 at 01:10
  • @Tanaike If you want to do it, I would thank you, it would be very useful for me and would help me to test it and see if it works. – Digital Farmer May 28 '22 at 01:29
  • @Tanaike Do you want me to create a question about how to convert this code from DriveApp to Drive API? – Digital Farmer May 28 '22 at 01:30
  • 1
    I prepared a modified script using Drive API. In this modification, your 2 functions are merged into one function. Could you please confirm it? If that was not useful, I apologize. – Tanaike May 28 '22 at 01:31

1 Answers1

2

From the discussions in the comment, when Drive API is used for your script, it becomes as follows. Before you use this, please enable Drive API at Advanced Google services.

Modified script:

function sample() {
  const createFile = (filename, blob, folderId) => Drive.Files.insert({ title: filename, parents: [{ id: folderId }] }, blob);

  SpreadsheetApp.flush();
  var theurl = 'https://docs.google.com/a/mydomain.org/spreadsheets/d/' +
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +
      '/export?format=pdf' +
        '&size=0' +
          '&portrait=true' +
            '&fitw=true' + 
              '&top_margin=0' +            
                '&bottom_margin=0' +         
                  '&left_margin=0' +        
                    '&right_margin=0' +     
                      '&sheetnames=false&printtitle=false' +
                        '&pagenum=false' +
                          '&gridlines=false' +
                            '&fzr=FALSE' +
                              '&gid=' +
                                'aaaaaaaaaaa';
  var token = ScriptApp.getOAuthToken();
  var docurl = UrlFetchApp.fetch(theurl, { headers: { 'Authorization': 'Bearer ' + token } });
  var pdfBlob = docurl.getBlob();
  var fileName = ss.getSheetByName("General").getRange("H2").getValue();
  var folder;
  var folders = DriveApp.getFoldersByName("Archives");
  if (folders.hasNext()) {
    folder = folders.next();
  } else {
    folder = DriveApp.createFolder("Archives");
  }
  var existing = folder.getFilesByName(fileName);
  var pdfFileId = "";
  if (existing.hasNext()) {
    var duplicate = existing.next();
    if (duplicate.getOwner().getEmail() == Session.getActiveUser().getEmail()) {
      var durl = 'https://www.googleapis.com/drive/v3/files/' + duplicate.getId();
      var dres = UrlFetchApp.fetch(durl, {
        method: 'delete',
        muteHttpExceptions: true,
        headers: { 'Authorization': 'Bearer ' + token }
      });
      var status = dres.getResponseCode();
      if (status >= 400) {
      } else if (status == 204) {
        var obj = createFile(fileName, pdfBlob, folder.getId());
        pdfFileId = obj.id;
      }
    }
  } else {
    var obj = createFile(fileName, pdfBlob, folder.getId());
    pdfFileId = obj.id;
  }

  // Utilities.sleep(5000);

  Drive.Permissions.insert({ role: "reader", type: "anyone" }, pdfFileId);
  league = fileName.split(' ')[0];
  title = fileName.split(league)[1].split('.pdf')[0];
  shareable = "https://drive.google.com/file/d/" + pdfFileId;
  id = pdfFileId;
  var data = {
    'api_league_name': league,
    'title': title,
    'google_drive_id': id,
    'google_drive_url': shareable,
    'pass': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
  };
  var options = {
    'method': 'post',
    'contentType': 'application/json',
    'payload': JSON.stringify(data)
  };
  UrlFetchApp.fetch('https://www.xxx.com.br/api/posts', options);
}

Note:

  • This is a sample script for testing whether Utilities.sleep(5000) can be removed.
Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • I've activated it for testing and I'll leave it working in the next few hours and see the result! – Digital Farmer May 28 '22 at 01:36
  • 1
    @Digital Farmer Thank you for replying. If this was not useful, I apologize. – Tanaike May 28 '22 at 01:37
  • Hi @Tanaike, it worked! Now it is no longer necessary to add the 5 seconds of sleep. Do you have any thesis on why DriveApp happens this problem and with Drive API it doesn't? – Digital Farmer May 28 '22 at 11:28
  • @Digital Farmer Thank you for replyng and testing it. I'm glad your issue was resolved. About your additional question of `Do you have any thesis on why DriveApp happens this problem and with Drive API it doesn't?`. Unfortunately, I have no it. This is due to my very poor skill. I deeply apologize for my very poor skill. I think that I have to study more. I would be grateful if you can forgive my very poor skill. – Tanaike May 28 '22 at 11:50