tomba 1.0.0 → 1.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14fc88b877a55b993f2d26a344212ba05c3e95caecc23c544340c33938a0cc2b
4
- data.tar.gz: 3c083ee97a506e80b081dd8c1316bf396e5f0f6f445d402cb70d0c40d82a2e63
3
+ metadata.gz: 5fff8329f928fffbfda42060021c557a64940a0234e8ac4378acca4c97deb1aa
4
+ data.tar.gz: e5989ccb45131269458d65b796fd3bfe048b8358a1de622d6b349c158805506c
5
5
  SHA512:
6
- metadata.gz: 79fa611ff51ae93ff978c716e9461e0a8677889fd0b880deac9ee75af5b76d11f7c4719fcb5427cdbdffd956310dd6a7d62a267d76514d17a9937f8d68b8bf1b
7
- data.tar.gz: 47132687b7c2f5788bc1aafc47c0ad1318d9e1d69231323509bdceb1322fe1cf68966c72050d8d847a78ab51a26c41b520aa78fb6f6efbe604e92992837f0493
6
+ metadata.gz: 717b6282a840d73850339e169e7e4ee5a6dc05895437f03399ed661d485f41cf90054deaa150ea22f23b3868f651125de784491499570f78a064bdd3687095ba
7
+ data.tar.gz: c79081d69394733d89c575b7efb4fcf390d06489e62965fe8df85b0981935b4a61cec2be77f70eefe7166b0e1fa81fd1a7b48364c8a5ea9dd6ad665d8e7aa6ae
data/lib/tomba/client.rb CHANGED
@@ -1,122 +1,136 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'net/http'
2
4
  require 'uri'
3
5
  require 'json'
4
6
  require 'cgi'
5
7
 
6
8
  module Tomba
