Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added list and update status with media supporting #130

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 142 additions & 3 deletions lib/twitter.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var VERSION = '0.2.8',
http = require('http'),
https = require('https'),
querystring = require('querystring'),
oauth = require('oauth'),
Cookies = require('cookies'),
Expand Down Expand Up @@ -539,6 +540,122 @@ Twitter.prototype.updateStatus = function(text, params, callback) {
return this;
}

Twitter.prototype.updateStatusWithMedia = function(status, media_name, media_row, encoding, params, callback) {
if (status === undefined) {
throw new Error('Missing required parameter: status.');
}

if (media_name === undefined) {
throw new Error('Missing required parameter: media_name.');
}

if (media_row === undefined) {
throw new Error('Missing required parameter: media_row.');
}

if (typeof encoding === 'function') {
callback = encoding;
encoding = 'base64'; // default encodingf
params = null;
}

if (typeof params === 'function') {
callback = params;
params = null;
}

var url = this.options.rest_base + '/statuses/update_with_media.json';
var defaults = {
status: status
};
params = utils.merge(defaults, params);

// Workaround: oauth + booleans == broken signatures
if (params && typeof params === 'object') {
Object.keys(params).forEach(function(e) {
if ( typeof params[e] === 'boolean' )
params[e] = params[e].toString();
});
}

// oauth - multipart post
var crlf = '\r\n';
var boundary = 'ece072908565ge59x89ch983452389hosdfd8923y523hedhf923y53';
var separator = '--' + boundary;
var footer = crlf + separator + '--' + crlf;
var fileHttpHeader = 'Content-Disposition: form-data; name="media[]"; filename="' + media_name + '"';
if (encoding === 'base64') {
fileHttpHeader = fileHttpHeader + crlf + 'Content-Transfer-Encoding: base64';
media_row = new Buffer(media_row); // convert base64 string to binary
}
var contents = separator + crlf
+ 'Content-Disposition: form-data; name="status"' + crlf
+ crlf
+ status + crlf
+ separator + crlf
+ 'Content-Type: application/octet-stream' + crlf
+ fileHttpHeader + crlf
+ crlf;

var multipartBody = Buffer.concat([
new Buffer(contents),
media_row,
new Buffer(footer)
]);

var hostname = 'api.twitter.com';
var authorization = this.oauth.authHeader(
'https://api.twitter.com/1.1/statuses/update_with_media.json',
this.options.access_token_key, this.options.access_token_secret, 'POST');
var headers = {
'Authorization': authorization,
'Content-Type': 'multipart/form-data;boundary=' + boundary,
'Host': hostname,
'Content-Length': multipartBody.length/*,
'Connection': 'Keep-Alive'*/
};
var options = {
host: hostname,
port: 443,
path: '/1.1/statuses/update_with_media.json',
method: 'POST',
headers: headers
};

var req = https.request(options, function (res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
try {
var json = JSON.parse(chunk);
}
catch(err) {
return callback(err);
}
callback(null, json);
});
res.on('end', function () {
});
});
req.write(multipartBody);
req.end();

req.on('error', function(error) {
if ( error && error.statusCode ) {
var err = new Error('HTTP Error '
+ error.statusCode + ': '
+ http.STATUS_CODES[error.statusCode]
+ ', API message: ' + error.data);
err.data = error.data;
err.statusCode = error.statusCode;
callback(err);
} else if (error) {
callback(error);
}
});

return this;
}

Twitter.prototype.destroyStatus = function(id, callback) {
var url = '/statuses/destroy/' + escape(id) + '.json';
this.post(url, null, null, callback);
Expand Down Expand Up @@ -690,15 +807,18 @@ Twitter.prototype.getLists = function(id, params, callback) {
params = null;
}

var defaults = {key:'lists'};
var defaults = {};
if (typeof id === 'string')
defaults.screen_name = id;
else
defaults.user_id = id;
params = utils.merge(defaults, params);

var url = '/lists.json';
this._getUsingCursor(url, params, callback);
// FIX by Eric Cao
//var url = '/lists.json';
//this._getUsingCursor(url, params, callback);
var url = '/lists/list.json';
this.get(url, params, callback);
return this;
}

Expand Down Expand Up @@ -738,6 +858,25 @@ Twitter.prototype.getListSubscriptions = function(id, params, callback) {
return this;
}

// Added by Eric Cao
Twitter.prototype.getListsStatuses = function(id, screen_name, params, callback) {
if (typeof params === 'function') {
callback = params;
params = null;
}

var defaults = {
list_id: id,
owner_screen_name: screen_name
};
params = utils.merge(defaults, params);


var url = '/lists/statuses.json';
this.get(url, params, callback);
return this;
}

// FIXME: Uses deprecated Twitter lists API
Twitter.prototype.showList = function(screen_name, list_id, callback) {
var url = '/' + escape(screen_name) + '/lists/' + escape(list_id) + '.json';
Expand Down