Search code examples
pdfgoogle-apps-scriptmicrosoft-graph-apibinarystream

Converting PDF to Binary Stream in GAS for MS Graph API


I am fetching a PDF - getPDF() - to then upload to a Sharepoint Document Library. The following code fetches the PDF and creates a file called 'filename.pdf', however the file cannot be displayed presumably because the incorrect data is being loaded.

I can prove the PDF is being fetched because the file blob has an expected file size. I can also prove that the created file has various file sizes depending on how I manipulate the code. This has allowed me to narrow it down to how I am preparing the PDF for upload.

var myPDF = getPDF()
var myFile = myPDF.getBlob().getBytes()

var myBody = {
  file:myFile
}

var url = 'https://graph.microsoft.com/v1.0/drives/'+drive_id+'/items/'+parent_id+':/filename.pdf:/content'

var headers = {"Authorization" : 'Bearer ' + code};

var params = {
  'method': 'PUT',
  'muteHttpExceptions': true,
  'headers': headers,
  'contentType': 'application/json;odata=verbose',
  'payload': JSON.stringify(myBody)
};

var res = UrlFetchApp.fetch(url, params);
var myObj = JSON.parse(res.getContentText());
console.log(myObj)

Per the docs:

The contents of the request body should be the binary stream of the file to be uploaded.

I assume this is isn't working because var myFile = myPDF.getBlob().getBytes() is not the correct way to convert a PDF to a 'binary stream'.

I have tried wrapping myFile in Utilities.base64Encode, and prepending myFile with "data:application/pdf;base64,".


Solution

  • In your script, how about the following modification?

    Modified script:

    const code = "###"; // Please set your access token.
    var drive_id = "###"; // Please set your drive ID.
    var parent_id = "###"; // Please set your folder ID you want to upload the file.
    
    var myPDF = getPDF();
    var url = 'https://graph.microsoft.com/v1.0/drives/' + drive_id + '/items/' + parent_id + ':/filename.pdf:/content'
    var headers = { "Authorization": 'Bearer ' + code };
    var params = {
      'method': 'PUT',
      'muteHttpExceptions': true,
      'headers': headers,
      'contentType': 'application/pdf', // I thought that in this case, this might not be able to be required to be used.
      'payload': myPDF.getBlob().getBytes()
    };
    var res = UrlFetchApp.fetch(url, params);
    var myObj = JSON.parse(res.getContentText());
    console.log(myObj)
    
    • In this case, I think that you can directly upload the byte array with payload. But, from your showing script, your data is uploaded as string data. I think that this might be the reason for your issue.

    Note:

    • When I tested this modified script, I could confirm that a PDF file was uploaded to the specific folder on OneDrive. But, if an error occurs, please check your code, drive_id and parent_id, again.

    References: