instagram 0.11.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,23 @@
1
1
  module Instagram
2
2
  class Client
3
+ # Defines methods related to embedding
3
4
  module Embedding
5
+ # Returns information about the media associated with the given short link
6
+ #
7
+ # @overload oembed(url=nil, options={})
8
+ # @param url [String] An instagram short link
9
+ # @param options [Hash] A customizable set of options
10
+ # @option options [Integer] :maxheight Maximum height of returned media
11
+ # @option options [Integer] :maxwidth Maximum width of returned media
12
+ # @option options [Integer] :callback A JSON callback to be invoked
13
+ # @return [Hashie::Mash] Information about the media associated with given short link
14
+ # @example Return information about the media associated with http://instagr.am/p/BUG/
15
+ # Instagram.oembed(http://instagr.am/p/BUG/)
16
+ #
17
+ # @see http://instagram.com/developer/embedding/#oembed
18
+ # @format :json
19
+ # @authenticated false
20
+ # @rate_limited true
4
21
  def oembed(*args)
5
22
  url = args.first
6
23
  return nil unless url
@@ -14,7 +14,7 @@ module Instagram
14
14
  #
15
15
  # If getting this data of a protected user, you must be authenticated (and be allowed to see that user).
16
16
  # @rate_limited true
17
- # @see TODO:docs url
17
+ # @see http://instagram.com/developer/endpoints/likes/#get_media_likes
18
18
  def media_likes(id, *args)
19
19
  response = get("media/#{id}/likes")
20
20
  response
@@ -32,7 +32,7 @@ module Instagram
32
32
  #
33
33
  # If getting this data of a protected user, you must be authenticated (and be allowed to see that user).
34
34
  # @rate_limited true
35
- # @see TODO:docs url
35
+ # @see http://instagram.com/developer/endpoints/likes/#post_likes
36
36
  def like_media(id, options={})
37
37
  response = post("media/#{id}/likes", options)
38
38
  response
@@ -48,7 +48,7 @@ module Instagram
48
48
  # @format :json
49
49
  # @authenticated true
50
50
  # @rate_limited true
51
- # @see TODO:docs url
51
+ # @see http://instagram.com/developer/endpoints/likes/#delete_likes
52
52
  def unlike_media(id, options={})
53
53
  response = delete("media/#{id}/likes", options)
54
54
  response
@@ -12,7 +12,7 @@ module Instagram
12
12
  # @format :json
13
13
  # @authenticated false
14
14
  # @rate_limited true
15
- # @see TODO:docs url
15
+ # @see http://instagram.com/developer/endpoints/locations/#get_locations
16
16
  def location(id, *args)
17
17
  response = get("locations/#{id}")
18
18
  response
@@ -28,7 +28,7 @@ module Instagram
28
28
  # @return [Hashie::Mash]
29
29
  # @example Return a list of the most recent media items taken at the Instagram office
30
30
  # Instagram.location_recent_media(514276)
31
- # @see TODO:docs url
31
+ # @see http://instagram.com/developer/endpoints/locations/#get_locations_media_recent
32
32
  # @format :json
33
33
  # @authenticated false
34
34
  # @rate_limited true
@@ -50,7 +50,7 @@ module Instagram
50
50
  # Instagram.location_search("3fd66200f964a520c5f11ee3") (Schiller's Liquor Bar, 131 Rivington St., NY, NY 10002)
51
51
  # @example 2: Return locations around 37.7808851, -122.3948632 (164 S Park, SF, CA USA)
52
52
  # Instagram.location_search("37.7808851", "-122.3948632")
53
- # @see TODO:doc url
53
+ # @see http://instagram.com/developer/endpoints/locations/#get_locations_search
54
54
  # @format :json
55
55
  # @authenticated false
56
56
  # @rate_limited true
@@ -63,6 +63,9 @@ module Instagram
63
63
  when 2
64
64
  lat, lng = args
