Hello!

I'm developing Twitter client and I want to add option for uploading
photo to Twitpic. This is the code:

[...] // Listener on "Add photo" button.

triggerBtn.addEventListener('click', function() {
    opera.io.filesystem.browseForFile('', '', function(mp) {
        var fs = mp.open(null, 'r'),
              data = fs.readBase64(fs.bytesAvailable);

         uploadPhoto(data);
    }, false, false, []);
}, false);

[...]

function uploadPhoto(photoB64) {
    // Run method from library for handling communication with Twitpic
    O.Twitpic.upload(photoB64, {
        fn: function(req) {
            console.info('upload success', req.responseText);
        }
    }, {
        fn: function(req) {
            console.info('upload failure', req.responseText);
        }
    });
}

[...]

upload: function(photo, onSuccess, onFailure) {
    makeRequest(
        O.IO.Req.POST,
        'http://api.twitpic.com/2/upload.json',
        [
            {name: 'key', value: TWITPIC_KEY},
            {name: 'message', value: 'message'},
            {name: 'media', value: 'data:image/png;base64,' +photo}
        ],
        onSuccess,
        onFailure
    );
}

[...]

function makeRequest(method, action, parameters, onSuccess, onFailure)
{
    var message = {
        method: method,
        action: action,
        parameters: []
    };

    parameters.forEach(function(parameter) {
        message.parameters.push([parameter.name, parameter.value]);
    });


    var body = OAuth.formEncode(message.parameters);

    var o = {
       consumerKey: O.Twitter.getConsumerKey(),
       consumerSecret: O.Twitter.getConsumerSecret(),
       token: O.Twitter.getAccessToken(),
       tokenSecret: O.Twitter.getAccessTokenSecret()
    };

    OAuth.completeRequest(message, o);

    var authHeader = OAuth.getAuthorizationHeader('https://
twitter.com/',
 
message.parameters);

    new O.IO.Req({
        url: action
        data: body,
        method: method,
        headers: [{
            name: 'X-Verify-Credentials-Authorization',
            val: authHeader
        }, {
             name: 'X-Auth-Service-Provider',
             val: 'https://api.twitter.com/1/account/
verify_credentials.json'
        }],
         onSuccess: {
             fn: function(req) {
                 try{
                     var respJSON = JSON.parse(req.responseText);
                     onSuccess.fn.call(onSuccess.scope, req,
respJSON);
                  } catch(e) {
                     onFailure.fn.call(onFailure.scope, req);
                  }
            }
        },
        onFailure: {
            fn: function(req) {
                try{
                    var respJSON = JSON.parse(req.responseText);
                    onFailure.fn.call(onFailure.scope, req, respJSON);
                } catch(e) {
                    onFailure.fn.call(onFailure.scope, req);
                }
            }
        }});
}

[...] // O.IO.Req constructor

/**
 * Ajax request class.
 * @class Req
 * @constructor
 */
O.IO.Req = function(o) {
    this._url = o.url;
    this._onSuccess = o.onSuccess;
    this._onFailure = o.onFailure;
    this._data = o.data;
    this._sync = typeof o.sync === "boolean" ? o.sync : true;
    this._headers = o.headers || [];
    this._method = o.method || "GET";

    this._req = new XMLHttpRequest();
    this._req.open(this._method, this._url, this._sync);

    if(this._method === "POST") {
        this._req.setRequestHeader("Content-type",
            "application/x-www-form-urlencoded");
    }

    var that = this;
    this._headers.forEach(function(header) {
        that._req.setRequestHeader(header.name, header.val);
    });

    this._req.onreadystatechange = function () {
        if (this.readyState != 4) { return };

        if (this.status != 200 && this.status != 304 && this.status !=
0) {
            that._onFailure.fn.call(that._onFailure.scope, this);
            return;
        }

        that._onSuccess.fn.call(that._onSuccess.scope, this);
    };

    if(this._req.readyState == 4) { return; }

    console.info('data', this._data);
    this._req.send(this._data);
};

This is how look data passed to send method (displayed with the last
console.info):

key={MY_TWITPIC_KEY}&message=message&media=data%3Aimage%2Fpng
%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAFEAAACECAIAAABnHlD9AAAAAXNS...

Response:

{"errors":[{"code":400,"message":"Bad Request. Media not included in
POST payload."}]}

I tried also without 'data:image/png;base64,' prefix in data but I get
the same resposne. This media should be sent as I'm doing it or in
some other way like files in standard html forms?

-- 
Twitter developer documentation and resources: http://dev.twitter.com/doc
API updates via Twitter: http://twitter.com/twitterapi
Issues/Enhancements Tracker: http://code.google.com/p/twitter-api/issues/list
Change your membership to this group: 
http://groups.google.com/group/twitter-development-talk

Reply via email to