7
- class Client
9
+ class Client
10
+ METHOD_GET = 'get'
11
+ METHOD_POST = 'post'
12
+ METHOD_PUT = 'put'
13
+ METHOD_PATCH = 'patch'
14
+ METHOD_DELETE = 'delete'
15
+ METHOD_HEAD = 'head'
16
+ METHOD_OPTIONS = 'options'
17
+ METHOD_CONNECT = 'connect'
18
+ METHOD_TRACE = 'trace'
19
+
20
+ def initialize
21
+ @headers = {
22
+ 'content-type' => '',
23
+ 'user-agent' => "#{RUBY_PLATFORM}:ruby-#{RUBY_VERSION}",
24
+ 'x-sdk-version' => "tomba:ruby:v#{Tomba::VERSION}"
25
+
26
+ }
27
+ @endpoint = 'https://api.tomba.io/v1'
28
+ end
29
+
30
+ def set_key(value)
31
+ add_header('x-tomba-key', value)
32
+
33
+ self
34
+ end
35
+
36
+ def set_secret(value)
37
+ add_header('x-tomba-secret', value)
38
+
39
+ self
40
+ end
41
+
42
+ def set_endpoint(endpoint)
43
+ @endpoint = endpoint
44
+
45
+ self
46
+ end
47
+
48
+ def add_header(key, value)
49
+ @headers[key.downcase] = value
50
+
51
+ self
52
+ end
53
+
54
+ def call(method, path = '', headers = {}, params = {})
55
+ uri = URI.parse(@endpoint + path + (method == METHOD_GET && params.length ? "?#{encode(params)}" : ''))
56
+ fetch(method, uri, headers, params)
57
+ end
58
+
59
+ private
60
+
61
+ def fetch(method, uri, headers, params, limit = 5)
62
+ raise ArgumentError, 'Too Many HTTP Redirects' if limit.zero?
63
+
64
+ http = Net::HTTP.new(uri.host, uri.port)
65
+ http.use_ssl = (uri.scheme == 'https')
66
+ http.read_timeout = 120
67
+ http.open_timeout = 120
68
+ payload = ''
69
+
70
+ headers = @headers.merge(headers)
71
+ @boundary = '----A30#3ad1'
72
+ if method != METHOD_GET
73
+ payload = case headers['content-type'][0,
74
+ headers['content-type'].index(';') || headers['content-type'].length]
75
+ when 'application/json'
76
+ params.to_json
77
+ else
78
+ encode(params)
79
+ end
80
+ end
81
+
82
+ begin
83
+ response = http.send_request(method.upcase, uri.request_uri, payload, headers)
84
+ rescue StandardError => e
85
+ raise Tomba::Exception, e.message
86
+ end
87
+
88
+ # Handle Redirects
89
+ if response.instance_of?(Net::HTTPRedirection) || response.instance_of?(Net::HTTPMovedPermanently)
90
+ location = response['location']
91
+ uri = URI.parse("#{uri.scheme}://#{uri.host}#{location}")
92
+
93
+ return fetch(method, uri, headers, {}, limit - 1)
94
+ end
95
+
96
+ begin
97
+ res = JSON.parse(response.body)
98
+ rescue JSON::ParserError
99
+ raise Tomba::Exception.new(response.body, response.code, nil)
100
+ end
101
+
102
+ raise Tomba::Exception.new(res['errors']['message'], res['errors']['code'], res) if response.code.to_i >= 400
103
+
104
+ { 'data' => res, 'rate_limit' => parse_rate_limit(response) }
105
+ end
106
+
107
+ def parse_rate_limit(response)
108
+ {
109
+ 'x-second-rate-limit' => response['x-second-rate-limit']&.to_i,
110
+ 'x-minute-rate-limit' => response['x-minute-rate-limit']&.to_i,
111
+ 'x-daily-rate-limit' => response['x-daily-rate-limit']&.to_i,
112
+ 'x-minute-request-left' => response['x-minute-request-left']&.to_i,
113
+ 'x-daily-request-left' => response['x-daily-request-left']&.to_i,
114
+ 'x-minute-reset-seconds' => response['x-minute-reset-seconds']&.to_i,
115
+ 'x-daily-reset-seconds' => response['x-daily-reset-seconds']&.to_i,
116
+ 'retry-after' => response['retry-after']&.to_i,
117
+ 'ratelimit-policy' => response['ratelimit-policy'],
118
+ 'ratelimit' => response['ratelimit']
119
+ }
120
+ end
121
+
122
+ def encode(value, key = nil)
123
+ case value
124
+ when Hash then value.map { |k, v| encode(v, append_key(key, k)) }.join('&')
125
+ when Array then value.map { |v| encode(v, "#{key}[]") }.join('&')
126
+ when nil then ''
127
+ else
128
+ "#{key}=#{CGI.escape(value.to_s)}"
129
+ end
130
+ end
8
131
 
