linkedin-api 0.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/linked_in/api/current_user.rb +29 -0
- data/lib/linked_in/api/media.rb +44 -0
- data/lib/linked_in/api/organization.rb +29 -0
- data/lib/linked_in/api/post.rb +112 -0
- data/lib/linked_in/auth/access_token.rb +14 -0
- data/lib/linked_in/auth/client.rb +64 -0
- data/lib/linked_in/configuration.rb +25 -0
- data/lib/linked_in/errors.rb +43 -0
- data/lib/linked_in/http_client.rb +85 -0
- data/lib/linked_in/middleware/raise_error.rb +30 -0
- data/lib/linked_in/version.rb +5 -0
- data/lib/linked_in.rb +23 -0
- metadata +137 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 93d087170b8192f65f736e4c4372591df800da4e41fff2dde3e33673cc3e364a
|
|
4
|
+
data.tar.gz: a40a61cabd1006e165050c547713912779f1ac8b7d76f8432e2a14dc4f6a9b5a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 41eecf64b4c967af66c5275d941c3c6912efe496fd2edbd1ba5dbe2e4b3f4935eaa3fddd7bf37c2a43d63dc63f57de8f570d7824aa8ce5ccfd358c2419453d7a
|
|
7
|
+
data.tar.gz: 01e4686bac59ccaa6ef956110801fcbc3bfc0d1b319b9d3033efe019674a59a81bbc7f96a58a398cd61c2131bfd866ececc03d7f43d767d06968d0fe3ee73793
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedIn
|
|
4
|
+
module API
|
|
5
|
+
class CurrentUser
|
|
6
|
+
attr_reader :client
|
|
7
|
+
|
|
8
|
+
LOCATION_URN_PREFIX = 'urn:li:standardizedLocationKey'
|
|
9
|
+
|
|
10
|
+
def initialize(client)
|
|
11
|
+
@client = client
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def me
|
|
15
|
+
client.get('v2/me', projection: '(*,profilePicture(displayImage~:playableStreams))')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def email
|
|
19
|
+
client.get('v2/emailAddress', q: 'members', projection: '(elements*(handle~))')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def location(urn)
|
|
23
|
+
return unless urn.start_with?(LOCATION_URN_PREFIX)
|
|
24
|
+
|
|
25
|
+
client.get('v2/regions', q: 'standardizedLocation', standardizedLocation: urn)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'open-uri'
|
|
4
|
+
|
|
5
|
+
module LinkedIn
|
|
6
|
+
module API
|
|
7
|
+
class Media
|
|
8
|
+
TYPES = { 'image/png': '.png', 'image/jpeg': '.jpeg' }.freeze
|
|
9
|
+
attr_reader :client
|
|
10
|
+
|
|
11
|
+
def initialize(client)
|
|
12
|
+
@client = client
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def upload(image_url, organization_id)
|
|
16
|
+
image = URI.open(image_url)
|
|
17
|
+
type = image.content_type
|
|
18
|
+
raise "Unexpected content type: '#{type}'" unless TYPES.key?(type.to_sym)
|
|
19
|
+
|
|
20
|
+
response = image_register(organization_id)
|
|
21
|
+
client.media_upload(response[:uploadUrl], image, filename(image))
|
|
22
|
+
response
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def image_register(organization_id)
|
|
28
|
+
body = {
|
|
29
|
+
initializeUploadRequest: {
|
|
30
|
+
owner: "urn:li:organization:#{organization_id}",
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
response = client.post('rest/images?action=initializeUpload', body)
|
|
34
|
+
response.dig(:value)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def filename(media)
|
|
38
|
+
filename = File.basename(media.base_uri.to_s)
|
|
39
|
+
filename += TYPES[media.content_type.to_sym] unless filename.match?('\.(jpg|jpeg|png)')
|
|
40
|
+
filename
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedIn
|
|
4
|
+
module API
|
|
5
|
+
class Organization
|
|
6
|
+
attr_reader :client
|
|
7
|
+
|
|
8
|
+
def initialize(client)
|
|
9
|
+
@client = client
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def organizations
|
|
13
|
+
client.get('rest/organizationAcls?q=roleAssignee&count=50')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def organization(id)
|
|
17
|
+
client.get("rest/organizations/#{id}")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def organization_statistics(urn)
|
|
21
|
+
client.get("rest/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=#{urn}")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def organization_network_size(id)
|
|
25
|
+
client.get("rest/networkSizes/urn:li:organization:#{id}", edgeType: 'COMPANY_FOLLOWED_BY_MEMBER')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedIn
|
|
4
|
+
module API
|
|
5
|
+
class Post
|
|
6
|
+
attr_reader :client, :media, :logger
|
|
7
|
+
|
|
8
|
+
def initialize(client, media, logger=nil)
|
|
9
|
+
@client = client
|
|
10
|
+
@media = media
|
|
11
|
+
@logger = logger
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create(organization_id, share_data)
|
|
15
|
+
share = Hashie::Mash.new(share_data)
|
|
16
|
+
post = create_post(content(share, organization_id), organization_id).to_json
|
|
17
|
+
client.post('rest/posts', post)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def social_summary(id)
|
|
21
|
+
get_post_summary(id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def likes_summary(id)
|
|
25
|
+
get_post_summary(id, '(likesSummary)')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def comments_summary(id)
|
|
29
|
+
get_post_summary(id, '(commentsSummary)')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def content(share, organization_id)
|
|
35
|
+
comment = comment_content(share.comment)
|
|
36
|
+
content = image_content(share.content, organization_id) || {}
|
|
37
|
+
compact(comment.deep_merge!(content))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def create_post(content, organization_id)
|
|
41
|
+
payload = Hashie::Mash.new(
|
|
42
|
+
author: "urn:li:organization:#{organization_id}",
|
|
43
|
+
lifecycleState: 'PUBLISHED',
|
|
44
|
+
visibility: 'PUBLIC',
|
|
45
|
+
isReshareDisabledByAuthor: false,
|
|
46
|
+
distribution: {
|
|
47
|
+
feedDistribution: "MAIN_FEED",
|
|
48
|
+
targetEntities: [],
|
|
49
|
+
thirdPartyDistributionChannels: [],
|
|
50
|
+
},
|
|
51
|
+
).deep_merge!(content)
|
|
52
|
+
|
|
53
|
+
logger&.debug(msg: "## PAYLOAD -> ", payload: payload.to_json)
|
|
54
|
+
payload
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def comment_content(comment)
|
|
58
|
+
Hashie::Mash.new(
|
|
59
|
+
commentary: escape_characters(comment)
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
##
|
|
64
|
+
# The api from 2023-02 has some special characters and underscore is one of them that not works as expected on links
|
|
65
|
+
#
|
|
66
|
+
# @link https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/little-text-format?view=li-lms-2023-02#text
|
|
67
|
+
#
|
|
68
|
+
#
|
|
69
|
+
def escape_characters(comment)
|
|
70
|
+
replacements = {
|
|
71
|
+
'_' => '\\_',
|
|
72
|
+
'~' => '\\~',
|
|
73
|
+
'*' => '\\*',
|
|
74
|
+
'[' => '\\[',
|
|
75
|
+
']' => '\\]',
|
|
76
|
+
'(' => '\\(',
|
|
77
|
+
')' => '\\)',
|
|
78
|
+
'{' => '\\{',
|
|
79
|
+
'}' => '\\}',
|
|
80
|
+
'|' => '\\|',
|
|
81
|
+
'#' => '\\#',
|
|
82
|
+
'@' => '\\@',
|
|
83
|
+
'>' => '\\>',
|
|
84
|
+
'<' => '\\<',
|
|
85
|
+
'\\' => '\\\\'
|
|
86
|
+
}
|
|
87
|
+
comment.to_s.gsub(/[\_\~\*\[\]\(\)\{\}\|\#\@\>\<\\]/, replacements)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def image_content(content, organization_id)
|
|
91
|
+
image_url = content&.dig(:"submitted-image-url") || ''
|
|
92
|
+
return if image_url.empty?
|
|
93
|
+
|
|
94
|
+
image = @media.upload(image_url, organization_id)
|
|
95
|
+
{
|
|
96
|
+
content: {
|
|
97
|
+
media: compact(id: image[:image]),
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def compact(hash)
|
|
103
|
+
hash.delete_if { |_k, value| value.is_a?(Hash) ? compact(value).empty? : value.nil? }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def get_post_summary(id, projection = {})
|
|
107
|
+
options = { projection: projection } unless projection.empty?
|
|
108
|
+
client.get("v2/socialActions/" + URI.encode_www_form_component("urn:li:share:#{id}"), options || {})
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedIn
|
|
4
|
+
module Auth
|
|
5
|
+
class AccessToken
|
|
6
|
+
attr_reader :token, :expires_in
|
|
7
|
+
|
|
8
|
+
def initialize(attrs = {})
|
|
9
|
+
@token = attrs.delete('access_token')
|
|
10
|
+
@expires_in = attrs.delete('expires_in')
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'securerandom'
|
|
5
|
+
require 'faraday_middleware'
|
|
6
|
+
|
|
7
|
+
require 'linked_in/middleware/raise_error'
|
|
8
|
+
require 'linked_in/auth/access_token'
|
|
9
|
+
|
|
10
|
+
module LinkedIn
|
|
11
|
+
module Auth
|
|
12
|
+
class Client
|
|
13
|
+
def initialize(state = SecureRandom.hex, config = LinkedIn.config)
|
|
14
|
+
@state = state
|
|
15
|
+
@config = config
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def authorize_url
|
|
19
|
+
params = authorize_url_params.merge(state: @state)
|
|
20
|
+
connection.build_url(config.authorize_url, params).to_s
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def access_token(code, state = nil)
|
|
24
|
+
raise LinkedIn::InvalidRequestError if code.nil?
|
|
25
|
+
|
|
26
|
+
params = access_token_params.merge(code: code, state: state)
|
|
27
|
+
response = connection.post(config.token_url, params)
|
|
28
|
+
|
|
29
|
+
Auth::AccessToken.new(response.body)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
attr_reader :config
|
|
35
|
+
|
|
36
|
+
def connection
|
|
37
|
+
@connection ||= Faraday.new(config.site) do |conn|
|
|
38
|
+
conn.use LinkedIn::Middleware::RaiseError
|
|
39
|
+
conn.request :url_encoded
|
|
40
|
+
conn.response :json, content_type: /\bjson$/
|
|
41
|
+
conn.adapter Faraday.default_adapter
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def authorize_url_params
|
|
46
|
+
{
|
|
47
|
+
scope: config.scope,
|
|
48
|
+
response_type: :code,
|
|
49
|
+
client_id: config.client_id,
|
|
50
|
+
redirect_uri: config.redirect_uri,
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def access_token_params
|
|
55
|
+
{
|
|
56
|
+
client_id: config.client_id,
|
|
57
|
+
client_secret: config.client_secret,
|
|
58
|
+
redirect_uri: config.redirect_uri,
|
|
59
|
+
grant_type: :authorization_code,
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedIn
|
|
4
|
+
class Configuration
|
|
5
|
+
FIELDS = {
|
|
6
|
+
site: 'https://www.linkedin.com',
|
|
7
|
+
scope: nil,
|
|
8
|
+
client_id: nil,
|
|
9
|
+
client_secret: nil,
|
|
10
|
+
redirect_uri: nil,
|
|
11
|
+
token_url: '/oauth/v2/accessToken',
|
|
12
|
+
authorize_url: '/oauth/v2/authorization',
|
|
13
|
+
}.freeze
|
|
14
|
+
|
|
15
|
+
FIELDS.each do |name, default_value|
|
|
16
|
+
define_method(name) do
|
|
17
|
+
instance_variable_get("@#{name}") || default_value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
define_method("#{name}=") do |value|
|
|
21
|
+
instance_variable_set("@#{name}", value)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LinkedIn
|
|
4
|
+
class APIError < RuntimeError
|
|
5
|
+
def initialize(response = nil)
|
|
6
|
+
@response = response
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def http_status
|
|
10
|
+
response&.status
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def http_headers
|
|
14
|
+
response&.headers
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def http_body
|
|
18
|
+
response&.body
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def message
|
|
22
|
+
return super() unless response
|
|
23
|
+
|
|
24
|
+
"#{self.class} - #{http_status}: #{http_body}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
attr_reader :response
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class InvalidRequestError < APIError; end
|
|
33
|
+
|
|
34
|
+
class UnauthorizedError < APIError; end
|
|
35
|
+
|
|
36
|
+
class AccessDeniedError < APIError; end
|
|
37
|
+
|
|
38
|
+
class NotFoundError < APIError; end
|
|
39
|
+
|
|
40
|
+
class InformLinkedInError < APIError; end
|
|
41
|
+
|
|
42
|
+
class UnavailableError < APIError; end
|
|
43
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'faraday_middleware'
|
|
5
|
+
require 'linked_in/middleware/raise_error'
|
|
6
|
+
|
|
7
|
+
module LinkedIn
|
|
8
|
+
class HTTPClient
|
|
9
|
+
BASE_URL = 'https://api.linkedin.com/'
|
|
10
|
+
LINKEDIN_VERSION_API = '202511'
|
|
11
|
+
HEADER_RESTLI_PROTOCOL = '2.0.0'
|
|
12
|
+
|
|
13
|
+
attr_reader :json_client, :multipart_client, :protocol, :debug_mode
|
|
14
|
+
|
|
15
|
+
def initialize(access_token:, protocol: true, debug_mode: false)
|
|
16
|
+
@protocol = protocol
|
|
17
|
+
@json_client = build_client(access_token, BASE_URL, :json)
|
|
18
|
+
@multipart_client = build_client(access_token, BASE_URL, :multipart)
|
|
19
|
+
@debug_mode = debug_mode
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get(path, params = {}, headers = {})
|
|
23
|
+
response = json_client.get(path, params, headers)
|
|
24
|
+
to_result(response)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def post(path, body = {})
|
|
28
|
+
response = json_client.post(path, body)
|
|
29
|
+
to_result(response)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def register_upload(path, body)
|
|
33
|
+
post(path, body)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def media_upload(path, media, filename)
|
|
37
|
+
header_media_content(multipart_client, media)
|
|
38
|
+
content = Faraday::UploadIO.new(media, media.content_type, filename)
|
|
39
|
+
|
|
40
|
+
response = multipart_client.put(path, content)
|
|
41
|
+
response
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def header_media_content(client, media)
|
|
47
|
+
client.headers["Content-Type"] = media.content_type
|
|
48
|
+
client.headers['Content-Length'] = media.length.to_s
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_result(response)
|
|
52
|
+
unless response.body.empty?
|
|
53
|
+
body = response.body.is_a?(Hash) ? response.body : JSON.parse(response.body)
|
|
54
|
+
|
|
55
|
+
return Hashie::Mash.new(response.body)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
Hashie::Mash.new(
|
|
59
|
+
'id': response.headers['x-restli-id'],
|
|
60
|
+
'x-li-uuid': response.headers['x-li-uuid']
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def build_client(access_token, url, type)
|
|
65
|
+
Faraday.new(url: url) do |builder|
|
|
66
|
+
builder.authorization('Bearer', access_token)
|
|
67
|
+
builder.request type
|
|
68
|
+
builder.use Faraday::Request::UrlEncoded
|
|
69
|
+
builder.use LinkedIn::Middleware::RaiseError
|
|
70
|
+
builder.use FaradayMiddleware::ParseJson, content_type: /\bjson$/
|
|
71
|
+
builder.adapter :net_http
|
|
72
|
+
|
|
73
|
+
# @link https://learn.microsoft.com/en-us/linkedin/marketing/versioning?view=li-lms-unversioned
|
|
74
|
+
builder.headers['LinkedIn-Version'] = LINKEDIN_VERSION_API
|
|
75
|
+
builder.headers['X-Restli-Protocol-Version'] = HEADER_RESTLI_PROTOCOL if protocol?
|
|
76
|
+
|
|
77
|
+
builder.response :logger, nil, { headers: true, bodies: true, errors: true }
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def protocol?
|
|
82
|
+
protocol
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'linked_in/errors'
|
|
4
|
+
|
|
5
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
6
|
+
module LinkedIn
|
|
7
|
+
module Middleware
|
|
8
|
+
class RaiseError < Faraday::Response::RaiseError
|
|
9
|
+
def on_complete(env)
|
|
10
|
+
response = env.response
|
|
11
|
+
case response.status
|
|
12
|
+
when 400
|
|
13
|
+
raise LinkedIn::InvalidRequestError, response
|
|
14
|
+
when 401
|
|
15
|
+
raise LinkedIn::UnauthorizedError, response
|
|
16
|
+
when 403
|
|
17
|
+
raise LinkedIn::AccessDeniedError, response
|
|
18
|
+
when 404
|
|
19
|
+
raise LinkedIn::NotFoundError, response
|
|
20
|
+
when 500
|
|
21
|
+
raise LinkedIn::InformLinkedInError, response
|
|
22
|
+
when 502..503
|
|
23
|
+
raise LinkedIn::UnavailableError, response
|
|
24
|
+
else
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/linked_in.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'hashie'
|
|
4
|
+
require 'linked_in/version'
|
|
5
|
+
require 'linked_in/http_client'
|
|
6
|
+
require 'linked_in/auth/client'
|
|
7
|
+
require 'linked_in/api/organization'
|
|
8
|
+
require 'linked_in/api/media'
|
|
9
|
+
require 'linked_in/api/post'
|
|
10
|
+
require 'linked_in/api/current_user'
|
|
11
|
+
require 'linked_in/configuration'
|
|
12
|
+
|
|
13
|
+
module LinkedIn
|
|
14
|
+
class << self
|
|
15
|
+
def setup
|
|
16
|
+
yield config
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def config
|
|
20
|
+
@config ||= Configuration.new
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: linkedin-api
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.8.9
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- LeadGen Team
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2025-12-02 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: faraday
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.17'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.17'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: faraday_middleware
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.13'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.13'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: hashie
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.5'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.5'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: bundler
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '2.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '2.0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rake
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rexml
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
description: A gem to use LinkedIn API
|
|
98
|
+
email: leadgen@resultadosdigitais.com.br
|
|
99
|
+
executables: []
|
|
100
|
+
extensions: []
|
|
101
|
+
extra_rdoc_files: []
|
|
102
|
+
files:
|
|
103
|
+
- lib/linked_in.rb
|
|
104
|
+
- lib/linked_in/api/current_user.rb
|
|
105
|
+
- lib/linked_in/api/media.rb
|
|
106
|
+
- lib/linked_in/api/organization.rb
|
|
107
|
+
- lib/linked_in/api/post.rb
|
|
108
|
+
- lib/linked_in/auth/access_token.rb
|
|
109
|
+
- lib/linked_in/auth/client.rb
|
|
110
|
+
- lib/linked_in/configuration.rb
|
|
111
|
+
- lib/linked_in/errors.rb
|
|
112
|
+
- lib/linked_in/http_client.rb
|
|
113
|
+
- lib/linked_in/middleware/raise_error.rb
|
|
114
|
+
- lib/linked_in/version.rb
|
|
115
|
+
homepage: https://github.com/ResultadosDigitais/linkedin
|
|
116
|
+
licenses: []
|
|
117
|
+
metadata: {}
|
|
118
|
+
post_install_message:
|
|
119
|
+
rdoc_options: []
|
|
120
|
+
require_paths:
|
|
121
|
+
- lib
|
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
|
+
requirements:
|
|
124
|
+
- - ">="
|
|
125
|
+
- !ruby/object:Gem::Version
|
|
126
|
+
version: '3.0'
|
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
requirements: []
|
|
133
|
+
rubygems_version: 3.4.20
|
|
134
|
+
signing_key:
|
|
135
|
+
specification_version: 4
|
|
136
|
+
summary: A gem to use LinkedIn API
|
|
137
|
+
test_files: []
|