forked from ttezel/twit
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhelpers.js
128 lines (118 loc) · 3.79 KB
/
helpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
var querystring = require('querystring');
var request = require('request');
var endpoints = require('./endpoints');
/**
* Encodes object as a querystring, to be used as the suffix of request URLs.
* @param {Object} obj
* @return {String}
*/
exports.makeQueryString = function (obj) {
var qs = querystring.stringify(obj)
qs = qs.replace(/\!/g, "%21")
.replace(/\'/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29")
.replace(/\*/g, "%2A");
return qs
}
/**
* For each `/:param` fragment in path, move the value in params
* at that key to path. If the key is not found in params, throw.
* Modifies both params and path values.
*
* @param {Objet} params Object used to build path.
* @param {String} path String to transform.
* @return {Undefined}
*
*/
exports.moveParamsIntoPath = function (params, path) {
var rgxParam = /\/:(\w+)/g
var missingParamErr = null
path = path.replace(rgxParam, function (hit) {
var paramName = hit.slice(2)
var suppliedVal = params[paramName]
if (!suppliedVal) {
throw new Error('Twit: Params object is missing a required parameter for this request: `'+paramName+'`')
}
var retVal = '/' + suppliedVal
delete params[paramName]
return retVal
})
return path
}
/**
* When Twitter returns a response that looks like an error response,
* use this function to attach the error info in the response body to `err`.
*
* @param {Error} err Error instance to which body info will be attached
* @param {Object} body JSON object that is the deserialized HTTP response body received from Twitter
* @return {Undefined}
*/
exports.attachBodyInfoToError = function (err, body) {
err.twitterReply = body;
if (!body) {
return
}
if (body.error) {
// the body itself is an error object
err.message = body.error
err.allErrors = err.allErrors.concat([body])
} else if (body.errors && body.errors.length) {
// body contains multiple error objects
err.message = body.errors[0].message;
err.code = body.errors[0].code;
err.allErrors = err.allErrors.concat(body.errors)
}
}
exports.makeTwitError = function (message) {
var err = new Error()
if (message) {
err.message = message
}
err.code = null
err.allErrors = []
err.twitterReply = null
return err
}
/**
* Get a bearer token for OAuth2
* @param {String} consumer_key
* @param {String} consumer_secret
* @param {Function} cb
*
* Calls `cb` with Error, String
*
* Error (if it exists) is guaranteed to be Twit error-formatted.
* String (if it exists) is the bearer token received from Twitter.
*/
exports.getBearerToken = function (consumer_key, consumer_secret, cb) {
// use OAuth 2 for app-only auth (Twitter requires this)
// get a bearer token using our app's credentials
var b64Credentials = new Buffer(consumer_key + ':' + consumer_secret).toString('base64');
request.post({
url: endpoints.API_HOST + '/oauth2/token',
headers: {
'Authorization': 'Basic ' + b64Credentials,
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: 'grant_type=client_credentials',
json: true,
}, function (err, res, body) {
if (err) {
var error = exports.makeTwitError(err.toString());
exports.attachBodyInfoToError(error, body);
return cb(error, body, res);
}
if ( !body ) {
var error = exports.makeTwitError('Not valid reply from Twitter upon obtaining bearer token');
exports.attachBodyInfoToError(error, body);
return cb(error, body, res);
}
if (body.token_type !== 'bearer') {
var error = exports.makeTwitError('Unexpected reply from Twitter upon obtaining bearer token');
exports.attachBodyInfoToError(error, body);
return cb(error, body, res);
}
return cb(err, body.access_token);
})
}