9
- METHOD_GET = 'get'
10
- METHOD_POST = 'post'
11
- METHOD_PUT = 'put'
12
- METHOD_PATCH = 'patch'
13
- METHOD_DELETE = 'delete'
14
- METHOD_HEAD = 'head'
15
- METHOD_OPTIONS = 'options'
16
- METHOD_CONNECT = 'connect'
17
- METHOD_TRACE = 'trace'
18
-
19
- def initialize()
20
- @headers = {
21
- 'content-type' => '',
22
- 'user-agent' => RUBY_PLATFORM + ':ruby-' + RUBY_VERSION,
23
- 'x-sdk-version' => 'tomba:ruby:v1.0.0'
24
-
25
- }
26
- @endpoint = 'https://api.tomba.io/v1';
27
- end
28
-
29
- def set_key(value)
30
- add_header('x-tomba-key', value)
31
-
32
- return self
33
- end
34
-
35
- def set_secret(value)
36
- add_header('x-tomba-secret', value)
37
-
38
- return self
39
- end
40
-
41
- def set_endpoint(endpoint)
42
- @endpoint = endpoint
43
-
44
- return self
45
- end
46
-
47
- def add_header(key, value)
48
- @headers[key.downcase] = value
49
-
50
- return self
51
- end
52
-
53
- def call(method, path = '', headers = {}, params = {})
54
- uri = URI.parse(@endpoint + path + ((method == METHOD_GET && params.length) ? '?' + encode(params) : ''))
55
- return fetch(method, uri, headers, params)
56
- end
57
-
58
- protected
59
-
60
- private
61
-
62
- def fetch(method, uri, headers, params, limit = 5)
63
- raise ArgumentError, 'Too Many HTTP Redirects' if limit == 0
64
-
65
- http = Net::HTTP.new(uri.host, uri.port)
66
- http.use_ssl = (uri.scheme == 'https')
67
- payload = ''
68
-
69
- headers = @headers.merge(headers)
70
- @BOUNDARY = "----A30#3ad1"
71
- if (method != METHOD_GET)
72
- case headers['content-type'][0, headers['content-type'].index(';') || headers['content-type'].length]
73
- when 'application/json'
74
- payload = params.to_json
75
- else
76
- payload = encode(params)
77
- end
78
- end
79
-
80
- begin
81
- response = http.send_request(method.upcase, uri.request_uri, payload, headers)
82
- rescue => error
83
- raise Tomba::Exception.new(error.message)
84
- end
85
-
86
- # Handle Redirects
87
- if (response.class == Net::HTTPRedirection || response.class == Net::HTTPMovedPermanently)
88
- location = response['location']
89
- uri = URI.parse(uri.scheme + "://" + uri.host + "" + location)
90
-
91
- return fetch(method, uri, headers, {}, limit - 1)
92
- end
93
-
94
- begin
95
- res = JSON.parse(response.body);
96
- rescue JSON::ParserError => e
97
- raise Tomba::Exception.new(response.body, response.code, nil)
98
- end
99
-
100
- if(response.code.to_i >= 400)
101
- raise Tomba::Exception.new(res['errors']['message'], res['errors']['code'], res)
102
- end
103
-
104
- return res;
105
- end
106
-
107
-
108
- def encode(value, key = nil)
109
- case value
110
- when Hash then value.map { |k,v| encode(v, append_key(key,k)) }.join('&')
111
- when Array then value.map { |v| encode(v, "#{key}[]") }.join('&')
112
- when nil then ''
113
- else
114
- "#{key}=#{CGI.escape(value.to_s)}"
115
- end
116
- end
117
-
118
- def append_key(root_key, key)
119
- root_key.nil? ? key : "#{root_key}[#{key.to_s}]"
120
- end
132
+ def append_key(root_key, key)
133
+ root_key.nil? ? key : "#{root_key}[#{key}]"
121
134
  end
135
+ end
122
136
  end
@@ -1,14 +1,23 @@
1
- module Tomba
2
- class Exception < StandardError
3
- @code = 0;
4
- @response = nil;
1
+ # frozen_string_literal: true
5
2
 
6
- def initialize(message, code, response)
7
- super(message)
8
- @code = code
9
- @response = response
10
- end
11
- attr_reader :code
12
- attr_reader :response
3
+ module Tomba
4
+ # Custom exception class for Tomba API errors.
5
+ #
6
+ # Raised when the API returns an error response or when
7
+ # required parameters are missing.
8
+ #
9
+ # @attr_reader code [Integer, nil] the HTTP status code or error code
10
+ # @attr_reader response [Hash, nil] the full error response body
11
+ class Exception < StandardError
12
+ # @param message [String] the error message
13
+ # @param code [Integer, nil] the HTTP status code or error code
14
+ # @param response [Hash, nil] the full error response body
15
+ def initialize(message, code = nil, response = nil)
16
+ super(message)
17
+ @code = code
18
+ @response = response
13
19
  end
20
+
21
+ attr_reader :code, :response
22
+ end
14
23
  end
data/lib/tomba/service.rb CHANGED
@@ -1,12 +1,16 @@
1
- module Tomba
2
- class Service
3
-
4
- def initialize(client)
5
- @client = client
6
- end
7
-
8
- protected
1
+ # frozen_string_literal: true
9
2
 
