Want to use Nodejs to write a microblogging client Weibo, helpless Sina Weibo Nodejs SDK is OAuth1.0.
can only oneself according to OAuth1.0 change.
Only write Statuses/update and Statuses/upload, the other implementations are basically similar.
Update is a simple parameter post,upload is the multipart contains a binary picture of the post.
Change the account parameters and send the picture path, node Weibotest.js can be successfully sent.
If the Chinese appears garbled, please save these two JS files into Utf-8 code.
Weibo.js
var querystring = require (' querystring '), Crypto = require (' crypto '), HTTPS = require (' https '), URL = require (' URL '), path
= Require (' path '), FS = require (' FS ');
var apiprefix = ' https://api.weibo.com/2/', Appkey = ' 2849184197 ', Appsecret = ' 7338acf99a00412983f255767c7643d0 ';
var userId = "Weibo account number", passwd = "Micro-blog password";
var baseurl = "https://api.weibo.com/2/";
var Weibo = Module.exports = function () {This._accesstoken = "";
This._accesstokenname = "Access_token";
};
Weibo.prototype = {//oauth2/authorize Getauthorize:function (callback) {var params = {}; params[' client_id '] = Appkey; Appkey params[' redirect_uri '] = "";
Oauth2 callback Address params[' response_type ' = "code";
params[' action ' = "submit"; params[' userId '] = userId; Weibo account params[' passwd ' = passwd;
account password var post_data = querystring.stringify (params);
var post_headers = {' Content-type ': ' application/x-www-form-urlencoded ' };
var url = apiprefix + "Oauth2/authorize";
HTTPS request var m = "POST";
var code = "";
var tt = this;
This._request (M, url, post_headers, post_data, NULL, function (error, body, response) {if (error) {
Console.log ("Error:" + error);
else {code = RESPONSE.HEADERS.LOCATION.SUBSTR (6);
Console.log ("code:" + code); Tt.getaccesstoken (Code, function (Err, Access_token, Refresh_token) {Console.log (acces
S_token);
Tt._accesstoken = Access_token;
Callback (Err, Access_token, Refresh_token);
});
}
});
},//oauth2/access_token getaccesstoken:function (code, callback) {var params = {}; params[' grant_type ' = "Authorization_code"; Appkey params[' redirect_uri '] = "";
Oauth2 Callback Address params[' client_id '] = Appkey;
params[' client_secret '] = Appsecret;
params[' Code ' = code;
var post_data = querystring.stringify (params); var post_headers = {' Content-type ': ' application/x-www-form-urlencoded ', ' contentType ': ' text/html
; Charset=uft-8 "};
var url = apiprefix + "Oauth2/access_token";
HTTPS request var m = "POST"; This._request (M, url, post_headers, post_data, NULL, function (error, data, response) {if (error) call
Back (error);
else {var results; try {//As of http://tools.ietf.org/html/draft-ietf-oauth-v2-07//Responses Shou
LD is in JSON results = json.parse (data); catch (E) {//..... However both Facebook + Github currently use rev05 of the spec//And neither seem to specify a Content-type correctly in their response headers:(//clients of this services would suffer a *minor * Performance cost of the exception//being thrown results = Querystring.parse (da
TA);
var Access_token = results["Access_token"];
var Refresh_token = results["Refresh_token"];
Delete results["Refresh_token"];
Callback (NULL, Access_token, Refresh_token);
}
}); },//Universal HTTPS request, Oauth2 _request:function from Node-oauth (method, URL, headers, post_body, Access_token, call
back) {var creds = crypto.createcredentials ({});
var parsedurl = Url.parse (URL, true);
if (Parsedurl.protocol = = "https:" &&!parsedurl.port) parsedurl.port = 443;
var realheaders = {};
if (headers) {for (var key in headers) {Realheaders[key] = Headers[key]; } realheaders[' Host ' = parsedurl.host;
if (Buffer.isbuffer (post_body)) {realheaders[' content-length '] = post_body? post_body.length:0; else {realheaders[' content-length '] = post_body?
Buffer.bytelength (Post_body): 0;
} if (Access_token) {if (!parsedurl.query) parsedurl.query = {};
Parsedurl.query[this._accesstokenname] = Access_token;
var result = "";
var querystr = querystring.stringify (parsedurl.query);
if (querystr) querystr = "?" + querystr; var options = {host:parsedUrl.hostname, port:parsedUrl.port, Path:parsedUrl.pathna
Me + querystr, Method:method, headers:realheaders}; Some hosts *cough* Google appear to close the connection early/send no Content-length headers//Allow this is
Haviour.
var allowearlyclose = false; var callbackcalled = false;
function Passbackcontrol (response, result) {if (!callbackcalled) {callbackcalled = true; if (Response.statuscode!= && (Response.statuscode!=) && (Response.statuscode!= 30 2) {callback ({StatusCode:response.statusCode, data
: result});
else {callback (NULL, result, response);
}} console.log ("Options:");
Console.log (options); var request = https.request (options, function (response) {Response.on ("data"), function (Chu
NK) {result = chunk}); Response.on ("Close", function (Err) {if (allowearlyclose) {Passbackcontro
L (response, result);
}
}); Response.addlistener (' End ', function () {Passbackcontrol (response, result);
});
});
Request.on (' Error ', function (e) {callbackcalled = true;
Callback (e);
});
if (method = = ' POST ' && post_body) {request.write (post_body);
} request.end (); },//Normal post, execute similar statuses/update.json post:function (URL, params, callback) {if (!this._accesstoken) retur
N Callback ("not authorize");
var post_data = querystring.stringify (params);
var post_headers = {' Content-type ': ' application/x-www-form-urlencoded '}; if (params. ContentType) {post_headers[' content-type '] = params.
ContentType;
} this._request ("POST", BaseURL + URL + '. json ', Post_headers, Post_data, This._accesstoken, callback); /********** statuses *********///statuses/repost forwards a microblog message//staTuses/destroy Delete microblogging information//statuses/update release a micro-blog information//statuses/upload upload a picture and publish a micro-blog//statuses/upload_url_text released a Micro Bo also specify upload pictures or pictures URL//emotions get the official expression repost:function (args, callback) {/* args parameters: * ID: Weibo ID * St ATUs: Forwarding Text * Is_comment 0-No comment 1-send comments to the current microblog 2-send comments to the original micro-Bo 3-All hair/if (!args.id) return callback (' Missing Argume
NT ID ');
This.post (' Statuses/repost ', args, callback);
}, Update:function (params, callback) {if (!params.status) return callback (' missing argument status ');
This.post (' statuses/update ', params, callback);
}, File_content_types: {'. gif ': ' Image/gif ', '. jpeg ': ' image/jpeg ', '. jpg ': ' Image/jpeg ', '. png ': ' Image/png '},//Get file information for statuses/upload upload picture and post a microblog fileinfo:function (file) {var name
, Content_Type;
if (typeof (file) = = ' string ') {var ext = path.extname (file); Content_Type = this. File_content_tyPes[ext];
Name = Path.basename (file);
else {name = File.name | | file.filename; Content_Type = File.filetype | |
File.type;
return {name:name, content_type:content_type}; /** * Upload picture * Pic:filepath * callback:finish callback function **/Upload:function (para
MS, callback) {if (!params.status) return callback (' missing argument status ');
var pic = params.pic;
var Pic_field = ' pic ';
var boundary = ' Boundary ' + (new Date). GetTime ();
var dashdash = '--';
var CRLF = ' \ r \ n '; /* Build RFC2388 string.
* * var builder = ';
Builder + = Dashdash;
Builder + = boundary;
Builder + = CRLF; Micro-Blog Text builder = ' Content-disposition:form-data;
Name= "status";
Builder + = CRLF;
Builder + = CRLF; /* Append form data. * * Builder + + Params.status;
Builder + = CRLF; /* Write boundary.
* * Builder + = Dashdash;
Builder + = boundary;
Builder + = CRLF;
var FileInfo = This.fileinfo (pic); /* Generate headers. [PIC] * * builder + = ' content-disposition:form-data;
Name= "' + Pic_field + '"; Builder + = ';
Filename= "' + Fileinfo.name + '";
Builder + = CRLF;
Builder + = ' Content-type: ' + Fileinfo.content_type + ';
Builder + = CRLF;
Builder + = CRLF;
var tt = this; Process file content//Weibo picture This.read_file (pic, function (file_buffer) {var endstr = Crlf + dashd
Ash + boundary + Dashdash + CRLF, buffer = null;
if (typeof (blobbuilder) = = ' undefined ') {var builderlength = new Buffer (builder). length;
var size = builderlength + file_buffer.length + endstr.length;
Buffer = new buffer (size);
var offset = 0; Buffer.write (builder);
Offset + + builderlength;
File_buffer.copy (buffer, offset);
Offset + + file_buffer.length;
Buffer.write (endstr, offset);
else {buffer = new Blobbuilder ();//note webkitblogbuilder buffer.append (builder);
Buffer.append (pic);
Buffer.append (ENDSTR);
Buffer = Buffer.getblob ();
} if (!tt._accesstoken) return callback (' not authorize ');
var post_data = buffer; Must use multipart/form-data var post_headers = {' Content-type ': ' multipart/form-data;boundary= '
+ Boundary};
Console.log (builder);
Tt._request ("POST", BaseURL + ' statuses/upload ' + '. Json ', Post_headers, Post_data, Tt._accesstoken, callback);
}); }, Read_file:function (pic, callback) {if (typeof (pic) = = ' String ') {
Fs.stat (pic, function (err, stats) {fs.readfile (pic, function (err
, File_buffer) {console.log (err);
if (!err) callback (File_buffer);
});
});
else {callback (pic); }
},
};
Weibotest.js
var Weibo = require ('./weibo ');
var wb = new Weibo ();
Wb.getauthorize (function (err, Access_token, Refresh_token) {
//wb.update {
// Status: "Not in Chinese." "
//},
//function (Error, body, response) {
// if (error) {
// Console.log (" error: "); Console.log (error); / else {
// Console.log ("body:" + body);
// }
//});
Wb.upload ({
"status": "Chinese not.") ",
" pic ":" E:/xx.jpg "
},
function (error, body, response) {
if (error) {
Console.log (" Error: ");
Console.log (Error);
}
else {
Console.log ("body:" + body);
}
});