65
65
  response = get('locations/search', options.merge(:lat => lat, :lng => lng))
66
+ when 3
67
+ lat, lng, distance = args
68
+ response = get('locations/search', options.merge(:lat => lat, :lng => lng, :distance => distance))
66
69
  end
67
70
  response
68
71
  end
@@ -14,7 +14,7 @@ module Instagram
14
14
  #
15
15
  # If getting this data of a protected user, you must authenticate (and be allowed to see that user).
16
16
  # @rate_limited true
17
- # @see TODO:docs url
17
+ # @see http://instagram.com/developer/endpoints/media/#get_media
18
18
  def media_item(*args)
19
19
  id = args.first || 'self'
20
20
  response = get("media/#{id}")
@@ -28,7 +28,7 @@ module Instagram
28
28
  # @return [Hashie::Mash]
29
29
  # @example Returns a list of the overall most popular media
30
30
  # Instagram.media_popular
31
- # @see TODO:docs url
31
+ # @see http://instagram.com/developer/endpoints/media/#get_media_popular
32
32
  # @format :json
33
33
  # @authenticated false unless requesting it from a protected user
34
34
  #
@@ -50,7 +50,7 @@ module Instagram
50
50
  # @return [Hashie::Mash] A list of matching media
51
51
  # @example Return media around 37.7808851, -122.3948632 (164 S Park, SF, CA USA)
52
52
  # Instagram.media_search("37.7808851", "-122.3948632")
53
- # @see TODO:doc url
53
+ # @see http://instagram.com/developer/endpoints/media/#get_media_search
54
54
  # @format :json
55
55
  # @authenticated false
56
56
  # @rate_limited true
@@ -41,7 +41,7 @@ module Instagram
41
41
  # @option options [String, Integer] :object_id When specifying a location or tag use the location's ID or tag name respectively
42
42
  # @option options [String, Float] :lat The center latitude of an area, used when subscribing to a geography object
43
43
  # @option options [String, Float] :lng The center longitude of an area, used when subscribing to a geography object
44
- # @option options [String, Integer] :radius The distance in meters you'd like to capture around a given point
44
+ # @option options [String, Integer] :radius The distance in meters you'd like to capture around a given point
45
45
  #
46
46
  # Note that we only support "media" at this time, but we might support other types of subscriptions in the future.
47
47
  # @return [Hashie::Mash] The subscription created.
@@ -96,6 +96,61 @@ module Instagram
96
96
  response
97
97
  end
98
98
 
99
+ # As a security measure (to prevent DDoS attacks), Instagram sends a verification request to your server
100
+ # after you request a subscription.
101
+ # This method parses the challenge params and makes sure the call is legitimate.
102
+ #
103
+ # @param params the request parameters sent by Instagram. (You can pass in a Rails params hash.)
104
+ # @param verify_token the verify token sent in the {#subscribe subscription request}, if you provided one
105
+ #
106
+ # @yield verify_token if you need to compute the verification token
107
+ # (for instance, if your callback URL includes a record ID, which you look up
108
+ # and use to calculate a hash), you can pass meet_challenge a block, which
109
+ # will receive the verify_token received back from Instagram.
110
+ #
111
+ # @return the challenge string to be sent back to Instagram, or false if the request is invalid.
112
+ def meet_challenge(params, verify_token = nil, &verification_block)
113
+ if params["hub.mode"] == "subscribe" &&
114
+ # you can make sure this is legitimate through two ways
115
+ # if your store the token across the calls, you can pass in the token value
116
+ # and we'll make sure it matches
117
+ ((verify_token && params["hub.verify_token"] == verify_token) ||
118
+ # alternately, if you sent a specially-constructed value (such as a hash of various secret values)
119
+ # you can pass in a block, which we'll call with the verify_token sent by Instagram
120
+ # if it's legit, return anything that evaluates to true; otherwise, return nil or false
121
+ (verification_block && yield(params["hub.verify_token"])))
122
+ params["hub.challenge"]
123
+ else
124
+ false
125
+ end
126
+ end
127
+
128
+ # Public: As a security measure, all updates from Instagram are signed using
129
+ # X-Hub-Signature: sha1=XXXX where XXX is the sha1 of the json payload
130
+ # using your application secret as the key.
131
+ #
132
+ # Example:
133
+ # # in Rails controller
134
+ # def receive_update
135
+ # if Instagram.validate_update(request.body, headers)
136
+ # ...
137
+ # else
138
+ # render text: "not authorized", status: 401
139
+ # end
140
+ # end
141
+ def validate_update(body, headers)
142
+ unless client_secret
143
+ raise ArgumentError, "client_secret must be set during configure"
144
+ end
145
+
146
+ if request_signature = headers['X-Hub-Signature'] || headers['HTTP_X_HUB_SIGNATURE'] and
147
+ signature_parts = request_signature.split('sha1=')
148
+ request_signature = signature_parts[1]
149
+ calculated_signature = OpenSSL::HMAC.hexdigest('sha1', client_secret, body)
150
+ calculated_signature == request_signature
151
+ end
152
+ end
153
+
99
154
  # Process a subscription notification JSON payload
