1 | #twit
|
2 |
|
3 | Twitter API Client for node
|
4 |
|
5 | Supports both the **REST** and **Streaming** API.
|
6 |
|
7 | #Installing
|
8 |
|
9 | ```
|
10 | npm install twit
|
11 | ```
|
12 |
|
13 | ##Usage:
|
14 |
|
15 | ```javascript
|
16 | var Twit = require('twit')
|
17 |
|
18 | var T = new Twit({
|
19 | consumer_key: '...'
|
20 | , consumer_secret: '...'
|
21 | , access_token: '...'
|
22 | , access_token_secret: '...'
|
23 | })
|
24 |
|
25 | //
|
26 | // tweet 'hello world!'
|
27 | //
|
28 | T.post('statuses/update', { status: 'hello world!' }, function(err, data, response) {
|
29 | console.log(data)
|
30 | })
|
31 |
|
32 | //
|
33 | // search twitter for all tweets containing the word 'banana' since Nov. 11, 2011
|
34 | //
|
35 | T.get('search/tweets', { q: 'banana since:2011-11-11', count: 100 }, function(err, data, response) {
|
36 | console.log(data)
|
37 | })
|
38 |
|
39 | //
|
40 | // get the list of user id's that follow @tolga_tezel
|
41 | //
|
42 | T.get('followers/ids', { screen_name: 'tolga_tezel' }, function (err, data, response) {
|
43 | console.log(data)
|
44 | })
|
45 |
|
46 | //
|
47 | // retweet a tweet with id '343360866131001345'
|
48 | //
|
49 | T.post('statuses/retweet/:id', { id: '343360866131001345' }, function (err, data, response) {
|
50 | console.log(data)
|
51 | })
|
52 |
|
53 | //
|
54 | // destroy a tweet with id '343360866131001345'
|
55 | //
|
56 | T.post('statuses/destroy/:id', { id: '343360866131001345' }, function (err, data, response) {
|
57 | console.log(data)
|
58 | })
|
59 |
|
60 | //
|
61 | // get `funny` twitter users
|
62 | //
|
63 | T.get('users/suggestions/:slug', { slug: 'funny' }, function (err, data, response) {
|
64 | console.log(data)
|
65 | })
|
66 |
|
67 | //
|
68 | // stream a sample of public statuses
|
69 | //
|
70 | var stream = T.stream('statuses/sample')
|
71 |
|
72 | stream.on('tweet', function (tweet) {
|
73 | console.log(tweet)
|
74 | })
|
75 |
|
76 | //
|
77 | // filter the twitter public stream by the word 'mango'.
|
78 | //
|
79 | var stream = T.stream('statuses/filter', { track: 'mango' })
|
80 |
|
81 | stream.on('tweet', function (tweet) {
|
82 | console.log(tweet)
|
83 | })
|
84 |
|
85 | //
|
86 | // filter the public stream by the latitude/longitude bounded box of San Francisco
|
87 | //
|
88 | var sanFrancisco = [ '-122.75', '36.8', '-121.75', '37.8' ]
|
89 |
|
90 | var stream = T.stream('statuses/filter', { locations: sanFrancisco })
|
91 |
|
92 | stream.on('tweet', function (tweet) {
|
93 | console.log(tweet)
|
94 | })
|
95 |
|
96 | //
|
97 | // filter the public stream by english tweets containing `#apple`
|
98 | //
|
99 | var stream = T.stream('statuses/filter', { track: '#apple', language: 'en' })
|
100 |
|
101 | stream.on('tweet', function (tweet) {
|
102 | console.log(tweet)
|
103 | })
|
104 |
|
105 | ```
|
106 |
|
107 | # twit API:
|
108 |
|
109 | ##`T.get(path, [params], callback)`
|
110 | GET any of the REST API endpoints.
|
111 |
|
112 | **path**
|
113 |
|
114 | The endpoint to hit. When specifying `path` values, omit the **'.json'** at the end (i.e. use **'search/tweets'** instead of **'search/tweets.json'**).
|
115 |
|
116 | **params**
|
117 |
|
118 | (Optional) parameters for the request.
|
119 |
|
120 | **callback**
|
121 |
|
122 | `function (err, data, response)`
|
123 |
|
124 | - `data` is the parsed data received from Twitter.
|
125 | - `response` is the [http.IncomingMessage](http://nodejs.org/api/http.html#http_http_incomingmessage) received from Twitter.
|
126 |
|
127 | ##`T.post(path, [params], callback)`
|
128 |
|
129 | POST any of the REST API endpoints. Same usage as `T.get()`.
|
130 |
|
131 | ##`T.getAuth()`
|
132 | Get the client's authentication tokens.
|
133 |
|
134 | ##`T.setAuth(tokens)`
|
135 | Update the client's authentication tokens.
|
136 |
|
137 | ##`T.stream(path, [params])`
|
138 | Use this with the Streaming API.
|
139 |
|
140 | **path**
|
141 |
|
142 | Streaming endpoint to hit. One of:
|
143 |
|
144 | - **'statuses/filter'**
|
145 | - **'statuses/sample'**
|
146 | - **'statuses/firehose'**
|
147 | - **'user'**
|
148 | - **'site'**
|
149 |
|
150 | For a description of each Streaming endpoint, see the [Twitter API docs](https://dev.twitter.com/docs/api/1.1#334).
|
151 |
|
152 | **params**
|
153 |
|
154 | (Optional) parameters for the request. Any Arrays passed in `params` get converted to comma-separated strings, allowing you to do requests like:
|
155 |
|
156 | ```javascript
|
157 | //
|
158 | // I only want to see tweets about my favorite fruits
|
159 | //
|
160 |
|
161 | // same result as doing { track: 'bananas,oranges,strawberries' }
|
162 | var stream = T.stream('statuses/filter', { track: ['bananas', 'oranges', 'strawberries'] })
|
163 |
|
164 | stream.on('tweet', function (tweet) {
|
165 | //...
|
166 | })
|
167 | ```
|
168 |
|
169 | # Using the Streaming API
|
170 |
|
171 | `T.stream(path, [params])` keeps the connection alive, and returns an `EventEmitter`.
|
172 |
|
173 | The following events are emitted:
|
174 |
|
175 | ##event: 'tweet'
|
176 |
|
177 | Emitted each time a status (tweet) comes into the stream.
|
178 |
|
179 | ```javascript
|
180 | stream.on('tweet', function (tweet) {
|
181 | //...
|
182 | })
|
183 | ```
|
184 |
|
185 | ##event: 'delete'
|
186 |
|
187 | Emitted each time a status (tweet) deletion message comes into the stream.
|
188 |
|
189 | ```javascript
|
190 | stream.on('delete', function (deleteMessage) {
|
191 | //...
|
192 | })
|
193 | ```
|
194 |
|
195 | ##event: 'limit'
|
196 |
|
197 | Emitted each time a limitation message comes into the stream.
|
198 |
|
199 | ```javascript
|
200 | stream.on('limit', function (limitMessage) {
|
201 | //...
|
202 | })
|
203 | ```
|
204 |
|
205 | ##event: 'scrub_geo'
|
206 |
|
207 | Emitted each time a location deletion message comes into the stream.
|
208 |
|
209 | ```javascript
|
210 | stream.on('scrub_geo', function (scrubGeoMessage) {
|
211 | //...
|
212 | })
|
213 | ```
|
214 |
|
215 | ##event: 'disconnect'
|
216 |
|
217 | Emitted when a disconnect message comes from Twitter. This occurs if you have multiple streams connected to Twitter's API. Upon receiving a disconnect message from Twitter, `Twit` will close the connection and emit this event with the message details received from twitter.
|
218 |
|
219 | ```javascript
|
220 | stream.on('disconnect', function (disconnectMessage) {
|
221 | //...
|
222 | })
|
223 | ```
|
224 |
|
225 | ##event: 'connect'
|
226 |
|
227 | Emitted when a connection attempt is made to Twitter. The http `request` object is emitted.
|
228 |
|
229 | ```javascript
|
230 | stream.on('connect', function (request) {
|
231 | //...
|
232 | })
|
233 | ```
|
234 |
|
235 | ##event: 'connected'
|
236 |
|
237 | Emitted when the response is received from Twitter. The http `response` object is emitted.
|
238 |
|
239 | ```javascript
|
240 | stream.on('connected', function (response) {
|
241 | //...
|
242 | })
|
243 | ```
|
244 |
|
245 | ##event: 'reconnect'
|
246 |
|
247 | Emitted when a reconnection attempt to Twitter is scheduled. If Twitter is having problems or we get rate limited, we schedule a reconnect according to Twitter's [reconnection guidelines](https://dev.twitter.com/docs/streaming-apis/connecting). The last http `request` and `response` objects are emitted, along with the time (in milliseconds) left before the reconnect occurs.
|
248 |
|
249 | ```javascript
|
250 | stream.on('reconnect', function (request, response, connectInterval) {
|
251 | //...
|
252 | })
|
253 | ```
|
254 |
|
255 | ##event: 'warning'
|
256 |
|
257 | This message is appropriate for clients using high-bandwidth connections, like the firehose. If your connection is falling behind, Twitter will queue messages for you, until your queue fills up, at which point they will disconnect you.
|
258 |
|
259 | ```javascript
|
260 | stream.on('warning', function (warning) {
|
261 | //...
|
262 | })
|
263 | ```
|
264 |
|
265 | ##event: 'status_withheld'
|
266 |
|
267 | Emitted when Twitter sends back a `status_withheld` message in the stream. This means that a tweet was withheld in certain countries.
|
268 |
|
269 | ```javascript
|
270 | stream.on('status_withheld', function (withheldMsg) {
|
271 | //...
|
272 | })
|
273 | ```
|
274 |
|
275 | ##event: 'user_withheld'
|
276 |
|
277 | Emitted when Twitter sends back a `user_withheld` message in the stream. This means that a Twitter user was withheld in certain countries.
|
278 |
|
279 | ```javascript
|
280 | stream.on('user_withheld', function (withheldMsg) {
|
281 | //...
|
282 | })
|
283 | ```
|
284 |
|
285 | ##event: 'friends'
|
286 |
|
287 | Emitted when Twitter sends the ["friends" preamble](https://dev.twitter.com/docs/streaming-apis/messages#User_stream_messages) when connecting to a user stream. This message contains a list of the user's friends, represented as an array of user ids.
|
288 |
|
289 | ```javascript
|
290 | stream.on('friends', function (friendsMsg) {
|
291 | //...
|
292 | })
|
293 | ```
|
294 |
|
295 | ##event: 'direct_message'
|
296 |
|
297 | Emitted when a direct message is sent to the user. Unfortunately, Twitter has not documented this event for user streams.
|
298 |
|
299 | ```javascript
|
300 | stream.on('direct_message', function (directMsg) {
|
301 | //...
|
302 | })
|
303 | ```
|
304 |
|
305 | ##event: 'user_event'
|
306 |
|
307 | Emitted when Twitter sends back a [User stream event](https://dev.twitter.com/docs/streaming-apis/messages#User_stream_messages).
|
308 | See the Twitter docs for more information on each event's structure.
|
309 |
|
310 | ```javascript
|
311 | stream.on('user_event', function (eventMsg) {
|
312 | //...
|
313 | })
|
314 | ```
|
315 |
|
316 | In addition, the following user stream events are provided for you to listen on:
|
317 |
|
318 | * `blocked`
|
319 | * `unblocked`
|
320 | * `favorite`
|
321 | * `unfavorite`
|
322 | * `follow`
|
323 | * `unfollow`
|
324 | * `user_update`
|
325 | * `list_created`
|
326 | * `list_destroyed`
|
327 | * `list_updated`
|
328 | * `list_member_added`
|
329 | * `list_member_removed`
|
330 | * `list_user_subscribed`
|
331 | * `list_user_unsubscribed`
|
332 | * `unknown_user_event` (for an event that doesn't match any of the above)
|
333 |
|
334 | ###Example:
|
335 |
|
336 | ```javascript
|
337 | stream.on('favorite', function (event) {
|
338 | //...
|
339 | })
|
340 | ```
|
341 |
|
342 | ##event: 'error'
|
343 |
|
344 | Emitted when an API request or response error occurs.
|
345 | An `Error` object is emitted, with properties:
|
346 |
|
347 | ```js
|
348 | {
|
349 | message: '...', // error message
|
350 | statusCode: '...', // statusCode from Twitter
|
351 | code: '...', // error code from Twitter
|
352 | twitterReply: '...', // raw response data from Twitter
|
353 | allErrors: '...' // array of errors returned from Twitter
|
354 | }
|
355 | ```
|
356 |
|
357 | ##stream.stop()
|
358 |
|
359 | Call this function on the stream to stop streaming (closes the connection with Twitter).
|
360 |
|
361 | ##stream.start()
|
362 |
|
363 | Call this function to restart the stream after you called `.stop()` on it.
|
364 | Note: there is no need to call `.start()` to begin streaming. `Twit.stream` calls `.start()` for you.
|
365 |
|
366 | -------
|
367 |
|
368 | #What do I have access to?
|
369 |
|
370 | Anything in the Twitter API:
|
371 |
|
372 | * REST API Endpoints: https://dev.twitter.com/docs/api
|
373 | * Public stream endpoints: https://dev.twitter.com/docs/streaming-api/methods
|
374 | * User stream endpoints: https://dev.twitter.com/docs/streaming-api/user-streams
|
375 | * Site stream endpoints: https://dev.twitter.com/docs/streaming-api/site-streams
|
376 |
|
377 | -------
|
378 |
|
379 | Go here to create an app and get OAuth credentials (if you haven't already): https://dev.twitter.com/apps/new
|
380 |
|
381 |
|
382 | #How do I run the tests?
|
383 |
|
384 | Create two files: `config1.js` and `config2.js` at the root of the `twit` folder. They should contain two different sets of oauth credentials for twit to use (two accounts are needed for testing interactions). They should both look something like this:
|
385 |
|
386 | ```
|
387 | module.exports = {
|
388 | consumer_key: '...'
|
389 | , consumer_secret: '...'
|
390 | , access_token: '...'
|
391 | , access_token_secret: '...'
|
392 | }
|
393 | ```
|
394 |
|
395 | Then run the tests:
|
396 |
|
397 | ```
|
398 | npm test
|
399 | ```
|
400 |
|
401 | You can also run the example:
|
402 |
|
403 | ```
|
404 | node examples/rtd2.js
|
405 | ```
|
406 |
|
407 | ![iRTD2](http://dl.dropbox.com/u/32773572/RTD2_logo.png)
|
408 |
|
409 | The example is a twitter bot named [RTD2](https://twitter.com/#!/iRTD2) written using `twit`. RTD2 tweets about **github** and curates its social graph.
|
410 |
|
411 | -------
|
412 |
|
413 | ## License
|
414 |
|
415 | (The MIT License)
|
416 |
|
417 | Copyright (c) by Tolga Tezel <tolgatezel11@gmail.com>
|
418 |
|
419 | Permission is hereby granted, free of charge, to any person obtaining a copy
|
420 | of this software and associated documentation files (the "Software"), to deal
|
421 | in the Software without restriction, including without limitation the rights
|
422 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
423 | copies of the Software, and to permit persons to whom the Software is
|
424 | furnished to do so, subject to the following conditions:
|
425 |
|
426 | The above copyright notice and this permission notice shall be included in
|
427 | all copies or substantial portions of the Software.
|
428 |
|
429 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
430 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
431 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
432 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
433 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
434 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
435 | THE SOFTWARE.
|
436 |
|
437 | ## Changelog
|
438 |
|
439 | ###1.1.14
|
440 | * Emit `connected` event upon receiving the response from twitter
|
441 |
|
442 | ###1.0.0
|
443 | * now to stop and start the stream, use `stream.stop()` and `stream.start()` instead of emitting the `start` and `stop` events
|
444 | * If twitter sends a `disconnect` message, closes the stream and emits `disconnect` with the disconnect message received from twitter
|
445 |
|
446 | ###0.2.0
|
447 | * Updated `twit` for usage with v1.1 of the Twitter API.
|
448 |
|
449 | ###0.1.5
|
450 |
|
451 | * **BREAKING CHANGE** to `twit.stream()`. Does not take a callback anymore. It returns
|
452 | immediately with the `EventEmitter` that you can listen on. The `Usage` section in
|
453 | the Readme.md has been updated. Read it.
|
454 |
|
455 |
|
456 | ###0.1.4
|
457 |
|
458 | * `twit.stream()` has signature `function (path, params, callback)`
|