10
- private
11
- end
12
- end
3
+ module Tomba
4
+ # Base service class.
5
+ #
6
+ # All Tomba service classes inherit from this base class,
7
+ # which provides access to the API client.
8
+ class Service
9
+ # Initialize the service with a Tomba client.
10
+ #
11
+ # @param client [Tomba::Client] the API client instance
12
+ def initialize(client)
13
+ @client = client
14
+ end
15
+ end
16
+ end
@@ -1,19 +1,27 @@
1
- module Tomba
2
- class Account < Service
3
-
4
- def get_account()
5
- path = '/me'
6
-
7
- params = {}
8
-
9
- return @client.call('get', path, {
10
- 'content-type' => 'application/json',
11
- }, params);
12
- end
1
+ # frozen_string_literal: true
13
2
 
3
+ module Tomba
4
+ # Account service for retrieving account information.
5
+ #
6
+ # Provides methods to get the current account details.
7
+ #
8
+ # @see https://docs.tomba.io/api/account
9
+ class Account < Service
10
+ # Get Account
11
+ #
12
+ # Returns information about the current account.
13
+ #
14
+ # @see https://docs.tomba.io/api/account#get-account
15
+ # @return [Hash] API response containing account details
16
+ # @raise [Tomba::Exception]
17
+ def get_account
18
+ path = '/me'
14
19
 
15
- protected
20
+ params = {}
16
21
 
