Javascript problem "/media/upload": how to handle file for the append phase?

cordova
javascript
media-upload

#1

Hello everyone,

I’m new with the Twitter API and I’m currently working with Cordova in Javascript and i’m facing a problem with the “media/upload” (INIT/APPEND/FINISH) .

Here is the js function I use to sign my request.

function createTwitterSignature(method, url, params) {
        var token = angular.fromJson(getStoredToken());
        var oauthObject = {
            oauth_consumer_key: clientId,
            oauth_nonce: $cordovaOauthUtility.createNonce(10),
            oauth_signature_method: "HMAC-SHA1",
            oauth_token: token.oauth_token,
            oauth_timestamp: Math.round((new Date()).getTime() / 1000.0),
            oauth_version: "1.0"
        };
        var signatureObj = $cordovaOauthUtility.createSignature(method, url, oauthObject, params, clientSecret, token.oauth_token_secret);
        $http.defaults.headers.common.Authorization = signatureObj.authorization_header;
    }

For the “INITIALIZE” step:

I call my function, who takes the file I want to upload in parameter (Media is in Blob format (Binary Large Objects))
So I can easily get the mimeType and the size of the file.

tweetInitMediaStatus: function(media) {
			var media_upload_url = 'https://upload.twitter.com/1.1/media/upload.json';
			var results = createTwitterSignature('POST', media_upload_url, {'command': 'INIT', 'total_bytes': media.size, 'media_type': media.type});
			return $resource(media_upload_url, {'command': 'INIT', 'total_bytes': media.size, 'media_type': media.type}).save().$promise;
        }

After this call, I get back a promise who contains the media_id_string that I need to use for the next step.

For the “APPEND” step:

This is where I don’t really understand. I use a function almost similar to the first one.

tweetAppendMediaStatus: function(media_id,media,segment) {
			var media_upload_url = 'https://upload.twitter.com/1.1/media/upload.json';		
			var results = createTwitterSignature('POST', media_upload_url, {'command': 'APPEND', 'media': media, 'media_id': media_id, 'segment_index': segment});
			return $resource(media_upload_url, {'command': 'APPEND', 'media': media, 'media_id': media_id, 'segment_index': segment}).save().$promise;
        }

First case :

I get an error because the media parameter is in the URL and a blob parameter should be sent in a FormData instead. If i use a FormData i get a media parameter is missing. So I guess I don’t really know where I should place the FormData in the signature.

Second case :

Example :
https://upload.twitter.com/1.1/media/upload.json?command=APPEND&media_id=123&segment_index=2&media_data=123

However, if i choose to use media_data instead of media, i need to use the file as a base64-encoded. But the header is too short and the request sent me back an error 431 Request Header Fields Too Large

So my problem is that i don’t really know how i should send my parameters either with a media binary or a media base64-encoded.

Thank you for your advice/help :slight_smile: