├── .gitignore ├── LICENSE ├── README.textile ├── Rakefile ├── lib ├── twitter_oauth.rb └── twitter_oauth │ ├── account.rb │ ├── blocks.rb │ ├── client.rb │ ├── direct_messages.rb │ ├── favorites.rb │ ├── friendships.rb │ ├── geo.rb │ ├── help.rb │ ├── lists.rb │ ├── notifications.rb │ ├── saved_searches.rb │ ├── search.rb │ ├── spam.rb │ ├── status.rb │ ├── timeline.rb │ ├── trends.rb │ ├── user.rb │ └── utils.rb ├── test ├── client_test.rb └── test_helper.rb └── twitter_oauth.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | mytest.rb 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Richard Taylor 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. Twitter OAuth REST API client library for Ruby 2 | 3 | h2. Current Status 4 | 5 | Twitter turned off access to the v1 API so this project is currently migrating to v1.1. Unfortunately everything is not backward-compatible. 6 | 7 | The v.0.4.9x series of this gem is work in progress getting the library compatible with Twitter v1.1 - when complete we will push v0.5.0 of this library. 8 | 9 | h2. Install the gem 10 | 11 | gem 'twitter_oauth' 12 | 13 | h2. Using the gem 14 | 15 | To make authorized requests with the client library you'll need to "create a Twitter OAuth Application":http://twitter.com/oauth_clients/new. 16 | 17 | See "sinitter":http://github.com/moomerman/sinitter/tree/master for a full website integration example. 18 | 19 | h2. Unauthorized request example 20 | 21 | Since Twitter API v1.1 all requests are required to be authorized. 22 | 23 | h2. Authorized request example 24 | 25 | To use the full power of the Twitter API you need to authorize your application and a valid Twitter user via OAuth. 26 | An example showing how to update the status of an authorized user is below. 27 | 28 | Firstly we need to create an instance of the client with your application client credentials you have been given by Twitter 29 | when you set up your application. 30 | 31 |
client = TwitterOAuth::Client.new(
32 | :consumer_key => 'YOUR_APP_CONSUMER_KEY',
33 | :consumer_secret => 'YOUR_APP_CONSUMER_SECRET'
34 | )
35 | request_token = client.request_token(:oauth_callback => oauth_confirm_url)
36 | #:oauth_callback required for web apps, since oauth gem by default force PIN-based flow
37 | #( see http://groups.google.com/group/twitter-development-talk/browse_thread/thread/472500cfe9e7cdb9/848f834227d3e64d )
38 |
39 |
40 | request_token.authorize_url
41 | => http://twitter.com/oauth/authorize?oauth_token=TOKEN
42 |
43 |
44 | In your application your user would be redirected to Twitter to authorize the application at this point. You'll need to store
45 | the request token (usually in the session) for later. The code continues below assuming the user has authorized your application.
46 |
47 | NOTE: Above we called the client.request_token(...)
method, this authorizes the application on every call. You can also use the client.authentication_request_token(...)
method which automatically redirects back to your application if the user has previously authorized the app.
48 |
49 | access_token = client.authorize(
50 | request_token.token,
51 | request_token.secret,
52 | :oauth_verifier => params[:oauth_verifier]
53 | )
54 |
55 | client.authorized?
56 | => true
57 |
58 | client.update('checking out the twitter_oauth library') # sends a twitter status update
59 |
60 |
61 | Now if you keep hold of the access_token (usually in the database) for this user you won't need to re-authorize them next time. When you create an instance of the client you can just pass in the access token and secret that you have stored.
62 |
63 | access_token = @user.access_token # assuming @user
64 | client = TwitterOAuth::Client.new(
65 | :consumer_key => 'YOUR_CONSUMER_KEY',
66 | :consumer_secret => 'YOUR_APP_CONSUMER_SECRET',
67 | :token => access_token.token,
68 | :secret => access_token.secret
69 | )
70 |
71 | client.authorized?
72 | => true
73 |
74 |
75 | h2. PIN-based flow
76 |
77 | If you're writing a command line application or desktop app, you will probably want to use the PIN-based authorization method rather than the website redirect method.
78 |
79 | client = TwitterOAuth::Client.new(
80 | :consumer_key => 'YOUR_CONSUMER_KEY',
81 | :consumer_secret => 'YOUR_APP_CONSUMER_SECRET'
82 | )
83 |
84 | request_token = client.authentication_request_token(
85 | :oauth_callback => 'oob'
86 | )
87 |
88 | puts request_token.authorize_url
89 |
90 | print 'Please visit the URL and enter the code: '
91 | code = gets.strip
92 |
93 | access_token = client.authorize(
94 | request_token.token,
95 | request_token.secret,
96 | :oauth_verifier => code
97 | )
98 |
99 | client.authorized?
100 | => true
101 |
102 |
103 | The special oauth callback value of oob
tells Twitter you want to do the PIN-based authentication. The user goes to the authorization URL to get their unique code and they paste that into your application. Finally we authorize the user with this code.
104 |
105 | h2. Working with a Proxy
106 |
107 | Services such as "Apigee Analytics and API Management":http://apigee.com/ require you to proxy your API requests through their servers. The workflow is as follows.
108 |
109 | First you need to authorize the Twitter user via OAuth directly via the Twitter API (this part cannot be proxied)
110 |
111 | client = TwitterOAuth::Client.new(
112 | :consumer_key => 'YOUR_APP_CONSUMER_KEY',
113 | :consumer_secret => 'YOUR_APP_CONSUMER_SECRET'
114 | )
115 | request_token = client.request_token(:oauth_callback => 'YOUR_CALLBACK_URL')
116 |
117 | request_token.authorize_url
118 | => http://twitter.com/oauth/authorize?oauth_token=TOKEN
119 |
120 |
121 | The user is sent to Twitter to allow the application to access their account and then you need to obtain the access token for the user
122 |
123 | access_token = client.authorize(
124 | request_token.token,
125 | request_token.secret,
126 | :oauth_verifier => params[:oauth_verifier]
127 | )
128 |
129 | client.authorized?
130 | => true
131 |
132 |
133 | Now you can make all further API calls through the proxy of your choice:
134 |
135 | access_token = @user.access_token # assuming @user
136 | client = TwitterOAuth::Client.new(
137 | :proxy => 'http://XXX.YYY.apigee.com',
138 | :consumer_key => 'YOUR_CONSUMER_KEY',
139 | :consumer_secret => 'YOUR-CONSUMER-SECRET',
140 | :token => access_token.token,
141 | :secret => access_token.secret
142 | )
143 |
144 | client.authorized?
145 | => true
146 |
147 | client.update('Proxy via Apigee is working')
148 |
149 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rake/testtask'
2 | require 'shoulda/tasks'
3 |
4 |
5 | task :default => ["test:units"]
6 |
7 | desc "Run basic tests"
8 | Rake::TestTask.new("test:units") { |t|
9 | t.pattern = 'test/**/*_test.rb'
10 | t.verbose = true
11 | t.warning = true
12 | }
13 |
--------------------------------------------------------------------------------
/lib/twitter_oauth.rb:
--------------------------------------------------------------------------------
1 | require 'oauth'
2 | require 'json'
3 | require 'mime/types'
4 |
5 | require 'twitter_oauth/client'
6 |
7 | module TwitterOAuth
8 | VERSION = '0.4.94'
9 | end
10 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/account.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful;
5 | # returns a 401 status code and an error message if not.
6 | def authorized?
7 | puts "[Client] GET /account/verify_credentials.json" if @debug
8 | oauth_response = access_token.get("/#{@api_version}/account/verify_credentials.json")
9 | return oauth_response.class == Net::HTTPOK
10 | end
11 |
12 | def info
13 | get('/account/verify_credentials.json')
14 | end
15 |
16 | # Updates profile background image. Takes a File object and optional tile argument.
17 | # Returns extended user info object.
18 | def update_profile_background_image(image, tile = false)
19 | body, headers = http_multipart_data({:image => image, :tile => tile})
20 | post('/account/update_profile_background_image.json', body, headers)
21 | end
22 |
23 | # Updates profile avatar image. Takes a File object which should be an image.
24 | # Returns extended user info object.
25 | def update_profile_image(image)
26 | body, headers = http_multipart_data({:image => image})
27 | post('/account/update_profile_image.json', body, headers)
28 | end
29 |
30 | # colors hash must contain at least one or more of the following keys :profile_background_color, :profile_text_color, :profile_link_color, :profile_sidebar_fill_color, :profile_sidebar_border_color
31 | # returns extended user info object.
32 | def update_profile_colors(colors)
33 | post('/account/update_profile_colors.json', colors)
34 | end
35 |
36 | # Sets values that users are able to set under the "Account" tab of their settings page.
37 | # Valid parameters are:
38 | # :name Full name associated with the profile. Maximum of 20 characters.
39 | # :url URL associated with the profile. Will be prepended with "http://" if not present. Maximum of 100 characters.
40 | # :location The city or country describing where the user of the account is located. The contents are not normalized
41 | # or geocoded in any way. Maximum of 30 characters.
42 | # :description A description of the user owning the account. Maximum of 160 characters.
43 | def update_profile(params)
44 | post('/account/update_profile', params)
45 | end
46 |
47 | end
48 | end
49 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/blocks.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Blocks the user specified in the ID parameter as the authenticating user.
5 | # Destroys a friendship to the blocked user if it exists.
6 | # Returns the blocked user in the requested format when successful.
7 | def block(id)
8 | post("/blocks/create/#{id}.json")
9 | end
10 |
11 | # Un-blocks the user specified in the ID parameter for the authenticating user.
12 | # Returns the un-blocked user in the requested format when successful.
13 | def unblock(id)
14 | post("/blocks/destroy/#{id}.json")
15 | end
16 |
17 | # Returns if the authenticating user is blocking a target user.
18 | def blocked?(id)
19 | get("/blocks/exists/#{id}.json")
20 | end
21 |
22 | # Returns an array of user objects that the authenticating user is blocking.
23 | def blocking
24 | get("/blocks/blocking.json")
25 | end
26 |
27 | # Returns an array of numeric user ids the authenticating user is blocking.
28 | def blocking_ids
29 | get("/blocks/blocking/ids.json")
30 | end
31 |
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/client.rb:
--------------------------------------------------------------------------------
1 | require 'twitter_oauth/timeline'
2 | require 'twitter_oauth/status'
3 | require 'twitter_oauth/account'
4 | require 'twitter_oauth/direct_messages'
5 | require 'twitter_oauth/search'
6 | require 'twitter_oauth/notifications'
7 | require 'twitter_oauth/blocks'
8 | require 'twitter_oauth/friendships'
9 | require 'twitter_oauth/user'
10 | require 'twitter_oauth/favorites'
11 | require 'twitter_oauth/utils'
12 | require 'twitter_oauth/trends'
13 | require 'twitter_oauth/lists'
14 | require 'twitter_oauth/saved_searches'
15 | require 'twitter_oauth/spam'
16 | require 'twitter_oauth/geo'
17 | require 'twitter_oauth/help'
18 |
19 | module TwitterOAuth
20 | class Client
21 |
22 | def initialize(options = {})
23 | @consumer_key = options[:consumer_key]
24 | @consumer_secret = options[:consumer_secret]
25 | @token = options[:token]
26 | @secret = options[:secret]
27 | @proxy = options[:proxy]
28 | @debug = options[:debug]
29 | @api_version = options[:api_version] || '1.1'
30 | @api_host = options[:api_host] || 'api.twitter.com'
31 | end
32 |
33 | def authorize(token, secret, options = {})
34 | request_token = OAuth::RequestToken.new(
35 | consumer, token, secret
36 | )
37 | @access_token = request_token.get_access_token(options)
38 | @token = @access_token.token
39 | @secret = @access_token.secret
40 | @access_token
41 | end
42 |
43 | def show(username)
44 | get("/users/show/#{username}.json")
45 | end
46 |
47 | def request_token(options={})
48 | consumer.get_request_token(options)
49 | end
50 |
51 | def authentication_request_token(options={})
52 | consumer.options[:authorize_path] = '/oauth/authenticate'
53 | request_token(options)
54 | end
55 |
56 | private
57 |
58 | def consumer(options={})
59 | @consumer ||= OAuth::Consumer.new(
60 | @consumer_key,
61 | @consumer_secret,
62 | { :site => "https://#{@api_host}", :request_endpoint => @proxy }
63 | )
64 | end
65 |
66 | def access_token
67 | @access_token ||= OAuth::AccessToken.new(consumer, @token, @secret)
68 | end
69 |
70 | def get(path, headers={})
71 | puts "[Client] GET #{path}" if @debug
72 | headers.merge!("User-Agent" => "twitter_oauth gem v#{TwitterOAuth::VERSION}")
73 | oauth_response = access_token.get("/#{@api_version}#{path}", headers)
74 | parse(oauth_response.body)
75 | end
76 |
77 | def post(path, body='', headers={})
78 | puts "[Client] POST #{path}" if @debug
79 | headers.merge!("User-Agent" => "twitter_oauth gem v#{TwitterOAuth::VERSION}")
80 | headers.merge!("Content-Type" => "application/x-www-form-urlencoded\r\n")
81 | oauth_response = access_token.post("/#{@api_version}#{path}", body, headers)
82 | parse(oauth_response.body)
83 | end
84 |
85 | def delete(path, headers={})
86 | puts "[Client] DELETE #{path}" if @debug
87 | headers.merge!("User-Agent" => "twitter_oauth gem v#{TwitterOAuth::VERSION}")
88 | oauth_response = access_token.delete("/#{@api_version}#{path}", headers)
89 | parse(oauth_response.body)
90 | end
91 |
92 | def parse(response_body)
93 | begin
94 | JSON.parse(response_body)
95 | rescue JSON::ParserError
96 | {:response => response_body}.to_json
97 | end
98 | end
99 | end
100 | end
101 |
102 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/direct_messages.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Return the most recent direct messages sent to the authenticating user.
5 | # By default, returns the last 20. See http://apiwiki.twitter.com/Twitter-REST-API-Method:-direct_messages
6 | # for other options
7 | def messages(options={})
8 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
9 | get("/direct_messages.json?#{args}")
10 | end
11 |
12 | # By default, returns a list of the 20 most recent direct messages sent by the authenticating user.
13 | def sent_messages(options={})
14 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
15 | get("/direct_messages/sent.json?#{args}")
16 | end
17 |
18 | # Sends a new direct message to the specified user from the authenticating user.
19 | def message(user, text)
20 | post('/direct_messages/new.json', :user => user, :text => text)
21 | end
22 |
23 | # Destroys the direct message specified in the required ID parameter.
24 | def message_destroy(id)
25 | post("/direct_messages/destroy/#{id}.json")
26 | end
27 |
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/favorites.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Returns the 20 most recent favorite statuses for the authenticating user or user specified by the ID parameter.
5 | def favorites(page=1)
6 | get("/favorites.json?page=#{page}")
7 | end
8 |
9 | # Favorites the status specified in the ID parameter as the authenticating user.
10 | # Returns the favorite status when successful.
11 | def favorite(id)
12 | post("/favorites/create/#{id}.json")
13 | end
14 |
15 | # Un-favorites the status specified in the ID parameter as the authenticating user.
16 | # Returns the un-favorited status when successful.
17 | def unfavorite(id)
18 | post("/favorites/destroy/#{id}.json")
19 | end
20 |
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/friendships.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Returns an array of numeric IDs for every user the specified user is following.
5 | def friends_ids(options={})
6 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
7 | get("/friends/ids.json?#{args}")
8 | end
9 |
10 | # Returns an array of numeric IDs for every user following the specified user.
11 | def followers_ids(options={})
12 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
13 | get("/followers/ids.json?#{args}")
14 | end
15 |
16 | # Allows the authenticating user to follow the specified user. Returns the befriended user when successful.
17 | def friend(id)
18 | post("/friendships/create/#{id}.json")
19 | end
20 |
21 | # Allows the authenticating users to unfollow the specified user. Returns the unfollowed user when successful.
22 | def unfriend(id)
23 | post("/friendships/destroy/#{id}.json")
24 | end
25 |
26 | # Tests for the existence of friendship between two users. Will return true if user_a follows user_b, otherwise will return false.
27 | # You are better off using get_friendship as it returns more extended information.
28 | def friends?(a, b)
29 | oauth_response = access_token.get("/friendships/exists.json?user_a=#{a}&user_b=#{b}")
30 | oauth_response.body.strip == 'true'
31 | end
32 |
33 | # Returns detailed information about the relationship between two users.
34 | def get_friendship(a, b)
35 | get("/friendships/show.json?source_screen_name=#{a}&target_screen_name=#{b}")
36 | end
37 |
38 | # Returns a cursored collection of user objects for every user the specified
39 | # user is following (otherwise known as their "friends")
40 | def friends(cursor=-1)
41 | get("/friends/list.json?cursor=#{cursor}")
42 | end
43 |
44 | # Helper to retrun all friends via multiple requests
45 | def all_friends(cursor=-1)
46 | users = []
47 | while cursor != 0 do
48 | json = friends(cursor)
49 | cursor = json["next_cursor"]
50 | users += json["users"]
51 | end
52 | users
53 | end
54 |
55 | # Returns a cursored collection of user objects for users following the
56 | # specified user.
57 | def followers(cursor=-1)
58 | get("/followers/list.json?cursor=#{cursor}")
59 | end
60 |
61 | # Helper to retrun all followers via multiple requests
62 | def all_followers(cursor=-1)
63 | users = []
64 | while cursor != 0 do
65 | json = followers(cursor)
66 | cursor = json["next_cursor"]
67 | users += json["users"]
68 | end
69 | users
70 | end
71 |
72 | end
73 | end
74 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/geo.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Search for places (cities and neighborhoods) that can be attached to a statuses/update.
5 | # Given a latitude and a longitude, return a list of all the valid places that can be used as a place_id when updating a status
6 | def reverse_geocode(lat, lng, options={})
7 | options[:lat] = lat; options[:lng] = lng
8 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
9 | get "/geo/reverse_geocode.json?#{args}"
10 | end
11 |
12 | # Search for places (cities and neighborhoods) that can be attached to a statuses/update.
13 | # Given a latitude and a longitude pair, or an IP address, return a list of all the valid cities
14 | # and neighborhoods that can be used as a place_id when updating a status.
15 | def geo_search(options={})
16 | options[:query] = URI.escape(options[:query]) if options[:query]
17 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
18 | get "/geo/search.json?#{args}"
19 | end
20 |
21 | # Find out more details of a place that was returned from the geo/reverse_geocode method.
22 | def geo(id)
23 | get "/geo/id/#{id}.json"
24 | end
25 |
26 | end
27 | end
--------------------------------------------------------------------------------
/lib/twitter_oauth/help.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Returns the current rate limits for methods belonging to the specified
5 | # resource families. Each 1.1 API resource belongs to a "resource family"
6 | # which is indicated in its method documentation. You can typically
7 | # determine a method's resource family from the first component of the path
8 | # after the...
9 | def rate_limit_status
10 | get('/application/rate_limit_status.json')
11 | end
12 |
13 | end
14 | end
--------------------------------------------------------------------------------
/lib/twitter_oauth/lists.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | #
5 | # List methods
6 | #
7 |
8 | # Creates a new list for the authenticated user. Accounts are limited to 20 lists.
9 | def create_list(user, list, options={})
10 | post("/#{user}/lists.json", options.merge(:name => list))
11 | end
12 |
13 | # Updates the specified list.
14 | def update_list(user, list, options={})
15 | post("/#{user}/lists/#{list}.json", options)
16 | end
17 |
18 | # List the lists of the specified user.
19 | # Private lists will be included if the authenticated user is the same as the user whose lists are being returned.
20 | def get_lists(user)
21 | get("/#{user}/lists.json")
22 | end
23 |
24 | # Show the specified list. Private lists will only be shown if the authenticated user owns the specified list.
25 | def get_list(user, list)
26 | get("/#{user}/lists/#{list}.json")
27 | end
28 |
29 | # Deletes the specified list. Must be owned by the authenticated user.
30 | def delete_list(user, list)
31 | delete("/#{user}/lists/#{list}.json")
32 | end
33 |
34 | # Show tweet timeline for members of the specified list.
35 | def list_statuses(user, list)
36 | get("/#{user}/lists/#{list}/statuses.json")
37 | end
38 |
39 | # List the lists the specified user has been added to.
40 | def list_memberships(user)
41 | get("/#{user}/lists/memberships.json")
42 | end
43 |
44 | # List the lists the specified user follows.
45 | def list_subscriptions(user)
46 | get("/#{user}/lists/subscriptions.json")
47 | end
48 |
49 | #
50 | # List Members Methods
51 | #
52 |
53 | # Returns the members of the specified list.
54 | def list_members(user, list)
55 | get("/#{user}/#{list}/members.json")
56 | end
57 |
58 | # Add a member to a list. The authenticated user must own the list to be able to add members to it.
59 | # Lists are limited to having 500 members.
60 | def add_member_to_list(user, list, member_id, options={})
61 | post("/#{user}/#{list}/members.json", options.merge(:id => member_id))
62 | end
63 |
64 | # Removes the specified member from the list.
65 | # The authenticated user must be the list's owner to remove members from the list.
66 | def remove_member_from_list(user, list, member_id)
67 | delete("/#{user}/#{list}/members.json?id=#{member_id}")
68 | end
69 |
70 | # Check if a user is a member of the specified list.
71 | def get_member_of_list(user, list, member_id)
72 | get("/#{user}/#{list}/members/#{member_id}.json")
73 | end
74 |
75 | #
76 | # List Subscribers Methods
77 | #
78 |
79 | # Returns the subscribers of the specified list.
80 | def list_subscribers(user, list)
81 | get("/#{user}/#{list}/subscribers.json")
82 | end
83 |
84 | # Make the authenticated user follow the specified list.
85 | def subscribe_to_list(user, list, options={})
86 | post("/#{user}/#{list}/subscribers.json")
87 | end
88 |
89 | # Unsubscribes the authenticated user form the specified list.
90 | def unsubscribe_from_list(user, list)
91 | delete("/#{user}/#{list}/subscribers.json")
92 | end
93 |
94 | # Check if the specified user is a subscriber of the specified list.
95 | def get_subscriber_of_list(user, list, subscriber_id)
96 | get("/#{user}/#{list}/subscribers/#{subscriber_id}.json")
97 | end
98 |
99 | end
100 | end
--------------------------------------------------------------------------------
/lib/twitter_oauth/notifications.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Enables device notifications for updates from the specified user.
5 | # Returns the specified user when successful.
6 | def follow(id)
7 | post("/notifications/follow/#{id}.json")
8 | end
9 |
10 | # Disables notifications for updates from the specified user to the authenticating user.
11 | # Returns the specified user when successful.
12 | def leave(id)
13 | post("/notifications/leave/#{id}.json")
14 | end
15 |
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/saved_searches.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Returns the authenticated user's saved search queries.
5 | def saved_searches
6 | get("/saved_searches.json")
7 | end
8 |
9 | # Retrieve the data for a saved search owned by the authenticating user specified by the given id.
10 | def get_saved_search(search_id)
11 | get("/saved_searches/show/#{search_id}.json")
12 | end
13 |
14 | # Creates a saved search for the authenticated user.
15 | def create_saved_search(query)
16 | post("/saved_searches/create.json", :query => query)
17 | end
18 |
19 | def delete_saved_search(search_id)
20 | post("/saved_searches/destroy/#{search_id}.json")
21 | end
22 |
23 | end
24 | end
--------------------------------------------------------------------------------
/lib/twitter_oauth/search.rb:
--------------------------------------------------------------------------------
1 | require 'open-uri'
2 |
3 | module TwitterOAuth
4 | class Client
5 |
6 | def search(q, options={})
7 | options[:count] ||= 20
8 | options[:q] = URI.escape(q)
9 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
10 | get("/search/tweets.json?#{args}")
11 | end
12 |
13 | end
14 | end
--------------------------------------------------------------------------------
/lib/twitter_oauth/spam.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # The user specified in the id is blocked by the authenticated user and reported as a spammer.
5 | def report_spam(user)
6 | post("/report_spam.json", :id => user)
7 | end
8 |
9 | end
10 | end
--------------------------------------------------------------------------------
/lib/twitter_oauth/status.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Returns a single status, specified by the id parameter below.
5 | def status(id)
6 | get("/statuses/show/#{id}.json")
7 | end
8 |
9 | # Updates the authenticating user's status.
10 | def update(message, options={})
11 | post('/statuses/update.json', options.merge(:status => message))
12 | end
13 |
14 | # Destroys the status specified by the required ID parameter
15 | def status_destroy(id)
16 | post("/statuses/destroy/#{id}.json")
17 | end
18 |
19 | # Retweets the tweet specified by the id parameter. Returns the original tweet with retweet details embedded.
20 | def retweet(id)
21 | post("/statuses/retweet/#{id}.json")
22 | end
23 |
24 | # Returns the 100 most recent retweets of the tweet.
25 | def retweets(id)
26 | get("/statuses/retweets/#{id}.json")
27 | end
28 |
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/timeline.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Returns the 20 most recent statuses from non-protected users who have set a custom user icon.
5 | def public_timeline(options={})
6 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
7 | get("/statuses/public_timeline.json?#{args}")
8 | end
9 |
10 | # Returns the 20 most recent statuses, including retweets, posted by the authenticating user and that user's friends.
11 | # This is the equivalent of /timeline/home on the Web.
12 | def home_timeline(options={})
13 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
14 | get("/statuses/home_timeline.json?#{args}")
15 | end
16 |
17 | # Returns the 20 most recent statuses posted by the authenticating user and that user's friends.
18 | def friends_timeline(options={})
19 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
20 | get("/statuses/friends_timeline.json?#{args}")
21 | end
22 |
23 | # Returns the 20 most recent statuses posted from the authenticating user.
24 | def user_timeline(options={})
25 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
26 | get("/statuses/user_timeline.json?#{args}")
27 | end
28 | alias :user :user_timeline
29 |
30 | # Returns the 20 most recent @replies (status updates prefixed with @username) for the authenticating user.
31 | def mentions(options={})
32 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
33 | get("/statuses/mentions_timeline.json?#{args}")
34 | end
35 | alias :replies :mentions
36 |
37 | # Returns the 20 most recent retweets posted by the authenticating user
38 | def retweeted_by_me(options={})
39 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
40 | get("/statuses/retweeted_by_me.json?#{args}")
41 | end
42 |
43 | # Returns the 20 most recent retweets posted by the authenticating user's friends.
44 | def retweeted_to_me(options={})
45 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
46 | get("/statuses/retweeted_to_me.json?#{args}")
47 | end
48 |
49 | # Returns the 20 most recent tweets of the authenticated user that have been retweeted by others.
50 | def retweets_of_me(options={})
51 | args = options.map{|k,v| "#{k}=#{v}"}.join('&')
52 | get("/statuses/retweets_of_me.json?#{args}")
53 | end
54 |
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/trends.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Returns the top 10 trending topics for a specific WOEID, if trending
5 | # information is available for it. The response is an array of "trend"
6 | # objects that encode the name of the trending topic, the query parameter
7 | # that can be used to search for the topic on Twitter Search, and the
8 | # Twitter Search URL....
9 | def place_trends
10 | get("/trends/place.json")
11 | end
12 |
13 | # Returns the locations that Twitter has trending topic information for. The
14 | # response is an array of "locations" that encode the location's WOEID and
15 | # some other human-readable information such as a canonical name and country
16 | # the location belongs in. A WOEID is a Yahoo! Where On Earth ID.
17 | def available_trends
18 | get("/trends/available.json")
19 | end
20 |
21 | # Returns the locations that Twitter has trending topic information for,
22 | # closest to a specified location. The response is an array of "locations"
23 | # that encode the location's WOEID and some other human-readable information
24 | # such as a canonical name and country the location belongs in.
25 | # A WOEID is a Yahoo...
26 | def closest_trends
27 | get("/trends/closest.json")
28 | end
29 |
30 | end
31 | end
--------------------------------------------------------------------------------
/lib/twitter_oauth/user.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 |
4 | # Returns settings (including current trend, geo and sleep time information)
5 | # for the authenticating user.
6 | def settings
7 | get('/account/settings.json')
8 | end
9 |
10 | # Returns an HTTP 200 OK response code and a representation of the
11 | # requesting user if authentication was successful; returns a 401 status
12 | # code and an error message if not. Use this method to test if supplied user
13 | # credentials are valid.
14 | def verify_credentials
15 | get('/account/verify_credentials.json')
16 | end
17 |
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/twitter_oauth/utils.rb:
--------------------------------------------------------------------------------
1 | module TwitterOAuth
2 | class Client
3 | CRLF = "\r\n"
4 |
5 | private
6 | # Properly encodes images in form/multipart specification for upload via OAuth.
7 | def http_multipart_data(params)
8 | body = ""
9 | headers = {}
10 |
11 | boundary = Time.now.to_i.to_s(16)
12 |
13 | headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
14 | params.each do |key,value|
15 | esc_key = OAuth::Helper.escape(key.to_s)
16 | body << "--#{boundary}#{CRLF}"
17 |
18 | if value.respond_to?(:read)
19 | mime_type = MIME::Types.type_for(value.path)[0] || MIME::Types["application/octet-stream"][0]
20 | body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{File.basename(value.path)}\"#{CRLF}"
21 | body << "Content-Type: #{mime_type.simplified}#{CRLF*2}"
22 | body << value.read
23 | else
24 | body << "Content-Disposition: form-data; name=\"#{esc_key}\"#{CRLF*2}#{value}"
25 | end
26 | end
27 |
28 | body << "--#{boundary}--#{CRLF*2}"
29 | headers["Content-Length"] = body.size.to_s
30 |
31 | return [ body, headers ]
32 | end
33 | end
34 | end
--------------------------------------------------------------------------------
/test/client_test.rb:
--------------------------------------------------------------------------------
1 | require File.join(File.dirname(__FILE__), "/test_helper")
2 |
3 | class ClientTest < Test::Unit::TestCase
4 | include TwitterOAuth
5 |
6 | context "A client instance" do
7 |
8 | setup do
9 | @client = Client.new
10 | end
11 |
12 | should "be kind of TwitterOAuth" do
13 | assert_kind_of TwitterOAuth::Client, @client
14 | end
15 |
16 | context "authentication_request_token" do
17 | setup do
18 | @consumer = stub("oauth consumer", :options => {})
19 | @client.stubs(:request_token)
20 | @client.stubs(:consumer).returns(@consumer)
21 | end
22 |
23 | should "sets consumers authorize path" do
24 | @client.authentication_request_token
25 | assert_equal @client.consumer.options[:authorize_path], '/oauth/authenticate'
26 | end
27 | end
28 |
29 | context "when authorizing" do
30 | setup do
31 | @request_token = stub('a request token')
32 | @access_token = stub_everything('access token')
33 | @request_token.stubs(:get_access_token).returns(@access_token)
34 | OAuth::RequestToken.stubs(:new).returns(@request_token)
35 | end
36 |
37 | should "return an access token" do
38 | assert_equal @client.authorize("haha","haha"), @access_token
39 | end
40 | end
41 |
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'test/unit'
3 | require 'shoulda'
4 | require 'mocha'
5 |
6 | lib_files = File.join(File.dirname(__FILE__), "..", "lib")
7 |
8 | Dir.glob(File.join(lib_files, "**")).each do |file|
9 | require file
10 | end
11 |
--------------------------------------------------------------------------------
/twitter_oauth.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 |
3 | Gem::Specification.new do |s|
4 | s.name = %q{twitter_oauth}
5 | s.version = "0.4.94"
6 |
7 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8 | s.authors = ["Richard Taylor"]
9 | s.date = %q{2013-06-12}
10 | s.description = %q{twitter_oauth is a Ruby client for the Twitter API using OAuth.}
11 | s.email = %q{moomerman@gmail.com}
12 | s.files = ["LICENSE", "README.textile","lib/twitter_oauth.rb"] + Dir.glob('lib/twitter_oauth/*.rb')
13 | s.has_rdoc = false
14 | s.homepage = %q{http://github.com/moomerman/twitter_oauth}
15 | s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
16 | s.require_paths = ["lib"]
17 | s.rubyforge_project = %q{twitter_oauth}
18 | s.rubygems_version = %q{1.3.1}
19 | s.summary = %q{twitter_oauth is a Ruby client for the Twitter API using OAuth.}
20 |
21 | if s.respond_to? :specification_version then
22 | current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23 | s.specification_version = 2
24 |
25 | if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26 | s.add_runtime_dependency(%q