100
155
  #
101
156
  # @overload process_subscription(json, &block)
@@ -124,7 +179,7 @@ module Instagram
124
179
  def process_subscription(json, options={}, &block)
125
180
  raise ArgumentError, "callbacks block expected" unless block_given?
126
181
 
127
- if options[:signature]
182
+ if options.has_key?(:signature)
128
183
  if !client_secret
129
184
  raise ArgumentError, "client_secret must be set during configure"
130
185
  end
@@ -12,7 +12,7 @@ module Instagram
12
12
  # @format :json
13
13
  # @authenticated false
14
14
  # @rate_limited true
15
- # @see TODO:docs url
15
+ # @see http://instagram.com/developer/endpoints/tags/#get_tags
16
16
  def tag(tag, *args)
17
17
  response = get("tags/#{tag}")
18
18
  response
@@ -21,20 +21,20 @@ module Instagram
21
21
  # Returns a list of recent media items for a given Instagram tag
22
22
  #
23
23
  # @overload tag_recent_media(tag, options={})
24
- # @param id [String] An Instagram tag name.
24
+ # @param tag-name [String] An Instagram tag name.
25
25
  # @param options [Hash] A customizable set of options.
26
26
  # @option options [Integer] :max_id (nil) Returns results with an ID less than (that is, older than) or equal to the specified ID.
27
- # @option options [Integer] :count (nil) Limits the number of results returned per page.
27
+ # @option options [Integer] :min_id (nil) Returns results with an ID greater than (that is, newer than) or equal to the specified ID.
28
28
  # @return [Hashie::Mash]
29
29
  # @example Return a list of the most recent media items tagged "cat"
30
30
  # Instagram.tag_recent_media('cat')
31
- # @see TODO:docs url
31
+ # @see http://instagram.com/developer/endpoints/tags/#get_tags_media_recent
32
32
  # @format :json
33
33
  # @authenticated false
34
34
  # @rate_limited true
35
35
  def tag_recent_media(id, *args)
36
36
  options = args.last.is_a?(Hash) ? args.pop : {}
37
- response = get("tags/#{id}/media/recent", options)
37
+ response = get("tags/#{id}/media/recent", options, false, false)
38
38
  response
39
39
  end
40
40
 
@@ -47,7 +47,7 @@ module Instagram
47
47
  # @param options [Hash] A customizable set of options.
48
48
  # @option options [Integer] :count The number of media items to retrieve.
49
49
  # @return [Hashie::Mash]
50
- # @see TODO:doc url
50
+ # @see http://instagram.com/developer/endpoints/tags/#get_tags_search
51
51
  # @example Return tags that start with "cat"
