1
votes

I am new to SO.

I am trying to hit an api using put request to upload the images and I wanted to do it using google sheets and google apps script. I am able to add images from url to the sheet but not to the api because it accepts only .png/.jpeg format and I think currently it is going in blob format. Not sure.

Can anyone please help me on how to send image to api using google apps script and sheet.

I am able to get success response using postman when in params I type image as key (filetype) and then upload image from device.

Here is some code that I am using to achieve the above:

function insertImageOnSpreadsheet() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();

  var sheet = ss.getSheetByName('Sheet1');

  var response = UrlFetchApp.fetch('Enter URL Here');
  var binaryData = response.getContent();

  // Insert the image in cell A1.
  var blob1 = Utilities.newBlob(binaryData, 'image/png', 'MyImageName');
  Logger.log(blob1)
  
      var apiHeaders = 
    {
      "Content-Type":"application/json",
      "Authorization":"Enter Token here"
    }
    var formData= '{"image": "'+blob1+'"}'

    var eventApiResponse = callApi('Enter API Here',"put",formData,apiHeaders,"insertImageOnSpreadsheet");
    Logger.log(eventApiResponse)
 
 
  sheet.insertImage(blob1, 1, 3);
}

function callApi(targetURL, method, formData, headers,functionName) {
  var options = {
    "method": method,
    "payload":formData,
    "headers":headers}
  var response = UrlFetchApp.fetch(targetURL, options);
  return response;
 }

API : livestream.com/developers/docs/api/#update-event-logo-poster

Somebody pleaasseee help

1
In order to correctly understand about your current situation, can you provide the specification of the API you want to use and the current error message? - Tanaike
The API says unsupported file type. So I assume that my code is sending blob. API accepts a png file in the image key - Ponnay
Thank you for replying. For example, when you send the file as the byte array instead of the blob, what result will you get? It's like var formData = Utilities.newBlob(binaryData, 'image/png', 'MyImageName').getBytes() or var formData = JSON.stringify({image: Utilities.newBlob(binaryData, 'image/png', 'MyImageName').getBytes()}). If those were not the direct solution, I apologize. - Tanaike
Although I cannot still understand about the specification of the API you want to use, from The API says unsupported file type, for example, how about base64? - Tanaike
API will only accept Images in png and jpeg, no other file format or format like base64 or blob will be accepted. Error - {"code":415,"message":"HTTP 415 Unsupported Media Type"} - Ponnay

1 Answers

0
votes

I believe your goal as follows.

Modification points:

  • When I saw the sample curl command of "Update Event Logo (Poster)", it is as follows.

      curl -X PUT \
        -u [API_SECRET_KEY] \
        -F logo='@<image file location>;type=<image type>' \
        --header 'Content-Type: multipart/form-data' \
        'https://livestreamapis.com/v3/accounts/18855759/events/5201483/logo'
    
    • In this case, the basic authorization is used. And it seems that the request body is required to be sent {"logo": "data"} to "files" using multipart/form-data.
    • In order to send the file data with multipart/form-data, it is required to create the request body.
      • In this case, the request body is created with the byte array, because the binary data is included.
  • In your script,

    • I cannot understand about "Authorization":"Enter Token here". But from the sample curl command, I thought that "API_SECRET_KEY" was not encoded with the base64.
    • At the sample curl command, "Content-Type":"application/json" is not used.

Modified script:

When your script is modified it becomes as follows.

const url = "###";  // Please set URL you want to use. It's like "https://livestreamapis.com/v3/accounts/18855759/events/5201483/logo".
const API_SECRET_KEY = "###";  // Please set your API_SECRET_KEY
// var binaryData = UrlFetchApp.fetch('Enter URL Here').getContent();
const binaryData = DriveApp.getFileById("### fileId ###").getBlob().getBytes();  // Modified

let data = "--xxxxxxxxxx\r\n";
data += "Content-Disposition: form-data; name=\"logo\"; filename=\"sample.png\"\r\n";
data += "Content-Type: image/png\r\n\r\n";
const payload = Utilities.newBlob(data).getBytes()
  .concat(binaryData)
  .concat(Utilities.newBlob("\r\n--xxxxxxxxxx--").getBytes());
const options = {
  method : "put",
  contentType : "multipart/form-data; boundary=xxxxxxxxxx",
  payload : payload,
  headers: {authorization : "Basic " + Utilities.base64Encode(API_SECRET_KEY)},
};
const res = UrlFetchApp.fetch(url, options);
console.log(res.getContentText())

var blob1 = Utilities.newBlob(binaryData, 'image/png', 'MyImageName');
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
sheet.insertImage(blob1, 1, 3);
  • In my environment, I could confirm that the request of above modified script is the same with that of the curl command.
  • In this case, it supposes that UrlFetchApp.fetch('Enter URL Here'); returns the binary data of the image of PNG or JPEG. Please be careful this.

Note:

  • Please use this script with enabling V8 runtime.
  • In this case, the line breaks in data is important. So please be careful this.
  • When your "API_SECRET_KEY" and URL are not correct, an error occurs. Please be careful this.
  • From the sample curl command, I proposed authorization : "Basic " + Utilities.base64Encode(API_SECRET_KEY) as the authorization header. But if API_SECRET_KEY is the same with "Basic " + Utilities.base64Encode(API_SECRET_KEY), please try to modify to authorization : "API_SECRET_KEY".

Reference: