Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
module ActionSprout
  module Facebook
    class CanonicalId

      method_object :facebook_post_id, :api

      POST_ID_ERROR_MESSAGE = '"facebook_post_id:" keyword argument must be present'.freeze
      API_ERROR_MESSAGE = '"api:" keyword argument must be present'.freeze

      def call
        check_args
        return post_object_id if post_object_id.present?
        return CanonicalId.call(facebook_post_id: parent_id, api: api) if parent_id.present?

        object_id = Link.call(link: link, api: api)
        return object_id if object_id.present?

        post_id
      end

      private

      def check_args
        raise ArgumentError, POST_ID_ERROR_MESSAGE unless facebook_post_id.present?
        raise ArgumentError, API_ERROR_MESSAGE unless api.present?
      end

      def post_object_id
        post_data['object_id']
      end

      def parent_id
        post_data['parent_id']
      end

      def link
        post_data['link']
      end

      def post_id
        post_data['id']
      end

      def post_data
        @_post_data ||= fetch_post.parsed_response
      end

      def fetch_post
        api.get facebook_post_id, query: post_query
      end

      def post_query
        {
          fields: 'id,object_id,parent_id,link'
        }
      end

      class Link
        method_object :link, :api

        IGNORE_LINK_PATTERNS = [
          'https://fb.me/'.freeze,
          %r{^fb://}.freeze,
        ]

        def call
          if link.present? && ! ignore_link?
            og_object_id || id_from_scrape
          end
        end

        private

        def og_object_id
          api.get("/", query: { id: link, fields: "og_object{id}" }).parsed_response.dig("og_object", "id")
        rescue ActionSprout::Facebook::FacebookError => e
          handle_og_object_facebook_error e
        end

        def id_from_scrape
          api.post("/", query: { id: link, scrape: true }).parsed_response.dig("id")
        end

        def handle_og_object_facebook_error(error)
          if error.message.match(/Tried accessing nonexisting field/)
            # When the link is to a Facebook page, the object is the page which
            # does not have an og_object.
            api.get("/", query: { id: link }).parsed_response&.dig('id')
          else
            raise error
          end
        end

        def ignore_link?
          IGNORE_LINK_PATTERNS.any? { |pattern| pattern === link }
        end
      end
    end
  end
end