52
52
  # Instagram.tag_search("cat")
53
53
  def tag_search(query, options={})
@@ -14,7 +14,7 @@ module Instagram
14
14
  #
15
15
  # If getting this data of a protected user, you must authenticate (and be allowed to see that user).
16
16
  # @rate_limited true
17
- # @see TODO:docs url
17
+ # @see http://instagram.com/developer/endpoints/users/#get_users
18
18
  def user(*args)
19
19
  options = args.last.is_a?(Hash) ? args.pop : {}
20
20
  id = args.first || 'self'
@@ -31,7 +31,7 @@ module Instagram
31
31
  # @param options [Hash] A customizable set of options.
32
32
  # @option options [Integer] :count The number of users to retrieve.
33
33
  # @return [Hashie::Mash]
34
- # @see TODO:doc url
34
+ # @see http://instagram.com/developer/endpoints/users/#get_users_search
35
35
  # @example Return users that match "Shayne Sweeney"
36
36
  # Instagram.user_search("Shayne Sweeney")
37
37
  def user_search(query, options={})
@@ -54,7 +54,7 @@ module Instagram
54
54
  # @return [Hashie::Mash]
55
55
  # @example Return a list of users @mikeyk follows
56
56
  # Instagram.user_follows(4) # @mikeyk user ID being 4
57
- # @see TODO:docs url
57
+ # @see http://instagram.com/developer/endpoints/relationships/#get_users_follows
58
58
  # @format :json
59
59
  # @authenticated false unless requesting it from a protected user
60
60
  #
@@ -83,7 +83,7 @@ module Instagram
83
83
  # @return [Hashie::Mash]
84
84
  # @example Return a list of users @mikeyk is followed by
85
85
  # Instagram.user_followed_by(4) # @mikeyk user ID being 4
86
- # @see TODO:docs url
86
+ # @see http://instagram.com/developer/endpoints/relationships/#get_users_followed_by
87
87
  # @format :json
88
88
  # @authenticated false unless requesting it from a protected user
89
89
  #
@@ -96,7 +96,7 @@ module Instagram
96
96
  response
97
97
  end
98
98
 
99
- # Returns a list of users whom a given user is followed by
99
+ # Returns a list of users who have requested the currently authorized user's permission to follow
100
100
  #
101
101
  # @overload user_requested_by()
102
102
  # @param options [Hash] A customizable set of options.
@@ -107,16 +107,16 @@ module Instagram
107
107
  # @return [Hashie::Mash]
108
108
  # @example Return a list of users who have requested to follow the authenticated user
109
109
  # Instagram.user_requested_by()
110
- # @see TODO:docs url
110
+ # @see http://instagram.com/developer/endpoints/relationships/#get_incoming_requests
111
111
  # @format :json
112
- # @authenticated truei
112
+ # @authenticated true
113
113
  # @rate_limited true
114
114
  def user_requested_by()
115
115
  response = get("users/self/requested-by")
116
116
  response
117
117
  end
118
118
 
119
- # Returns most recent media items from the currently authorized user's feed.
119
+ # Returns most recent media items from the currently authorized user's feed
120
120
  #
121
121
  # @overload user_media_feed(options={})
122
122
  # @param options [Hash] A customizable set of options.
@@ -190,7 +190,7 @@ module Instagram
190
190
  # @return [Hashie::Mash]
191
191
  # @example Return the relationship status between the currently authenticated user and @mikeyk
192
192
  # Instagram.user_relationship(4) # @mikeyk user ID being 4
193
- # @see http://instagram.com/developer/endpoints/relationships/
193
+ # @see http://instagram.com/developer/endpoints/relationships/#get_relationship
194
194
  # @format :json
195
195
  # @authenticated true
196
196
  # @rate_limited true
@@ -207,7 +207,7 @@ module Instagram
207
207
  # @return [Hashie::Mash]
