weibo-api
Version:
基于 NODE 的 Weibo SDK,封装了一些基本方法
330 lines (292 loc) • 10.4 kB
JavaScript
var validator = require('validator');
var urllib = require('urllib');
var querystring = require('querystring');
var WeiboApi = function () {
this.api_hostname = 'api.weibo.com';
// this.api_port = 433;
this.api_root = 'https://' + this.api_hostname + '/2/';
this.app_key = '';
this.app_secret = '';
this.redirect_uri = '';
this.token = null;
this.access_token = '';
};
module.exports = new WeiboApi();
var pt = WeiboApi.prototype;
pt.init = function (opt) {
this.app_key = opt.app_key;
this.app_secret = opt.app_secret;
this.redirect_uri = opt.app_redirect_uri;
};
pt.request = function (apiName, options, callback) {
var self = this;
var url = self.api_root + apiName + '.json';
options.data.access_token = self.access_token;
console.log('request', apiName, url, options);
urllib.request(url, options, function (err, data, res) {
if (typeof callback == 'function') {
if (err) {
callback(err, null);
} else {
// console.log(res.statusCode);
// console.log(res.headers);
// data is Buffer instance
// console.log(data.toString());
callback(err, JSON.parse(data));
}
}
});
};
pt.requestGet = function (apiName, params, callback) {
var options = {
method: 'GET',
data: params
};
this.request(apiName, options, callback);
};
pt.requestPost = function (apiName, options, callback) {
var options = {
method: 'POST',
data: params
};
this.request(apiName, options, callback);
};
pt._getOauthrizationURL = function () {
var params = {
client_id: this.app_key,
redirect_uri: this.redirect_uri,
response_type: 'code'
};
var query = querystring.stringify(params);
return 'https://' + this.api_hostname + '/oauth2/authorize?' + query;
};
pt.authorize = function (res) {
var url = this._getOauthrizationURL();
// console.log('weibo.authorize', url);
if (res.redirect) {
res.redirect(url);
} else {
res.writeHead(302, {
'Location': url
//add other headers here...
});
res.end();
}
};
pt.accessToken = function (code, callback) {
var self = this;
var url = 'https://' + self.api_hostname + '/oauth2/access_token';
var params = {
method: 'POST',
data: {
client_id: self.app_key,
client_secret: self.app_secret,
redirect_uri: self.redirect_uri,
grant_type: 'authorization_code',
code: code
}
};
urllib.request(url, params, function (err, data, res) {
// self.token = data;
// self.access_token = data.access_token;
// console.log(res.statusCode);
// console.log(res.headers);
// data is Buffer instance
// console.log(data.toString());
if (typeof callback == 'function') {
if (err) {
console.error(err);
} else {
callback(err, JSON.parse(data));
}
}
});
};
// status true string 要发布的微博文本内容,必须做URLencode,内容不超过140个汉字。
// visible false int 微博的可见性,0:所有人能看,1:仅自己可见,2:密友可见,3:指定分组可见,默认为0。
// list_id false string 微博的保护投递指定分组ID,只有当visible参数为3时生效且必选。
// lat false float 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
// long false float 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。
// annotations false string 元数据,主要是为了方便第三方应用记录一些适合于自己使用的信息,每条微博可以包含一个或者多个元数据,必须以json字串的形式提交,字串长度不超过512个字符,具体内容可以自定。
// rip false string 开发者上报的操作用户真实IP,形如:211.156.0.1。
pt.statusesUpdate = function (params, callback) {
var err = [];
params.status = validator.trim(params.status);
if (params.status.length === 0) {
err.push('请输入内容');
}
if (params.status.length > 140) {
err.push('内容不要超过140个字符');
}
if (err.length) {
callback(err, null);
return;
}
this.requestPost('statuses/update', params, callback);
};
// status true string 要发布的微博文本内容,必须做URLencode,内容不超过140个汉字。
// visible false int 微博的可见性,0:所有人能看,1:仅自己可见,2:密友可见,3:指定分组可见,默认为0。
// list_id false string 微博的保护投递指定分组ID,只有当visible参数为3时生效且必选。
// pic true binary 要上传的图片,仅支持JPEG、GIF、PNG格式,图片大小小于5M。
// lat false float 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
// long false float 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。
// annotations false string 元数据,主要是为了方便第三方应用记录一些适合于自己使用的信息,每条微博可以包含一个或者多个元数据,必须以json字串的形式提交,字串长度不超过512个字符,具体内容可以自定。
// rip false string 开发者上报的操作用户真实IP,形如:211.156.0.1。
pt.statusesUpload = function (params, pic, callback) {
var err = [];
params.status = validator.trim(params.status);
if (params.status.length === 0) {
err.push('请输入内容');
}
if (params.status.length > 140) {
err.push('内容不要超过140个字符');
}
if (err.length) {
callback(err, null);
return;
}
var self = this;
var url = self.api_root + 'statuses/upload' + '.json';
var boundary = 'boundary' + Date.now();
var dash = '--';
var crlf = '\r\n';
params.access_token = self.access_token;
/* RFC2388 */
var builder = [];
/* Generate headers. key */
for (var key in params) {
var item = dash + boundary + crlf;
item += 'Content-Disposition: form-data; name="' + key + '"' + crlf + crlf;
item += params[key];
builder.push(item);
}
/* Generate headers. [PIC] */
var item = dash + boundary + crlf;
item += 'Content-Disposition: form-data; name="' + pic.field + '"; ';
item += 'filename="' + pic.name + '"' + crlf;
item += 'Content-Type: ' + pic.type + ';' + crlf + crlf;
builder.push(item);
builder = builder.join(crlf);
/* Generate headers. end */
var builderEnd = crlf + dash + boundary + dash + crlf;
// console.log('statusesUpload.builder');
// console.log(Buffer.byteLength(builder), builder.length);
// console.log(builder + builderEnd);
var builderLength = Buffer.byteLength(builder);
// var size = builderLength + pic.data.length + endstr.length;
var size = builderLength + pic.data.length + builderEnd.length;
var buffer = new Buffer(size);
var offset = 0;
buffer.write(builder);
offset += builderLength;
pic.data.copy(buffer, offset);
offset += pic.data.length;
buffer.write(builderEnd, offset);
urllib.request(url, {
headers: {
'Content-type': 'multipart/form-data; boundary=' + boundary
},
method: 'POST',
content: buffer
}, function (err, data, res) {
if (typeof callback == 'function') {
if (err) {
callback(err, null);
} else {
// console.log(res.statusCode);
// console.log(res.headers);
// data is Buffer instance
// console.log(data.toString());
callback(err, JSON.parse(data));
}
}
});
};
// id true int64 要转发的微博ID。
// status false string 添加的转发文本,必须做URLencode,内容不超过140个汉字,不填则默认为“转发微博”。
// is_comment false int 是否在转发的同时发表评论,0:否、1:评论给当前微博、2:评论给原微博、3:都评论,默认为0 。
// rip false string 开发者上报的操作用户真实IP,形如:211.156.0.1。
pt.statusesRepost = function (params, callback) {
var err = [];
if (!validator.isInt(params.id)) {
err.push('微博ID丢失');
}
params.status = validator.trim(params.status);
if (params.status.length > 140) {
err.push('内容不要超过140个字符');
}
if (err.length) {
callback(err, null);
return;
}
this.requestPost('statuses/repost', params, callback);
};
// id true int64 需要查询的微博ID。
// since_id false int64 若指定此参数,则返回ID比since_id大的评论(即比since_id时间晚的评论),默认为0。
// max_id false int64 若指定此参数,则返回ID小于或等于max_id的评论,默认为0。
// count false int 单页返回的记录条数,默认为50。
// page false int 返回结果的页码,默认为1。
// filter_by_author false int 作者筛选类型,0:全部、1:我关注的人、2:陌生人,默认为0。
pt.commentsShow = function (params, callback) {
var err = [];
if (!validator.isInt(params.id)) {
err.push('微博ID丢失');
}
if (err.length) {
callback(err, null);
return;
}
this.requestGet('comments/show', params, callback);
};
pt.commentsCreate = function (params, callback) {
var err = [];
if (!validator.isInt(params.id)) {
err.push('微博ID丢失');
}
params.comment = validator.trim(params.comment);
if (params.comment.length === 0) {
err.push('请输入内容');
}
if (params.comment.length > 140) {
err.push('内容不要超过140个字符');
}
if (err.length) {
callback(err, null);
return;
}
this.requestPost('comments/create', params, callback);
};
pt.usersShow = function (params, callback) {
if (params.uid) {
delete params.screen_name;
}
this.requestGet('users/show', params, callback);
};
pt.friendshipsFollowers = function (params, callback) {
if (params.uid) {
delete params.screen_name;
}
this.requestGet('friendships/followers', params, callback);
};
pt.getWebImage = function (url, callback) {
urllib.request(url, {
method: 'GET'
}, function (err, data, res) {
// console.log(res.statusCode);
// console.log(res.headers);
// data is Buffer instance
// console.log(data.toString());
if (typeof callback == 'function') {
if (err) {
callback(err, null);
} else {
var pic = {
length: res.headers['content-length'],
type: res.headers['content-type'],
data: data
};
callback(err, pic);
}
}
});
};