diff --git a/lib/linked_in/api.rb b/lib/linked_in/api.rb index db90c60..cde76cf 100644 --- a/lib/linked_in/api.rb +++ b/lib/linked_in/api.rb @@ -24,7 +24,8 @@ def initialize(access_token=nil) :skills, :connections, :picture_urls, - :new_connections + :new_connections, + :me def_delegators :@search, :search @@ -50,15 +51,10 @@ def initialize(access_token=nil) def_delegators :@communications, :send_message - def_delegators :@share_and_social_stream, :shares, - :share, - :add_share, - :like_share, - :share_likes, - :unlike_share, - :share_comments, - :update_comment, - :network_updates + def_delegators :@share_and_social_stream, :add_text_share + + def_delegators :@organizations, :organization_access, + :organization private ############################################################## @@ -70,16 +66,15 @@ def initialize_endpoints @companies = LinkedIn::Companies.new(@connection) @communications = LinkedIn::Communications.new(@connection) @share_and_social_stream = LinkedIn::ShareAndSocialStream.new(@connection) + @organizations = LinkedIn::Organizations.new(@connection) end def default_params - # https//developer.linkedin.com/documents/authentication - return {oauth2_access_token: @access_token.token} + {} end def default_headers - # https://developer.linkedin.com/documents/api-requests-json - return {"x-li-format" => "json"} + { "Authorization" => "Bearer #{@access_token.token}" } end def verify_access_token!(access_token) diff --git a/lib/linked_in/api_resource.rb b/lib/linked_in/api_resource.rb index 83b8984..9fd8b31 100644 --- a/lib/linked_in/api_resource.rb +++ b/lib/linked_in/api_resource.rb @@ -114,6 +114,10 @@ def build_fields_params(fields) end end + def me_path + "/me" + end + def profile_path(options={}, allow_multiple=true) path = "/people" diff --git a/lib/linked_in/companies.rb b/lib/linked_in/companies.rb index 424a5bf..517bd9a 100644 --- a/lib/linked_in/companies.rb +++ b/lib/linked_in/companies.rb @@ -23,6 +23,7 @@ class Companies < APIResource # @option options [String] :type # @option options [String] :count # @option options [String] :start + # @option options [String] :profile_fields # @return [LinkedIn::Mash] def company(options = {}) path = company_path(options) @@ -182,7 +183,11 @@ def company_path(options) if domain = options.delete(:domain) path += "?email-domain=#{CGI.escape(domain)}" elsif id = options.delete(:id) - path += "/#{id}" + if profile_fields = options.delete(:profile_fields) + path += "/#{id}:(#{profile_fields})" + else + path += "/#{id}" + end elsif url = options.delete(:url) path += "/url=#{CGI.escape(url)}" elsif name = options.delete(:name) diff --git a/lib/linked_in/configuration.rb b/lib/linked_in/configuration.rb index bb4771d..b903ba2 100644 --- a/lib/linked_in/configuration.rb +++ b/lib/linked_in/configuration.rb @@ -32,7 +32,7 @@ class Configuration def initialize @api = "https://api.linkedin.com" - @api_version = "/v1" + @api_version = "/v2" @site = "https://www.linkedin.com" @token_url = "/uas/oauth2/accessToken" @authorize_url = "/uas/oauth2/authorization" diff --git a/lib/linked_in/organizations.rb b/lib/linked_in/organizations.rb new file mode 100644 index 0000000..cf185e9 --- /dev/null +++ b/lib/linked_in/organizations.rb @@ -0,0 +1,27 @@ +module LinkedIn + + class Organizations < APIResource + + # Retrieves a member's organization access control information + def organization_access(options={}) + path = "/organizationAcls?q=roleAssignee&projection=(elements*(*,organization~(localizedName)))" + get(path, options) + end + + # Retrieves an organization + def organization(options={}) + path = organization_path(options) + get(path, options) + end + + def organization_path(options) + path = "/organizations" + + if id = options.delete(:id) + path += "/#{id}" + end + end + + end + +end diff --git a/lib/linked_in/people.rb b/lib/linked_in/people.rb index 850e241..51ca832 100644 --- a/lib/linked_in/people.rb +++ b/lib/linked_in/people.rb @@ -39,6 +39,11 @@ def profile(id={}, options={}) get(path, options) end + def me(options={}) + path = me_path + get(path, options) + end + # Retrieve a list of 1st degree connections for a user who has # granted access to his/her account # @@ -95,15 +100,6 @@ def skills(id={}, options={}) options = parse_id(id, options) path = "#{profile_path(options, false)}/skills" get(path, options) - end - - - protected ############################################################ - - - def get(path, options) - options[:"secure-urls"] = true unless options[:secure] == false - super path, options end diff --git a/lib/linked_in/share_and_social_stream.rb b/lib/linked_in/share_and_social_stream.rb index c1c1ad7..708f3e8 100644 --- a/lib/linked_in/share_and_social_stream.rb +++ b/lib/linked_in/share_and_social_stream.rb @@ -1,133 +1,34 @@ module LinkedIn - # Share and Social Stream APIs + # Share APIs # - # @see http://developer.linkedin.com/documents/share-and-social-stream - # @see http://developer.linkedin.com/documents/share-api Share API + # @see https://docs.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/share-on-linkedin # - # The following API actions do not have corresponding methods in - # this module - # - # * GET Network Statistics - # * POST Post Network Update - # - # [(contribute here)](https://github.com/emorikawa/linkedin-oauth2) class ShareAndSocialStream < APIResource - # Retrieve the authenticated users network updates - # - # Permissions: rw_nus - # - # @see http://developer.linkedin.com/documents/get-network-updates-and-statistics-api - # @see http://developer.linkedin.com/documents/network-update-types Network Update Types - # - # @macro profile_options - # @option options [String] :scope - # @option options [String] :type - # @option options [String] :count - # @option options [String] :start - # @option options [String] :after - # @option options [String] :before - # @option options [String] :show-hidden-members - # @return [LinkedIn::Mash] - def network_updates(options={}) - path = "#{profile_path(options)}/network/updates" - get(path, options) - end - - # TODO refactor to use #network_updates - def shares(options={}) - path = "#{profile_path(options)}/network/updates" - get(path, {type: "SHAR", scope: "self"}.merge(options)) - end - - def share(update_key, options={}) - path = "#{profile_path(options)}/network/updates/key=#{update_key}" - get(path) - end - - # Retrieve all comments for a particular network update - # - # @note The first 5 comments are included in the response to #network_updates - # - # Permissions: rw_nus - # - # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates - # - # @param [String] update_key a update/update-key representing a - # particular network update - # @macro profile_options - # @return [LinkedIn::Mash] - def share_comments(update_key, options={}) - path = "#{profile_path(options)}/network/updates/key=#{update_key}/update-comments" - get(path, options) - end - - # Retrieve all likes for a particular network update - # - # @note Some likes are included in the response to #network_updates - # - # Permissions: rw_nus + # Create a text share for the authenticated user # - # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates - # - # @param [String] update_key a update/update-key representing a - # particular network update - # @macro profile_options - # @return [LinkedIn::Mash] - def share_likes(update_key, options={}) - path = "#{profile_path(options)}/network/updates/key=#{update_key}/likes" - get(path, options) - end - - # Create a share for the authenticated user - # - # Permissions: rw_nus - # - # @see http://developer.linkedin.com/documents/share-api - # - # @macro share_input_fields - # @return [void] - def add_share(share) - path = "/people/~/shares" - defaults = {visibility: {code: "anyone"}} - post(path, MultiJson.dump(defaults.merge(share)), "Content-Type" => "application/json") - end - - # Create a comment on an update from the authenticated user - # - # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates - # - # @param [String] update_key a update/update-key representing a - # particular network update - # @param [String] comment The text of the comment - # @return [void] - def update_comment(update_key, comment) - path = "/people/~/network/updates/key=#{update_key}/update-comments" - post(path, {comment: comment}) - end - - # (Update) like an update as the authenticated user - # - # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates - # - # @param [String] update_key a update/update-key representing a - # particular network update - # @return [void] - def like_share(update_key) - path = "/people/~/network/updates/key=#{update_key}/is-liked" - put(path, "true") - end - - # (Destroy) unlike an update the authenticated user previously - # liked + # Permissions: w_member_social # - # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates + # @see https://docs.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/share-on-linkedin#create-a-text-share # - # @param [String] update_key a update/update-key representing a - # particular network update # @return [void] - def unlike_share(update_key) - path = "/people/~/network/updates/key=#{update_key}/is-liked" - put(path, "false") + def add_text_share(authorId, text) + path = "/ugcPosts" + params = { + "author" => authorId, + "lifecycleState" => "PUBLISHED", + "specificContent" => { + "com.linkedin.ugc.ShareContent" => { + "shareCommentary" => { + "text" => text + }, + "shareMediaCategory" => "NONE" + } + }, + "visibility" => { + "com.linkedin.ugc.MemberNetworkVisibility" => "PUBLIC" + } + } + post(path, params.to_json, { "Content-Type" => "application/json", "X-Restli-Protocol-Version" => "2.0.0" }) end end end diff --git a/lib/linkedin-oauth2.rb b/lib/linkedin-oauth2.rb index 3cf8a39..5637b3f 100644 --- a/lib/linkedin-oauth2.rb +++ b/lib/linkedin-oauth2.rb @@ -33,6 +33,7 @@ require "linked_in/companies" require "linked_in/communications" require "linked_in/share_and_social_stream" +require "linked_in/organizations" # The primary API object that makes requests. # It composes in all of the endpoints diff --git a/spec/linked_in/api/companies_spec.rb b/spec/linked_in/api/companies_spec.rb index 96b211b..d953ff5 100644 --- a/spec/linked_in/api/companies_spec.rb +++ b/spec/linked_in/api/companies_spec.rb @@ -14,6 +14,11 @@ def stub(url) expect(api.company(id: 1586)).to be_an_instance_of(LinkedIn::Mash) end + it "retrieves a company page with requested profile fields" do + stub("https://api.linkedin.com/v1/companies/1586:(id,name,description,logo-url)?") + expect(api.company(id: 1586, profile_fields: "id,name,description,logo-url")).to be_an_instance_of(LinkedIn::Mash) + end + it "should be able to view a company by universal name" do stub("https://api.linkedin.com/v1/companies/universal-name=acme?") expect(api.company(name: "acme")).to be_an_instance_of(LinkedIn::Mash)