208
208
  # @example Request the current user to follow the target user
209
209
  # Instagram.follow_user(4)
210
- # @see http://instagram.com/developer/endpoints/relationships/
210
+ # @see http://instagram.com/developer/endpoints/relationships/#post_relationship
211
211
  # @format :json
212
212
  # @authenticated true
213
213
  # @rate_limited true
@@ -225,7 +225,7 @@ module Instagram
225
225
  # @return [Hashie::Mash]
226
226
  # @example Remove a follows relationship between the current user and the target user
227
227
  # Instagram.unfollow_user(4)
228
- # @see http://instagram.com/developer/endpoints/relationships/
228
+ # @see http://instagram.com/developer/endpoints/relationships/#post_relationship
229
229
  # @format :json
230
230
  # @authenticated true
231
231
  # @rate_limited true
@@ -243,7 +243,7 @@ module Instagram
243
243
  # @return [Hashie::Mash]
244
244
  # @example Block a relationship between the current user and the target user
245
245
  # Instagram.block_user(4)
246
- # @see http://instagram.com/developer/endpoints/relationships/
246
+ # @see http://instagram.com/developer/endpoints/relationships/#post_relationship
247
247
  # @format :json
248
248
  # @authenticated true
249
249
  # @rate_limited true
@@ -261,7 +261,7 @@ module Instagram
261
261
  # @return [Hashie::Mash]
262
262
  # @example Remove a relationship block between the current user and the target user
263
263
  # Instagram.unblock_user(4)
264
- # @see http://instagram.com/developer/endpoints/relationships/
264
+ # @see http://instagram.com/developer/endpoints/relationships/#post_relationship
265
265
  # @format :json
266
266
  # @authenticated true
267
267
  # @rate_limited true
@@ -279,7 +279,7 @@ module Instagram
279
279
  # @return [Hashie::Mash]
280
280
  # @example Approve a relationship request between the current user and the target user
281
281
  # Instagram.approve_user(4)
282
- # @see http://instagram.com/developer/endpoints/relationships/
282
+ # @see http://instagram.com/developer/endpoints/relationships/#post_relationship
283
283
  # @format :json
284
284
  # @authenticated true
285
285
  # @rate_limited true
@@ -297,7 +297,7 @@ module Instagram
297
297
  # @return [Hashie::Mash]
298
298
  # @example Deny a relationship request between the current user and the target user
299
299
  # Instagram.deny_user(4)
300
- # @see http://instagram.com/developer/endpoints/relationships/
300
+ # @see http://instagram.com/developer/endpoints/relationships/#post_relationship
301
301
  # @format :json
302
302
  # @authenticated true
303
303
  # @rate_limited true
@@ -2,6 +2,19 @@ module Instagram
2
2
  class Client
3
3
  # @private
4
4
  module Utils
5
+ # Returns the raw full response including all headers. Can be used to access the values for 'X-Ratelimit-Limit' and 'X-Ratelimit-Remaining'
6
+ # ==== Examples
7
+ #
8
+ # client = Instagram.client(:access_token => session[:access_token])
9
+ # response = client.utils_raw_response
10
+ # remaining = response.headers[:x_ratelimit_remaining]
11
+ # limit = response.headers[:x_ratelimit_limit]
12
+ #
13
+ def utils_raw_response
14
+ response = get('users/self/feed',nil,true)
15
+ response
16
+ end
17
+
5
18
  private
6
19
 
7
20
  # Returns the configured user name or the user name of the authenticated user
@@ -6,22 +6,22 @@ module Instagram
6
6
  module Configuration
7
7
  # An array of valid keys in the options hash when configuring a {Instagram::API}
8
8
  VALID_OPTIONS_KEYS = [
9
+ :access_token,
9
10
  :adapter,
10
11
  :client_id,
11
12
  :client_secret,
13
+ :connection_options,
12
14
  :scope,
13
- :access_token,
15
+ :redirect_uri,
14
16
  :endpoint,
15
17
  :format,
18
+ :proxy,
16
19
  :user_agent,
17
- :proxy
20
+ :no_response_wrapper
18
21
  ].freeze
