Home > Net >  How to fix this? Twitter Api v1.1 post multipart request(Append endpoint) from Google apps script al
How to fix this? Twitter Api v1.1 post multipart request(Append endpoint) from Google apps script al

Time:03-28

In the below function, I got an error response from Twitter as "Bad request". Please help me to solve this.

//param1 file === DriveApp.getFileById()
//param2 init === returned object of initTwitterUpload function
//param3 service === OAuth1.createService()
function appendTwitterUpload(file,init,service) {
  var blob = file.getBlob()
  var bytes = blob.getBytes()
  var base64Blob = Utilities.base64Encode(bytes)
  var metaData = {name: file.getName(),
    mimeType: file.getMimeType()}
  var baseUrl =  "https://upload.twitter.com/1.1/media/upload.json" //?command=APPEND&media_id=" 
    //Oauth1percentEncode(init["media_id_string"])    "&segment_index="   Oauth1percentEncode(0);
  var options = {method:'POST',
                 contentType : 'multipart/form-data',
                 payload : {'command':'APPEND',
                            'media_id' : init["media_id"],
                            'segment_index': 0,
                           },
                 files:{'media': bytes},
                 muteHttpExceptions:true}
  var response = service.fetch(baseUrl,options);
  return JSON.parse(response.getContentText())
}

I appreciate a quick fix. any Twitter developer out there finding bugs, I have found one with Google apps script. I am using OAuth 1.0a authentication and following all the procedures mentioned in the documentation correctly. Please give an exact fix for the above function. I am using Urlfetchapp for posting the payload with content-type of multipart/form-data. Service param here is nothing but urlfetchapp with required authentication headers that is available in Oauth 1 library enter image description here

/Twitter file upload - init -->append -->finalize/ initTwitterUpload function is working perfectly. Service param is a urlfetchapp with authorization headers and matches with one of the functions in the oauth1 library(fetch)

Other functions in my gs file:

function uploadTwitterMedia(mediaUrl){
    var file = DriveApp.getFileById(mediaUrl.replace("https://drive.google.com/open?id=",""))
    var initResponse = initTwitterUpload(mediaUrl,service)
    var appendResponse = appendTwitterUpload(file,initResponse,service)
    var finalizeResponse = finalizeTwitterUpload(initResponse,service)
    return initResponse["media_id_string"]
}

function initTwitterUpload(url,service){
  var file = DriveApp.getFileById(url.replace("https://drive.google.com/open?id=",""))
  var type = file.getMimeType()
  var size = file.getSize()
  var baseUrl =  "https://upload.twitter.com/1.1/media/upload.json?"
  var oauthParams = "command=INIT&total_bytes=" encodeURIComponent(size).replace(/\!/g, "!")
  .replace(/\*/g, "*")
  .replace(/\'/g, "'")
  .replace(/\(/g, "(")
  .replace(/\)/g, ")") "&media_type=" encodeURIComponent(type).replace(/\!/g, "!")
  .replace(/\*/g, "*")
  .replace(/\'/g, "'")
  .replace(/\(/g, "(")
  .replace(/\)/g, ")") "&media_category="  Oauth1percentEncode("TWEET_IMAGE");
  var tweetUrl = baseUrl   oauthParams 
  var response = service.fetch(tweetUrl,{method:'POST'})
  return JSON.parse(response.getContentText())
}



function finalizeTwitterUpload(init,service){
  var baseUrl =  "https://upload.twitter.com/1.1/media/upload.json?"
  var params = "command=FINALIZE&media_id=" Oauth1percentEncode(init["media_id_string"])
  var tweetUrl = baseUrl   params 
  var response = service.fetch(tweetUrl,{method:'POST',
                                        muteHttpExceptions:true})
  return JSON.parse(response.getContentText())
}


function Oauth1percentEncode(text){
  text = encodeURIComponent(text).replace(/\!/g, "!").replace(/\*/g, "*").replace(/\'/g, "'")
  .replace(/\(/g, "(");
  return text
}

Also, the statusTwitterUpload function is not working as expected, it gives a response as "Page not found".I appreciate any kind of help.

CodePudding user response:

I found an answer. Thanks to me

function appendTwitterUpload(file,init,service) {
  var options = null
  var response = null
  var baseUrl = "https://upload.twitter.com/1.1/media/upload.json?command=APPEND&media_id="   init["media_id_string"]  
    "&segment_index="   Oauth1percentEncode(0);
  var boundary = "xxxxxxxxxx";
  var data = "";
  data  = "--"   boundary   "\r\n";
  data  = "Content-Disposition: form-data; name=\"media\"; filename=\""   file.getName()   "\"\r\n";
  data  = "Content-Type:"   file.getMimeType()   "\r\n\r\n";
  
  //retry fracemork for  drive service error
  var getPayload = partial (function(data,file,boundary){ return Utilities.newBlob(data).getBytes()
  .concat(file.getBlob().getBytes())
  .concat(Utilities.newBlob("\r\n--"   boundary   "--").getBytes());},data,file,boundary)
  var payload = executeWithRetry(getPayload,3)
  
  var options = {
    method : "post",
    contentType : "multipart/form-data; boundary="   boundary,
    payload : payload,
      muteHttpExceptions: true,
}
var response = service.fetch(baseUrl,options);
console.log("response---_>", response.getResponseCode());
return response.getResponseCode()
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.2/angular.min.js"></script>
Replace appendTwitterUpload with the function in the answer

  • Related