99var TWITTER_API_TIMEOUT = 5 ,
1010 TWITTER_API_USERAGENT = 'Node/' + process . version . substr ( 1 ) ,
1111 TWITTER_API_BASE = 'https://api.twitter.com/1.1' ;
12+ TWITTER_STREAM_BASE = 'https://stream.twitter.com/1.1' ;
1213 TWITTER_OAUTH_REQUEST_TOKEN_URL = 'https://twitter.com/oauth/request_token' ;
1314 TWITTER_OAUTH_AUTHORIZE_URL = 'https://twitter.com/oauth/authorize' ;
1415 TWITTER_OAUTH_AUTHENTICATE_URL = 'https://twitter.com/oauth/authenticate' ;
@@ -141,42 +142,16 @@ TwitterClient.prototype.deAuth = function(){
141142}
142143
143144TwitterClient . prototype . get = function ( requestPath , requestArgs , callback ) {
144- return this . call ( 'GET' , requestPath , requestArgs , callback ) ;
145+ return this . _rest ( 'GET' , requestPath , requestArgs , callback ) ;
145146}
146147
147148TwitterClient . prototype . post = function ( requestPath , requestArgs , callback ) {
148- return this . call ( 'POST' , requestPath , requestArgs , callback ) ;
149+ return this . _rest ( 'POST' , requestPath , requestArgs , callback ) ;
149150}
150151
151- TwitterClient . prototype . call = function ( requestMethod , requestPath , requestArgs , callback ) {
152- if ( ! this . hasAuth ( ) ) {
153- throw new Error ( 'Twitter client not authenticated' ) ;
154- }
155- requestMethod = String ( requestMethod || 'GET' ) . toUpperCase ( ) ;
152+ TwitterClient . prototype . _rest = function ( requestMethod , requestPath , requestArgs , callback ) {
156153 var requestUri = TWITTER_API_BASE + '/' + requestPath + '.json' ;
157- // build and sign request parameters
158- var params = new OAuthParams ( requestArgs )
159- . setConsumer ( this . consumerToken )
160- . setAccess ( this . accessToken )
161- . sign ( requestMethod , requestUri ) ;
162- // grab authorization header and any remaining params
163- var oauth = params . getHeader ( ) ,
164- query = params . serialize ( ) ;
165- // build http request starting with parsed endpoint
166- var http = require ( 'url' ) . parse ( requestUri ) ;
167- http . headers = {
168- Authorization : oauth ,
169- 'User-Agent' : TWITTER_API_USERAGENT
170- } ;
171- if ( 'POST' === requestMethod ) {
172- http . method = 'POST' ;
173- http . headers [ 'Content-Type' ] = 'application/x-www-form-urlencoded; charset=UTF-8' ;
174- http . headers [ 'Content-Length' ] = query . length ;
175- }
176- else if ( query ) {
177- http . path += '?' + query ;
178- }
179- var req = require ( 'https' ) . get ( http , function ( res ) {
154+ return this . call ( requestMethod , requestUri , requestArgs , function ( res ) {
180155 // started to receive response from twitter
181156 res . setEncoding ( 'utf8' ) ;
182157 var body = '' ;
@@ -205,6 +180,73 @@ TwitterClient.prototype.call = function( requestMethod, requestPath, requestArgs
205180 }
206181 } ) ;
207182 } ) ;
183+ }
184+
185+ TwitterClient . prototype . stream = function ( requestPath , requestArgs , callback ) {
186+ var requestMethod = 'GET' ,
187+ requestUri = TWITTER_STREAM_BASE + '/' + requestPath + '.json' ;
188+ if ( 'user' === requestPath ) {
189+ requestUri = requestUri . replace ( 'stream' , 'userstream' ) ;
190+ }
191+ else if ( 'site' === requestPath ) {
192+ requestUri = requestUri . replace ( 'stream' , 'sitestream' ) ;
193+ }
194+ else if ( 0 === requestPath . indexOf ( 'statuses/filter' ) ) {
195+ requestMethod = 'POST' ;
196+ }
197+ if ( 'function' !== typeof callback ) {
198+ callback = function ( json ) {
199+ console . log ( json ) ;
200+ } ;
201+ }
202+ var client = this ;
203+ return this . call ( requestMethod , requestUri , requestArgs , function ( res ) {
204+ client . response = res ;
205+ res . setEncoding ( 'utf8' ) ;
206+ if ( 200 !== res . statusCode ) {
207+ console . error ( 'Error ' + res . statusCode ) ;
208+ client . abort ( ) ;
209+ }
210+ res . on ( 'data' , function ( chunk ) {
211+ // simple sniff for valid json and call back
212+ if ( '{' == chunk . charAt ( 0 ) && '}\r\n' === chunk . substr ( - 3 ) ) {
213+ callback ( chunk ) ;
214+ }
215+ } ) ;
216+ res . on ( 'end' , function ( ) {
217+ client . response = null ;
218+ } ) ;
219+ } ) ;
220+ }
221+
222+ TwitterClient . prototype . call = function ( requestMethod , requestUri , requestArgs , callback ) {
223+ if ( ! this . hasAuth ( ) ) {
224+ throw new Error ( 'Twitter client not authenticated' ) ;
225+ }
226+ requestMethod = String ( requestMethod || 'GET' ) . toUpperCase ( ) ;
227+ // build and sign request parameters
228+ var params = new OAuthParams ( requestArgs )
229+ . setConsumer ( this . consumerToken )
230+ . setAccess ( this . accessToken )
231+ . sign ( requestMethod , requestUri ) ;
232+ // grab authorization header and any remaining params
233+ var oauth = params . getHeader ( ) ,
234+ query = params . serialize ( ) ;
235+ // build http request starting with parsed endpoint
236+ var http = require ( 'url' ) . parse ( requestUri ) ;
237+ http . headers = {
238+ Authorization : oauth ,
239+ 'User-Agent' : TWITTER_API_USERAGENT
240+ } ;
241+ if ( 'POST' === requestMethod ) {
242+ http . method = 'POST' ;
243+ http . headers [ 'Content-Type' ] = 'application/x-www-form-urlencoded; charset=UTF-8' ;
244+ http . headers [ 'Content-Length' ] = query . length ;
245+ }
246+ else if ( query ) {
247+ http . path += '?' + query ;
248+ }
249+ var req = require ( 'https' ) . get ( http , callback ) ;
208250 if ( 'POST' === requestMethod && query ) {
209251 req . write ( query ) ;
210252 req . write ( '\n' ) ;
@@ -213,6 +255,19 @@ TwitterClient.prototype.call = function( requestMethod, requestPath, requestArgs
213255 return this ;
214256}
215257
258+ TwitterClient . prototype . abort = function ( ) {
259+ try {
260+ if ( this . response ) {
261+ this . response . destroy ( ) ;
262+ this . response = null ;
263+ }
264+ }
265+ catch ( e ) {
266+ console . error ( e . message || String ( e ) || 'Unknown error on abort' ) ;
267+ }
268+ }
269+
270+
216271
217272
218273
0 commit comments