module Instagram::Client::Subscriptions
Defines methods related to real-time
Public Instance Methods
Creates a real-time subscription
@overload create_subscription
(options={})
@param options [Hash] A set of parameters @option options [String] :object The object you'd like to subscribe to (user, tag, location or geography) @option options [String] :callback_url The subscription callback URL @option options [String] :aspect The aspect of the object you'd like to subscribe to (in this case, "media"). @option options [String, Integer] :object_id When specifying a location or tag use the location's ID or tag name respectively @option options [String, Float] :lat The center latitude of an area, used when subscribing to a geography object @option options [String, Float] :lng The center longitude of an area, used when subscribing to a geography object @option options [String, Integer] :radius The distance in meters you'd like to capture around a given point
@overload create_subscription
(object, callback_url, aspect=“media”, options={})
@param object [String] The object you'd like to subscribe to (user, tag, location or geography) @param callback_url [String] The subscription callback URL @param aspect [String] he aspect of the object you'd like to subscribe to (in this case, "media"). @param options [Hash] Addition options and parameters @option options [String, Integer] :object_id When specifying a location or tag use the location's ID or tag name respectively @option options [String, Float] :lat The center latitude of an area, used when subscribing to a geography object @option options [String, Float] :lng The center longitude of an area, used when subscribing to a geography object @option options [String, Integer] :radius The distance in meters you'd like to capture around a given point Note that we only support "media" at this time, but we might support other types of subscriptions in the future. @return [Hashie::Mash] The subscription created. @example Creates a new subscription to receive notifications for user media changes. Instagram.create_subscription("user", "http://example.com/instagram/callback")
@format :json @authenticated true
Requires client_secret to be set on the client or passed in options
@rate_limited true @see api.instagram.com/developer/realtime/
# File lib/instagram/client/subscriptions.rb, line 56 def create_subscription(*args) options = args.last.is_a?(Hash) ? args.pop : {} object = args.shift callback_url = args.shift aspect = args.shift options.tap {|o| o[:object] = object unless object.nil? o[:callback_url] = callback_url unless callback_url.nil? o[:aspect] = aspect || o[:aspect] || "media" } response = post("subscriptions", options.merge(:client_secret => client_secret), signature=true) response end
Deletes a real-time subscription
@overload delete_subscription
(options={})
@param options [Hash] Addition options and parameters @option options [Integer] :subscription_id The subscription's ID @option options [String] :object When specified will remove all subscriptions of this object type, unless an :object_id is also specified (user, tag, location or geography) @option options [String, Integer] :object_id When specifying :object, inlcude an :object_id to only remove subscriptions of that object and object_id
@overload delete_subscription
(subscription_id, options={})
@param subscription_id [Integer] The subscription's ID @param options [Hash] Addition options and parameters @option options [String] :object When specified will remove all subscriptions of this object type, unless an :object_id is also specified (user, tag, location or geography) @option options [String, Integer] :object_id When specifying :object, inlcude an :object_id to only remove subscriptions of that object and object_id @return [Hashie::Mash] @example Deletes an application's user change subscription Instagram.delete_subscription(:object => "user")
@format :json @authenticated true
Requires client_secret to be set on the client or passed in options
@rate_limited true @see api.instagram.com/developer/realtime/
# File lib/instagram/client/subscriptions.rb, line 91 def delete_subscription(*args) options = args.last.is_a?(Hash) ? args.pop : {} subscription_id = args.first options.merge!(:id => subscription_id) if subscription_id response = delete("subscriptions", options.merge(:client_secret => client_secret), signature=true) response end
As a security measure (to prevent DDoS attacks), Instagram
sends a verification request to your server after you request a subscription. This method parses the challenge params and makes sure the call is legitimate.
@param params the request parameters sent by Instagram
. (You can pass in a Rails params hash.) @param verify_token the verify token sent in the {#subscribe subscription request}, if you provided one
@yield verify_token if you need to compute the verification token
(for instance, if your callback URL includes a record ID, which you look up and use to calculate a hash), you can pass meet_challenge a block, which will receive the verify_token received back from Instagram.
@return the challenge string to be sent back to Instagram
, or false if the request is invalid.
# File lib/instagram/client/subscriptions.rb, line 112 def meet_challenge(params, verify_token = nil, &verification_block) if params["hub.mode"] == "subscribe" && # you can make sure this is legitimate through two ways # if your store the token across the calls, you can pass in the token value # and we'll make sure it matches ((verify_token && params["hub.verify_token"] == verify_token) || # alternately, if you sent a specially-constructed value (such as a hash of various secret values) # you can pass in a block, which we'll call with the verify_token sent by Instagram # if it's legit, return anything that evaluates to true; otherwise, return nil or false (verification_block && yield(params["hub.verify_token"]))) params["hub.challenge"] else false end end
Process a subscription notification JSON payload
@overload process_subscription
(json, &block)
@param json [String] The JSON response received by the Instagram real-time server @param block [Proc] A callable in which callbacks are defined @option options [String] :signature Pass in an X-Hub-Signature to use for payload validation @return [nil] @example Process and handle a notification for a user media change Instagram.process_subscription(params[:body]) do |handler| handler.on_user_changed do |user_id, data| user = User.by_instagram_id(user_id) @client = Instagram.client(:access_token => _access_token_for_user(user)) latest_media = @client.user_recent_media[0] user.media.create_with_hash(latest_media) end end
@format :json @authenticated true
Requires client_secret to be set on the client or passed in options
@rate_limited true @see api.instagram.com/developer/realtime/
# File lib/instagram/client/subscriptions.rb, line 177 def process_subscription(json, options={}, &block) raise ArgumentError, "callbacks block expected" unless block_given? if options.has_key?(:signature) if !client_secret raise ArgumentError, "client_secret must be set during configure" end digest = OpenSSL::Digest.new('sha1') verify_signature = OpenSSL::HMAC.hexdigest(digest, client_secret, json) if options[:signature] != verify_signature raise Instagram::InvalidSignature, "invalid X-Hub-Signature does not match verify signature against client_secret" end end payload = MultiJson.decode(json) @changes = Hash.new { |h,k| h[k] = [] } for change in payload @changes[change['object']] << change end block.call(self) end
Returns a list of active real-time subscriptions
@overload subscriptions(options={})
@return [Hashie::Mash] The list of subscriptions. @example Returns a list of subscriptions for the authenticated application Instagram.subscriptions
@format :json @authenticated true
Requires client_secret to be set on the client or passed in options
@rate_limited true @see api.instagram.com/developer/realtime/
# File lib/instagram/client/subscriptions.rb, line 20 def subscriptions(options={}) response = get("subscriptions", options.merge(:client_secret => client_secret)) response end
Public: As a security measure, all updates from Instagram
are signed using X-Hub-Signature: XXXX where XXX is the sha1 of the json payload using your application secret as the key.
Example:
# in Rails controller def receive_update if Instagram.validate_update(request.body, headers) ... else render text: "not authorized", status: 401 end end
# File lib/instagram/client/subscriptions.rb, line 141 def validate_update(body, headers) unless client_secret raise ArgumentError, "client_secret must be set during configure" end if request_signature = headers['X-Hub-Signature'] || headers['HTTP_X_HUB_SIGNATURE'] calculated_signature = OpenSSL::HMAC.hexdigest('sha1', client_secret, body) calculated_signature == request_signature end end