17
- private
18
- end
19
- end
22
+ @client.call('get', path, {
23
+ 'content-type' => 'application/json'
24
+ }, params)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,235 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tomba
4
+ # Bulk service for managing bulk operations.
5
+ #
6
+ # Provides methods to list, get, create, launch, delete, archive,
7
+ # rename, check progress, and download bulk tasks.
8
+ #
9
+ # @see https://docs.tomba.io/api/bulk
10
+ class Bulk < Service
11
+ VALID_TYPES = %w[search similar company finder enrich linkedin author verifier phone-finder phone-validator].freeze
12
+
13
+ # Validate the bulk type parameter.
14
+ #
15
+ # @param type [String] the bulk type to validate
16
+ # @raise [Tomba::Exception] if the type is not valid
17
+ def validate_type(type)
18
+ return if VALID_TYPES.include?(type)
19
+
20
+ raise Tomba::Exception, "Invalid bulk type: \"#{type}\". Must be one of: #{VALID_TYPES.join(', ')}"
21
+ end
22
+
23
+ # List Bulk Tasks
24
+ #
25
+ # Returns a list of bulk tasks of the specified type.
26
+ #
27
+ # @see https://docs.tomba.io/api/bulks-tasks
28
+ # @param type [String] the bulk task type (e.g., "searches", "verifiers")
29
+ # @param params [Hash] optional query parameters for filtering
30
+ # @return [Hash] API response containing the list of bulk tasks
31
+ # @raise [Tomba::Exception]
32
+ def list(type, params: {})
33
+ raise Tomba::Exception, 'Missing required parameter: "type"' if type.nil?
34
+
35
+ validate_type(type)
36
+
37
+ path = "/bulk/#{type}"
38
+
39
+ @client.call('get', path, {
40
+ 'content-type' => 'application/json'
41
+ }, params)
42
+ end
43
+
44
+ # Get Bulk Task
45
+ #
46
+ # Returns a specific bulk task by type and ID.
47
+ #
48
+ # @see https://docs.tomba.io/api/bulk#get-bulk-task
49
+ # @param type [String] the bulk task type
50
+ # @param id [String] the bulk task ID
51
+ # @return [Hash] API response containing the bulk task data
52
+ # @raise [Tomba::Exception]
53
+ def get(type, id)
54
+ raise Tomba::Exception, 'Missing required parameter: "type"' if type.nil?
55
+
56
+ validate_type(type)
57
+ raise Tomba::Exception, 'Missing required parameter: "id"' if id.nil?
58
+
59
+ path = "/bulk/#{type}/#{id}"
60
+
61
+ params = {}
62
+
63
+ @client.call('get', path, {
64
+ 'content-type' => 'application/json'
65
+ }, params)
66
+ end
67
+
68
+ # Create Bulk Task
69
+ #
70
+ # Creates a new bulk task of the specified type.
71
+ #
72
+ # @see https://docs.tomba.io/api/bulk-task
73
+ # @param type [String] the bulk task type
74
+ # @param data [Hash] the bulk task data
75
+ # @return [Hash] API response containing the created bulk task
76
+ # @raise [Tomba::Exception]
77
+ def create(type, data)
78
+ raise Tomba::Exception, 'Missing required parameter: "type"' if type.nil?
79
+
80
+ validate_type(type)
81
+
82
+ path = "/bulk/#{type}"
83
+
84
+ @client.call('post', path, {
85
+ 'content-type' => 'application/json'
86
+ }, data)
87
+ end
88
+
89
+ # Launch Bulk Task
90
+ #
91
+ # Launches (starts) a bulk task by type and ID.
92
+ #
93
+ # @see https://docs.tomba.io/api/bulk-task
94
+ # @param type [String] the bulk task type
95
+ # @param id [String] the bulk task ID
96
+ # @return [Hash] API response
97
+ # @raise [Tomba::Exception]
98
+ def launch(type, id)
99
+ raise Tomba::Exception, 'Missing required parameter: "type"' if type.nil?
100
+
101
+ validate_type(type)
102
+ raise Tomba::Exception, 'Missing required parameter: "id"' if id.nil?
103
+
104
+ path = "/bulk/#{type}/#{id}/launch"
105
+
106
+ params = {}
107
+
108
+ @client.call('post', path, {
109
+ 'content-type' => 'application/json'
110
+ }, params)
111
+ end
112
+
113
+ # Delete Bulk Task
114
+ #
115
+ # Deletes a bulk task by type and ID.
116
+ #
117
+ # @see https://docs.tomba.io/api/bulk-task
118
+ # @param type [String] the bulk task type
119
+ # @param id [String] the bulk task ID
120
+ # @return [Hash] API response
121
+ # @raise [Tomba::Exception]
122
+ def delete(type, id)
123
+ raise Tomba::Exception, 'Missing required parameter: "type"' if type.nil?
124
+
125
+ validate_type(type)
126
+ raise Tomba::Exception, 'Missing required parameter: "id"' if id.nil?
127
+
128
+ path = "/bulk/#{type}/#{id}"
129
+
130
+ params = {}
131
+
132
+ @client.call('delete', path, {
133
+ 'content-type' => 'application/json'
134
+ }, params)
135
+ end
136
+
137
+ # Archive Bulk Task
138
+ #
139
+ # Archives a bulk task by type and ID.
140
+ #
141
+ # @see https://docs.tomba.io/api/bulk-task
142
+ # @param type [String] the bulk task type
143
+ # @param id [String] the bulk task ID
144
+ # @return [Hash] API response
145
+ # @raise [Tomba::Exception]
146
+ def archive(type, id)
147
+ raise Tomba::Exception, 'Missing required parameter: "type"' if type.nil?
148
+
149
+ validate_type(type)
150
+ raise Tomba::Exception, 'Missing required parameter: "id"' if id.nil?
151
+
152
+ path = "/bulk/#{type}/#{id}/archive"
153
+
154
+ params = {}
155
+
156
+ @client.call('post', path, {
157
+ 'content-type' => 'application/json'
158
+ }, params)
159
+ end
160
+
161
+ # Rename Bulk Task
162
+ #
163
+ # Renames a bulk task by type and ID.
164
+ #
165
+ # @see https://docs.tomba.io/api/bulk-task
166
+ # @param type [String] the bulk task type
167
+ # @param id [String] the bulk task ID
168
+ # @param name [String] the new name for the bulk task
169
+ # @return [Hash] API response
170
+ # @raise [Tomba::Exception]
171
+ def rename(type, id, name)
172
+ raise Tomba::Exception, 'Missing required parameter: "type"' if type.nil?
173
+
174
+ validate_type(type)
175
+ raise Tomba::Exception, 'Missing required parameter: "id"' if id.nil?
176
+ raise Tomba::Exception, 'Missing required parameter: "name"' if name.nil?
177
+
178
+ path = "/bulk/#{type}/#{id}/rename"
179
+
180
+ params = { name: name }
181
+
182
+ @client.call('put', path, {
183
+ 'content-type' => 'application/json'
184
+ }, params)
185
+ end
186
+
187
+ # Bulk Task Progress
188
+ #
189
+ # Returns the progress status of a bulk task.
190
+ #
191
+ # @see https://docs.tomba.io/api/bulk#bulk-task-progress
192
+ # @param type [String] the bulk task type
193
+ # @param id [String] the bulk task ID
194
+ # @return [Hash] API response containing progress data
195
+ # @raise [Tomba::Exception]
196
+ def progress(type, id)
197
+ raise Tomba::Exception, 'Missing required parameter: "type"' if type.nil?
198
+
199
+ validate_type(type)
200
+ raise Tomba::Exception, 'Missing required parameter: "id"' if id.nil?
201
+
202
+ path = "/bulk/#{type}/#{id}/progress"
203
+
204
+ params = {}
205
+
206
+ @client.call('get', path, {
207
+ 'content-type' => 'application/json'
208
+ }, params)
209
+ end
210
+
211
+ # Download Bulk Task
212
+ #
213
+ # Downloads the results of a completed bulk task.
214
+ #
215
+ # @see https://docs.tomba.io/api/bulk-task
216
+ # @param type [String] the bulk task type
217
+ # @param id [String] the bulk task ID
218
+ # @return [Hash] API response containing download data
219
+ # @raise [Tomba::Exception]
220
+ def download(type, id)
221
+ raise Tomba::Exception, 'Missing required parameter: "type"' if type.nil?
222
+
223
+ validate_type(type)
224
+ raise Tomba::Exception, 'Missing required parameter: "id"' if id.nil?
225
+
226
+ path = "/bulk/#{type}/#{id}/download"
227
+
228
+ params = {}
229
+
230
+ @client.call('get', path, {
231
+ 'content-type' => 'application/json'
232
+ }, params)
233
+ end
234
+ end
235
+ end
@@ -1,27 +1,31 @@
1
- module Tomba
2
- class Count < Service
3
-
4
- def email_count(domain:)
5
- if domain.nil?
6
- raise Tomba::Exception.new('Missing required parameter: "domain"')
7
- end
8
-
9
- path = '/email-count'
10
-
11
- params = {}
12
-
13
- if !domain.nil?
14
- params[:domain] = domain
15
- end
1
+ # frozen_string_literal: true
16
2
 
17
- return @client.call('get', path, {
18
- 'content-type' => 'application/json',
19
- }, params);
20
- end
21
-
22
-
23
- protected
24
-
25
- private
26
- end
27
- end
3
+ module Tomba
4
+ # Count service for email counting.
5
+ #
6
+ # Provides methods to get the number of email addresses found for a domain.
7
+ #
8
+ # @see https://docs.tomba.io/api/count
9
+ class Count < Service
10
+ # Email Count
11
+ #
12
+ # Returns the total number of email addresses found for a domain.
13
+ #
14
+ # @see https://docs.tomba.io/api/count#email-count
15
+ # @param domain [String] the domain name to count emails for
16
+ # @return [Hash] API response containing the email count
17
+ # @raise [Tomba::Exception]
18
+ def email_count(domain:)
19
+ raise Tomba::Exception, 'Missing required parameter: "domain"' if domain.nil?
20
+
21
+ path = '/email-count'
22
+
23
+ params = {}
24
+ params[:domain] = domain unless domain.nil?
25
+
26
+ @client.call('get', path, {
27
+ 'content-type' => 'application/json'
28
+ }, params)
29
+ end
30
+ end
31
+ end