19
22
 
20
- # An array of valid request/response formats
21
- #
22
- # @note Not all methods support the XML format.
23
- VALID_FORMATS = [
24
- :json].freeze
23
+ # By default, don't set a user access token
24
+ DEFAULT_ACCESS_TOKEN = nil
25
25
 
26
26
  # The adapter that will be used to connect if none is set
27
27
  #
@@ -34,14 +34,8 @@ module Instagram
34
34
  # By default, don't set an application secret
35
35
  DEFAULT_CLIENT_SECRET = nil
36
36
 
37
- # By default, don't set an application redirect uri
38
- DEFAULT_REDIRECT_URI = nil
39
-
40
- # By default, don't set a user access token
41
- DEFAULT_ACCESS_TOKEN = nil
42
-
43
- # By default, don't set a user scope
44
- DEFAULT_SCOPE = nil
37
+ # By default, don't set any connection options
38
+ DEFAULT_CONNECTION_OPTIONS = {}
45
39
 
46
40
  # The endpoint that will be used to connect if none is set
47
41
  #
@@ -56,9 +50,24 @@ module Instagram
56
50
  # By default, don't use a proxy server
57
51
  DEFAULT_PROXY = nil
58
52
 
53
+ # By default, don't set an application redirect uri
54
+ DEFAULT_REDIRECT_URI = nil
55
+
56
+ # By default, don't set a user scope
57
+ DEFAULT_SCOPE = nil
58
+
59
+ # By default, don't wrap responses with meta data (i.e. pagination)
60
+ DEFAULT_NO_RESPONSE_WRAPPER = false
61
+
59
62
  # The user agent that will be sent to the API endpoint if none is set
60
63
  DEFAULT_USER_AGENT = "Instagram Ruby Gem #{Instagram::VERSION}".freeze
61
64
 
65
+ # An array of valid request/response formats
66
+ #
67
+ # @note Not all methods support the XML format.
68
+ VALID_FORMATS = [
69
+ :json].freeze
70
+
62
71
  # @private
63
72
  attr_accessor *VALID_OPTIONS_KEYS
64
73
 
@@ -81,15 +90,18 @@ module Instagram
81
90
 
82
91
  # Reset all configuration options to defaults
83
92
  def reset
84
- self.adapter = DEFAULT_ADAPTER
85
- self.client_id = DEFAULT_CLIENT_ID
86
- self.client_secret = DEFAULT_CLIENT_SECRET
87
- self.scope = DEFAULT_SCOPE
88
- self.access_token = DEFAULT_ACCESS_TOKEN
89
- self.endpoint = DEFAULT_ENDPOINT
90
- self.format = DEFAULT_FORMAT
91
- self.user_agent = DEFAULT_USER_AGENT
92
- self.proxy = DEFAULT_PROXY
93
+ self.access_token = DEFAULT_ACCESS_TOKEN
94
+ self.adapter = DEFAULT_ADAPTER
95
+ self.client_id = DEFAULT_CLIENT_ID
96
+ self.client_secret = DEFAULT_CLIENT_SECRET
97
+ self.connection_options = DEFAULT_CONNECTION_OPTIONS
98
+ self.scope = DEFAULT_SCOPE
99
+ self.redirect_uri = DEFAULT_REDIRECT_URI
100
+ self.endpoint = DEFAULT_ENDPOINT
101
+ self.format = DEFAULT_FORMAT
102
+ self.proxy = DEFAULT_PROXY
103
+ self.user_agent = DEFAULT_USER_AGENT
104
+ self.no_response_wrapper= DEFAULT_NO_RESPONSE_WRAPPER
93
105
  end
94
106
  end
95
- end
107
+ end