cufinder-ruby 0.0.1 → 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: c9f06c87746a02b9f3ba1003f43e859f96549c67061db0d66465ce919324400f
4
- data.tar.gz: e304713de973c2cfa7de842e9788a2d49a17383dc540a9c7520ff6205f50dfcd
3
+ metadata.gz: 933505a753cc67ab4e2311cb44741da6ce2c89f186e2eaa36efad0adc2044a63
4
+ data.tar.gz: 8025f9c7eb01e26078c870967aba4d68af22ecab84242c93706279735620f555
5
5
  SHA512:
6
- metadata.gz: 65e625f7ac41c7b61af9b3f672d5a4c9cae6243a28a62c099feb13dc8bfecefd3c388790d355c5b6c7a47ec544676ccee0da857b89a23d7fc8de05ef745ab7d6
7
- data.tar.gz: a35579b44987e8aa8c2bb5a8ecad07da0c6dc4585cf3c0a08626b2202253e77da1b60000e7d6481bac5c11e906c84e8bba3e61685fddc008efd90ca4555eeb5b
6
+ metadata.gz: dcde541a1672ea1b08e82dade2fa76f5c7c5a2aecc81dff9900875b7acd15794e58ffc8b3bbea0aca6e71cafb23e230bd097c767b9665cd6da1c6f78115ded29
7
+ data.tar.gz: 2c6b4ff7797fe5b818d57673fcd06c9c3ea810f909ff1598763424bdb281d85c79ca44933f40a123ca20f35fce8870d5cfcbe6e670e63d198b025312ee433203
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Cufinder Ruby SDK Changelog
2
+
3
+
4
+ ## 1.1.0 (February 01, 2026)
5
+
6
+ #### Features
7
+ - **New V2 API services**: Add new V2 services including `BCD`, `CCP`, `ISC`, `CBC`, `CSC`, `CSN`, `NAO` and `NAA`
8
+
9
+
10
+ #### Documentation
11
+ - **Updated README.md**: Add API reference for all new services
data/README.md CHANGED
@@ -1,6 +1,19 @@
1
1
  # CUFinder Ruby SDK
2
2
 
3
- Official Ruby SDK for accessing CUFinder's comprehensive business intelligence and lead generation services.
3
+ [![](https://img.shields.io/badge/repo%20status-Active-28a745)](https://github.com/cufinder/cufinder-ruby)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-514BEE.svg)](https://opensource.org/licenses/MIT)
5
+ [![Gem Version](https://img.shields.io/gem/v/cufinder-ruby.svg)](https://rubygems.org/gems/cufinder-ruby)
6
+
7
+ A Ruby SDK for the CUFinder API that provides access to all company and person enrichment services.
8
+
9
+ ## Table of Contents
10
+
11
+ - [Installation](#installation)
12
+ - [Usage](#usage)
13
+ - [API Reference](#api-reference)
14
+ - [Error Handling](#error-handling)
15
+ - [Types](#types)
16
+ - [Support](#support)
4
17
 
5
18
  ## Installation
6
19
 
@@ -24,183 +37,439 @@ gem install cufinder-ruby
24
37
 
25
38
  ## Usage
26
39
 
27
- ### Basic Setup
28
-
29
40
  ```ruby
30
41
  require 'cufinder_ruby'
31
42
 
32
- # Initialize the SDK with your API key
33
- sdk = CufinderRuby::SDK.new(api_key: 'your-api-key-here')
43
+ # Initialize the client
44
+ client = Cufinder::Client.new(api_key: 'your-api-key-here')
45
+
46
+ # Initialize with more options
47
+ client = Cufinder::Client.new(
48
+ api_key: 'your-api-key-here',
49
+ timeout: 60,
50
+ max_retries: 3
51
+ )
52
+ ```
53
+
54
+ ## API Reference
55
+
56
+ This SDK covers all 28 Cufinder API (v2) endpoints:
57
+
58
+ - **CUF** - [Company Name to Domain](https://apidoc.cufinder.io/apis/company-name-to-domain)
59
+ - **LCUF** - [LinkedIn Company URL Finder](https://apidoc.cufinder.io/apis/company-linkedin-url-finder)
60
+ - **DTC** - [Domain to Company Name](https://apidoc.cufinder.io/apis/domain-to-company-name)
61
+ - **DTE** - [Company Email Finder](https://apidoc.cufinder.io/apis/company-email-finder)
62
+ - **NTP** - [Company Phone Finder](https://apidoc.cufinder.io/apis/company-phone-finder)
63
+ - **REL** - [Reverse Email Lookup](https://apidoc.cufinder.io/apis/reverse-email-lookup)
64
+ - **FCL** - [Company Lookalikes Finder](https://apidoc.cufinder.io/apis/company-lookalikes-finder)
65
+ - **ELF** - [Company Fundraising](https://apidoc.cufinder.io/apis/company-fundraising)
66
+ - **CAR** - [Company Revenue Finder](https://apidoc.cufinder.io/apis/company-revenue-finder)
67
+ - **FCC** - [Company Subsidiaries Finder](https://apidoc.cufinder.io/apis/company-subsidiaries-finder)
68
+ - **FTS** - [Company Tech Stack Finder](https://apidoc.cufinder.io/apis/company-tech-stack-finder)
69
+ - **EPP** - [LinkedIn Profile Enrichment](https://apidoc.cufinder.io/apis/linkedin-profile-enrichment)
70
+ - **FWE** - [LinkedIn Profile Email Finder](https://apidoc.cufinder.io/apis/linkedin-profile-email-finder)
71
+ - **TEP** - [Person Enrichment](https://apidoc.cufinder.io/apis/person-enrichment)
72
+ - **ENC** - [Company Enrichment](https://apidoc.cufinder.io/apis/company-enrichment)
73
+ - **CEC** - [Company Employee Count](https://apidoc.cufinder.io/apis/company-employee-count)
74
+ - **CLO** - [Company Locations](https://apidoc.cufinder.io/apis/company-locations)
75
+ - **CSE** - [Company Search](https://apidoc.cufinder.io/apis/company-search)
76
+ - **PSE** - [Person Search](https://apidoc.cufinder.io/apis/person-search)
77
+ - **LBS** - [Local Business Search (Google Maps Search API)](https://apidoc.cufinder.io/apis/local-business-search-google-maps-search-api)
78
+ - **BCD** - [B2B Customers Finder](https://apidoc.cufinder.io/apis/b2b-customers-finder)
79
+ - **CCP** - [Company Career Page Finder](https://apidoc.cufinder.io/apis/company-career-page-finder)
80
+ - **ISC** - [Company Saas Checker](https://apidoc.cufinder.io/apis/company-saas-checker)
81
+ - **CBC** - [Company B2B or B2C Checker](https://apidoc.cufinder.io/apis/company-b2b-or-b2c-checker)
82
+ - **CSC** - [Company Mission Statement](https://apidoc.cufinder.io/apis/company-mission-statement)
83
+ - **CSN** - [Company Snapshot](https://apidoc.cufinder.io/apis/company-snapshot)
84
+ - **NAO** - [Phone Number Normalizer](https://apidoc.cufinder.io/apis/phone-number-normalizer)
85
+ - **NAA** - [Address Normalizer](https://apidoc.cufinder.io/apis/address-normalizer)
86
+
87
+
88
+ **CUF - Company Name to Domain**
89
+
90
+ Returns the official website URL of a company based on its name.
91
+
92
+ ```ruby
93
+ result = client.cuf(company_name: 'cufinder', country_code: 'US')
94
+ puts result
34
95
  ```
35
96
 
36
- ### Available Services
97
+ **LCUF - LinkedIn Company URL Finder**
37
98
 
38
- The SDK provides access to all CUFinder API services:
99
+ Finds the official LinkedIn company profile URL from a company name.
39
100
 
40
- #### 1. CUF - Company URL Finder
41
101
  ```ruby
42
- result = sdk.cuf(company_name: "Apple Inc", country_code: "US")
43
- puts result.domain # => "apple.com"
102
+ result = client.lcuf(company_name: 'cufinder')
103
+ puts result
44
104
  ```
45
105
 
46
- #### 2. LCUF - LinkedIn Company URL Finder
106
+ **DTC - Domain to Company Name**
107
+
108
+ Retrieves the registered company name associated with a given website domain.
109
+
47
110
  ```ruby
48
- result = sdk.lcuf(company_name: "Apple Inc")
49
- puts result.linkedin_url # => "linkedin.com/company/apple"
111
+ result = client.dtc(company_website: 'cufinder.io')
112
+ puts result
50
113
  ```
51
114
 
52
- #### 3. DTC - Domain to Company
115
+ **DTE - Company Email Finder**
116
+
117
+ Returns up to five general or role-based business email addresses for a company.
118
+
53
119
  ```ruby
54
- result = sdk.dtc(company_website: "apple.com")
55
- puts result.company_name # => "Apple Inc"
120
+ result = client.dte(company_website: 'cufinder.io')
121
+ puts result
56
122
  ```
57
123
 
58
- #### 4. DTE - Domain to Emails
124
+ **NTP - Company Phone Finder**
125
+
126
+ Returns up to two verified phone numbers for a company.
127
+
128
+ ```ruby
129
+ result = client.ntp(company_name: 'apple')
130
+ puts result
131
+ ```
132
+
133
+ **REL - Reverse Email Lookup**
134
+
135
+ Enriches an email address with detailed person and company information.
136
+
59
137
  ```ruby
60
- result = sdk.dte(company_website: "apple.com")
61
- puts result.emails # => ["contact@apple.com", "info@apple.com"]
138
+ result = client.rel(email: 'iain.mckenzie@stripe.com')
139
+ puts result
62
140
  ```
63
141
 
64
- #### 5. NTP - Name to Phones
142
+ **FCL - Company Lookalikes Finder**
143
+
144
+ Provides a list of similar companies based on an input company's profile.
145
+
146
+ ```ruby
147
+ result = client.fcl(query: 'apple')
148
+ puts result
149
+ ```
150
+
151
+ **ELF - Company Fundraising**
152
+
153
+ Returns detailed funding information about a company.
154
+
155
+ ```ruby
156
+ result = client.elf(query: 'cufinder')
157
+ puts result
158
+ ```
159
+
160
+ **CAR - Company Revenue Finder**
161
+
162
+ Estimates a company's annual revenue based on name.
163
+
164
+ ```ruby
165
+ result = client.car(query: 'apple')
166
+ puts result
167
+ ```
168
+
169
+ **FCC - Company Subsidiaries Finder**
170
+
171
+ Identifies known subsidiaries of a parent company.
172
+
173
+ ```ruby
174
+ result = client.fcc(query: 'amazon')
175
+ puts result
176
+ ```
177
+
178
+ **FTS - Company Tech Stack Finder**
179
+
180
+ Detects the technologies a company uses.
181
+
182
+ ```ruby
183
+ result = client.fts(query: 'cufinder')
184
+ puts result
185
+ ```
186
+
187
+ **EPP - LinkedIn Profile Enrichment**
188
+
189
+ Takes a LinkedIn profile URL and returns enriched person and company data.
190
+
191
+ ```ruby
192
+ result = client.epp(linkedin_url: 'linkedin.com/in/iain-mckenzie')
193
+ puts result
194
+ ```
195
+
196
+ **FWE - LinkedIn Profile Email Finder**
197
+
198
+ Extracts a verified business email address from a LinkedIn profile URL.
199
+
65
200
  ```ruby
66
- result = sdk.ntp(company_name: "Apple Inc")
67
- puts result.phones # => ["+1-408-996-1010"]
201
+ result = client.fwe(linkedin_url: 'linkedin.com/in/iain-mckenzie')
202
+ puts result
68
203
  ```
69
204
 
70
- #### 6. REL - Reverse Email Lookup
205
+ **TEP - Person Enrichment**
206
+
207
+ Returns enriched person data based on full name and company name.
208
+
71
209
  ```ruby
72
- result = sdk.rel(email: "tim.cook@apple.com")
73
- puts result.person.full_name # => "Tim Cook"
210
+ result = client.tep(full_name: 'iain mckenzie', company: 'stripe')
211
+ puts result
74
212
  ```
75
213
 
76
- #### 7. FCL - Find Company Lookalikes
214
+ **ENC - Company Enrichment**
215
+
216
+ Provides a complete company profile from a company name.
217
+
77
218
  ```ruby
78
- result = sdk.fcl(query: "tech startup")
79
- puts result.companies.length # => 10
219
+ result = client.enc(query: 'cufinder')
220
+ puts result
80
221
  ```
81
222
 
82
- #### 8. ELF - Enrich LinkedIn Fundraising
223
+ **CEC - Company Employee Count**
224
+
225
+ Returns an estimated number of employees for a company.
226
+
83
227
  ```ruby
84
- result = sdk.elf(query: "tech company")
85
- puts result.fundraising.funding_money_raised # => "$5M"
228
+ result = client.cec(query: 'cufinder')
229
+ puts result
86
230
  ```
87
231
 
88
- #### 9. CAR - Company Annual Revenue
232
+ **CLO - Company Locations**
233
+
234
+ Returns the known physical office locations of a company.
235
+
89
236
  ```ruby
90
- result = sdk.car(query: "Apple Inc")
91
- puts result.revenue # => "$394.3B"
237
+ result = client.clo(query: 'apple')
238
+ puts result
92
239
  ```
93
240
 
94
- #### 10. FCC - Find Company Children
241
+ **CSE - Company Search**
242
+
243
+ Search for companies by keyword, partial name, industry, location, or other filters.
244
+
95
245
  ```ruby
96
- result = sdk.fcc(query: "Apple Inc")
97
- puts result.subsidiaries # => ["Beats Electronics", "Shazam"]
246
+ result = client.cse(
247
+ name: 'cufinder',
248
+ country: 'germany',
249
+ state: 'hamburg',
250
+ city: 'hamburg'
251
+ )
252
+ puts result
98
253
  ```
99
254
 
100
- #### 11. FTS - Find Tech Stack
255
+ **PSE - Person Search**
256
+
257
+ Search for people by name, company, job title, location, or other filters.
258
+
101
259
  ```ruby
102
- result = sdk.fts(query: "web development")
103
- puts result.technologies # => ["React", "Node.js", "Python"]
260
+ result = client.pse(
261
+ full_name: 'iain mckenzie',
262
+ company_name: 'stripe'
263
+ )
264
+ puts result
104
265
  ```
105
266
 
106
- #### 12. EPP - Enrich Person Profile
267
+ **LBS - Local Business Search (Google Maps Search API)**
268
+
269
+ Search for local businesses by location, industry, or name.
270
+
107
271
  ```ruby
108
- result = sdk.epp(linkedin_url: "linkedin.com/in/tim-cook")
109
- puts result.person.full_name # => "Tim Cook"
272
+ result = client.lbs(
273
+ country: 'united states',
274
+ state: 'california',
275
+ page: 1
276
+ )
277
+ puts result
110
278
  ```
111
279
 
112
- #### 13. FWE - Find Work Email
280
+ **BCD - B2B Customers Finder**
281
+
282
+ Returns company's careers page
283
+
113
284
  ```ruby
114
- result = sdk.fwe(linkedin_url: "linkedin.com/in/tim-cook")
115
- puts result.email # => "tim.cook@apple.com"
285
+ result = client.bcd(url: "stripe.com")
286
+ puts result
116
287
  ```
117
288
 
118
- #### 14. TEP - Title Email Phone
289
+ **CCP - Company Career Page Finder**
290
+
291
+ Returns is company SaaS or not
292
+
119
293
  ```ruby
120
- result = sdk.tep(full_name: "Tim Cook", company: "Apple Inc")
121
- puts result.person.email # => "tim.cook@apple.com"
122
- puts result.person.phone # => "+1-408-996-1010"
294
+ result = client.ccp(url: "stripe.com")
295
+ puts result
123
296
  ```
124
297
 
125
- #### 15. ENC - Enrich Company
298
+ **ISC - Company Saas Checker**
299
+
300
+ Returns is company SaaS or not
301
+
126
302
  ```ruby
127
- result = sdk.enc(query: "Apple Inc")
128
- puts result.company.employee_count # => 164000
303
+ result = client.isc(url: "stripe.com")
304
+ puts result
129
305
  ```
130
306
 
131
- #### 16. CEC - Company Employee Count
307
+ **CBC - Company B2B or B2C Checker**
308
+
309
+ Returns company's business type
310
+
132
311
  ```ruby
133
- result = sdk.cec(query: "Apple Inc")
134
- puts result.countries # => {"US" => 100000, "CA" => 5000}
312
+ result = client.cbc(url: "stripe.com")
313
+ puts result
135
314
  ```
136
315
 
137
- #### 17. CLO - Company Locations
316
+ **CSC - Company Mission Statement**
317
+
318
+ Returns company's mission statement
319
+
138
320
  ```ruby
139
- result = sdk.clo(query: "Apple Inc")
140
- puts result.locations.first.city # => "Cupertino"
321
+ result = client.csc(url: "stripe.com")
322
+ puts result
141
323
  ```
142
324
 
143
- #### 18. CSE - Company Search Engine
325
+ **CSN - Company Snapshot**
326
+
327
+ Returns company's snapshot information
328
+
144
329
  ```ruby
145
- result = sdk.cse(name: "tech", country: "US", industry: "software")
146
- puts result.companies.length # => 50
330
+ result = client.csn(url: "stripe.com")
331
+ puts result
147
332
  ```
148
333
 
149
- #### 19. PSE - Person Search Engine
334
+ **NAO - Phone Number Normalizer**
335
+
336
+ Returns normalized phone
337
+
150
338
  ```ruby
151
- result = sdk.pse(full_name: "John", country: "US", company_name: "Apple")
152
- puts result.peoples.length # => 25
339
+ result = client.nao(phone: "+18006676389")
340
+ puts result
153
341
  ```
154
342
 
155
- #### 20. LBS - Local Business Search
343
+ **NAA - Address Normalizer**
344
+
345
+ Returns normalized address
346
+
156
347
  ```ruby
157
- result = sdk.lbs(name: "restaurant", city: "New York")
158
- puts result.companies.length # => 100
348
+ result = client.naa(address: "1095 avenue of the Americas, 6th Avenue ny 10036")
349
+ puts result
159
350
  ```
160
351
 
161
- ### Error Handling
352
+ ## Error Handling
162
353
 
163
- The SDK provides comprehensive error handling:
354
+ The SDK provides comprehensive error handling with custom error types:
164
355
 
165
356
  ```ruby
357
+ require 'cufinder_ruby'
358
+
166
359
  begin
167
- result = sdk.cuf(company_name: "Apple Inc", country_code: "US")
168
- rescue CufinderRuby::AuthenticationError => e
360
+ result = client.cuf(company_name: 'cufinder', country_code: 'US')
361
+ rescue Cufinder::AuthenticationError => e
362
+ # 401 - Invalid API key
169
363
  puts "Authentication failed: #{e.message}"
170
- rescue CufinderRuby::RateLimitError => e
364
+ rescue Cufinder::CreditLimitError => e
365
+ # 400 - Not enough credit
366
+ puts "Not enough credit: #{e.message}"
367
+ rescue Cufinder::NotFoundError => e
368
+ # 404 - Not found result
369
+ puts "Not found result: #{e.message}"
370
+ rescue Cufinder::PayloadError => e
371
+ # 422 - Error in the payload
372
+ puts "Payload error: #{e.message}"
373
+ rescue Cufinder::RateLimitError => e
374
+ # 429 - Rate limit exceeded
171
375
  puts "Rate limit exceeded: #{e.message}"
172
- rescue CufinderRuby::CreditLimitError => e
173
- puts "Credit limit exceeded: #{e.message}"
174
- rescue CufinderRuby::ApiError => e
175
- puts "API error #{e.status}: #{e.message}"
176
- rescue CufinderRuby::ValidationError => e
376
+ rescue Cufinder::ServerError => e
377
+ # 500, 501, ... - Server errors
378
+ puts "Server error (#{e.status}): #{e.message}"
379
+ rescue Cufinder::NetworkError => e
380
+ puts "Network error: #{e.message}"
381
+ rescue Cufinder::ValidationError => e
177
382
  puts "Validation error: #{e.message}"
383
+ rescue Cufinder::ApiError => e
384
+ puts "Unknown error: #{e.message}"
178
385
  end
179
386
  ```
180
387
 
181
- ### Configuration
388
+ ## Types
182
389
 
183
- You can configure the SDK with custom settings:
390
+ The SDK exports comprehensive Ruby classes for all API requests and responses:
184
391
 
185
392
  ```ruby
186
- sdk = CufinderRuby::SDK.new(
187
- api_key: 'your-api-key',
188
- base_url: 'https://api.cufinder.io/v2', # Default
189
- timeout: 30, # Default
190
- max_retries: 3 # Default
191
- )
192
- ```
393
+ # Response classes
394
+ class BaseResponse
395
+ attr_reader :query, :credit_count
396
+ end
397
+
398
+ # Model classes
399
+ class Company
400
+ # The Company class contains all returned company data.
401
+ attr_reader :name, :domain, :website, :linkedin_url
402
+ attr_reader :country, :state, :city, :address
403
+ attr_reader :industry, :company_size, :revenue
404
+ attr_reader :employee_count, :subsidiaries, :tech_stack
405
+ attr_reader :emails, :phones, :description
406
+ attr_reader :locations, :founded_year, :logo_url
407
+ end
193
408
 
194
- ## Development
409
+ class Person
410
+ # The Person class contains all returned person data.
411
+ attr_reader :full_name, :first_name, :last_name
412
+ attr_reader :company_name, :company_domain, :job_title
413
+ attr_reader :country, :state, :city
414
+ attr_reader :email, :phone, :description, :linkedin_url
415
+ end
195
416
 
196
- After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests.
417
+ class LookalikeCompany
418
+ # The LookalikeCompany class contains all returned lookalike company data.
419
+ attr_reader :name, :domain, :website, :linkedin_url
420
+ attr_reader :country, :state, :city, :address
421
+ attr_reader :industry, :company_size, :revenue
422
+ attr_reader :employee_count, :subsidiaries, :tech_stack
423
+ attr_reader :emails, :phones, :description
424
+ attr_reader :locations, :founded_year, :logo_url
425
+ end
197
426
 
198
- To install this gem onto your local machine, run `bundle exec rake install`.
427
+ class FundraisingInfo
428
+ attr_reader :funding_last_round_type
429
+ attr_reader :funding_ammount_currency_code
430
+ attr_reader :funding_money_raised
431
+ attr_reader :funding_last_round_investors_url
432
+ end
199
433
 
200
- ## Contributing
434
+ class CompanyLocation
435
+ # The CompanyLocation class contains all returned company location data.
436
+ attr_reader :country, :state, :city, :postal_code
437
+ attr_reader :line1, :line2, :latitude, :longitude
438
+ end
201
439
 
202
- Bug reports and pull requests are welcome on GitHub at https://github.com/cufinder/cufinder-ruby.
440
+ class CompanySearchResult
441
+ attr_reader :companies, :total_results, :page
442
+ attr_reader :query, :credit_count
443
+ end
444
+
445
+ class PersonSearchResult
446
+ attr_reader :peoples, :total_results, :page
447
+ attr_reader :query, :credit_count
448
+ end
449
+
450
+ class LocalBusinessResult
451
+ attr_reader :businesses, :total_results, :page
452
+ attr_reader :query, :credit_count
453
+ end
454
+
455
+ # Configuration
456
+ class ClientConfig
457
+ attr_accessor :api_key, :base_url, :timeout, :max_retries
458
+ end
459
+
460
+ # Error classes
461
+ class CufinderError < StandardError; end
462
+ class AuthenticationError < CufinderError; end
463
+ class CreditLimitError < CufinderError; end
464
+ class NotFoundError < CufinderError; end
465
+ class PayloadError < CufinderError; end
466
+ class RateLimitError < CufinderError; end
467
+ class ServerError < CufinderError; end
468
+ class NetworkError < CufinderError; end
469
+ class ValidationError < CufinderError; end
470
+ class ApiError < CufinderError; end
471
+ ```
203
472
 
204
- ## License
473
+ ## Support
205
474
 
206
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
475
+ For support, please open an issue on the [GitHub repository](https://github.com/cufinder/cufinder-ruby/issues).
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "cufinder-ruby"
3
- spec.version = "0.0.1"
3
+ spec.version = "1.1.0"
4
4
  spec.authors = ["CUFinder Team"]
5
5
  spec.email = ["support@cufinder.io"]
6
6
 
@@ -0,0 +1,84 @@
1
+ require "httparty"
2
+ require "json"
3
+ require "cufinder_ruby/errors"
4
+
5
+ module Cufinder
6
+ class BaseApiClient
7
+ include HTTParty
8
+
9
+ attr_reader :api_key, :base_url, :timeout, :max_retries
10
+
11
+ def initialize(api_key:, timeout: 30, max_retries: 3)
12
+ @api_key = api_key
13
+ @base_url = "https://api.cufinder.io/v2"
14
+ @timeout = timeout
15
+ @max_retries = max_retries
16
+
17
+ self.class.base_uri @base_url
18
+ self.class.headers "User-Agent" => "cufinder-ruby/#{Cufinder::VERSION}"
19
+ end
20
+
21
+ def post(endpoint, data)
22
+ response = self.class.post(
23
+ endpoint,
24
+ body: form_encode(data),
25
+ headers: {
26
+ "x-api-key" => api_key,
27
+ "Content-Type" => "application/x-www-form-urlencoded"
28
+ },
29
+ timeout: @timeout
30
+ )
31
+
32
+ handle_response(response)
33
+ end
34
+
35
+ private
36
+
37
+ def form_encode(data)
38
+ return "" if data.nil? || data.empty?
39
+
40
+ data.map do |key, value|
41
+ next if value.nil?
42
+
43
+ if value.is_a?(Array)
44
+ value.map { |v| "#{key}=#{CGI.escape(v.to_s)}" }.join("&")
45
+ else
46
+ "#{key}=#{CGI.escape(value.to_s)}"
47
+ end
48
+ end.compact.join("&")
49
+ end
50
+
51
+ def handle_response(response)
52
+ case response.code
53
+ when 200..299
54
+ extract_data(response.parsed_response)
55
+ when 401
56
+ raise AuthenticationError, response.body
57
+ when 402
58
+ raise CreditLimitError, response.body
59
+ when 429
60
+ raise RateLimitError, response.body
61
+ else
62
+ raise ApiError.new(response.code, response.body)
63
+ end
64
+ rescue JSON::ParserError => e
65
+ raise HttpError, "Failed to parse response: #{e.message}"
66
+ rescue HTTParty::Error => e
67
+ raise HttpError, "HTTP request failed: #{e.message}"
68
+ end
69
+
70
+ def extract_data(response_data)
71
+ # Extract data from wrapper if present (similar to Go SDK's mapToStruct)
72
+ if response_data.is_a?(Hash) && response_data.key?("data")
73
+ data = response_data["data"]
74
+ # Add meta_data if it exists in the outer response
75
+ if response_data.key?("meta_data")
76
+ data["meta_data"] = response_data["meta_data"]
77
+ end
78
+ data
79
+ else
80
+ response_data
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,84 +1,145 @@
1
- require "httparty"
2
- require "json"
3
- require "cufinder_ruby/errors"
1
+ require "cufinder_ruby/base_api_client"
2
+ require "cufinder_ruby/services"
4
3
 
5
- module CufinderRuby
4
+ module Cufinder
5
+ # Main client class for interacting with the CUFinder API
6
+ #
7
+ # This is the primary entry point for all API operations.
8
+ # It provides convenient methods for each service and handles
9
+ # authentication and HTTP communication internally.
10
+ #
11
+ # @example Basic usage
12
+ # client = Cufinder::Client.new(api_key: 'your-api-key')
13
+ # result = client.cuf(company_name: 'Example Corp', country_code: 'US')
14
+ #
6
15
  class Client
7
- include HTTParty
8
-
9
- attr_reader :api_key, :base_url, :timeout, :max_retries
10
-
11
- def initialize(api_key:, base_url: "https://api.cufinder.io/v2", timeout: 30, max_retries: 3)
12
- @api_key = api_key
13
- @base_url = base_url
14
- @timeout = timeout
15
- @max_retries = max_retries
16
-
17
- self.class.base_uri base_url
18
- self.class.timeout timeout
19
- self.class.headers "User-Agent" => "cufinder-ruby/#{CufinderRuby::VERSION}"
20
- end
21
-
22
- def post(endpoint, data)
23
- response = self.class.post(
24
- endpoint,
25
- body: form_encode(data),
26
- headers: {
27
- "x-api-key" => api_key,
28
- "Content-Type" => "application/x-www-form-urlencoded"
29
- }
16
+ attr_reader :client, :services
17
+
18
+ # Initialize a new CUFinder client
19
+ #
20
+ # @param api_key [String] Your CUFinder API key
21
+ # @param timeout [Integer] Request timeout in seconds (default: 30)
22
+ # @param max_retries [Integer] Maximum number of retries (default: 3)
23
+ def initialize(api_key:, timeout: 30, max_retries: 3)
24
+ @client = BaseApiClient.new(
25
+ api_key: api_key,
26
+ timeout: timeout,
27
+ max_retries: max_retries
30
28
  )
31
-
32
- handle_response(response)
33
- end
34
-
35
- private
36
-
37
- def form_encode(data)
38
- return "" if data.nil? || data.empty?
39
-
40
- data.map do |key, value|
41
- next if value.nil?
42
-
43
- if value.is_a?(Array)
44
- value.map { |v| "#{key}=#{CGI.escape(v.to_s)}" }.join("&")
45
- else
46
- "#{key}=#{CGI.escape(value.to_s)}"
47
- end
48
- end.compact.join("&")
49
- end
50
-
51
- def handle_response(response)
52
- case response.code
53
- when 200..299
54
- extract_data(response.parsed_response)
55
- when 401
56
- raise AuthenticationError, response.body
57
- when 402
58
- raise CreditLimitError, response.body
59
- when 429
60
- raise RateLimitError, response.body
61
- else
62
- raise ApiError.new(response.code, response.body)
63
- end
64
- rescue JSON::ParserError => e
65
- raise HttpError, "Failed to parse response: #{e.message}"
66
- rescue HTTParty::Error => e
67
- raise HttpError, "HTTP request failed: #{e.message}"
68
- end
69
-
70
- def extract_data(response_data)
71
- # Extract data from wrapper if present (similar to Go SDK's mapToStruct)
72
- if response_data.is_a?(Hash) && response_data.key?("data")
73
- data = response_data["data"]
74
- # Add meta_data if it exists in the outer response
75
- if response_data.key?("meta_data")
76
- data["meta_data"] = response_data["meta_data"]
77
- end
78
- data
79
- else
80
- response_data
81
- end
29
+ @services = Services.new(@client)
30
+ end
31
+
32
+ # Service methods - Each method corresponds to a CUFinder API service
33
+ def cuf(company_name:, country_code:)
34
+ @services.get_domain(company_name: company_name, country_code: country_code)
35
+ end
36
+
37
+ def lcuf(company_name:)
38
+ @services.get_linkedin_url(company_name: company_name)
39
+ end
40
+
41
+ def dtc(company_website:)
42
+ @services.get_company_name(company_website: company_website)
43
+ end
44
+
45
+ def dte(company_website:)
46
+ @services.get_emails(company_website: company_website)
47
+ end
48
+
49
+ def ntp(company_name:)
50
+ @services.get_phones(company_name: company_name)
51
+ end
52
+
53
+ def rel(email:)
54
+ @services.get_person_by_email(email: email)
55
+ end
56
+
57
+ def fcl(query:)
58
+ @services.find_company_lookalikes(query: query)
59
+ end
60
+
61
+ def elf(query:)
62
+ @services.enrich_linkedin_fundraising(query: query)
63
+ end
64
+
65
+ def car(query:)
66
+ @services.get_annual_revenue(query: query)
67
+ end
68
+
69
+ def fcc(query:)
70
+ @services.find_company_children(query: query)
71
+ end
72
+
73
+ def fts(query:)
74
+ @services.find_tech_stack(query: query)
75
+ end
76
+
77
+ def epp(linkedin_url:)
78
+ @services.enrich_person_profile(linkedin_url: linkedin_url)
79
+ end
80
+
81
+ def fwe(linkedin_url:)
82
+ @services.find_work_email(linkedin_url: linkedin_url)
83
+ end
84
+
85
+ def tep(full_name:, company:)
86
+ @services.get_title_email_phone(full_name: full_name, company: company)
87
+ end
88
+
89
+ def enc(query:)
90
+ @services.enrich_company(query: query)
91
+ end
92
+
93
+ def cec(query:)
94
+ @services.get_company_employee_count(query: query)
95
+ end
96
+
97
+ def clo(query:)
98
+ @services.get_company_locations(query: query)
99
+ end
100
+
101
+ def cse(**params)
102
+ @services.search_companies(params)
103
+ end
104
+
105
+ def pse(**params)
106
+ @services.search_people(params)
107
+ end
108
+
109
+ def lbs(**params)
110
+ @services.search_local_businesses(params)
111
+ end
112
+
113
+ def bcd(url:)
114
+ @services.extract_b2b_customers(url: url)
115
+ end
116
+
117
+ def ccp(url:)
118
+ @services.find_company_careers_page(url: url)
119
+ end
120
+
121
+ def isc(url:)
122
+ @services.is_saas(url: url)
123
+ end
124
+
125
+ def cbc(url:)
126
+ @services.get_company_business_type(url: url)
127
+ end
128
+
129
+ def csc(url:)
130
+ @services.get_company_mission_statement(url: url)
131
+ end
132
+
133
+ def csn(url:)
134
+ @services.get_company_snapshot(url: url)
135
+ end
136
+
137
+ def nao(phone:)
138
+ @services.normalize_phone(phone: phone)
139
+ end
140
+
141
+ def naa(address:)
142
+ @services.normalize_address(address: address)
82
143
  end
83
144
  end
84
145
  end
@@ -1,4 +1,4 @@
1
- module CufinderRuby
1
+ module Cufinder
2
2
  class Error < StandardError; end
3
3
 
4
4
  class AuthenticationError < Error; end
@@ -1,8 +1,8 @@
1
- require "cufinder_ruby/client"
1
+ require "cufinder_ruby/base_api_client"
2
2
  require "cufinder_ruby/types"
3
3
  require "cufinder_ruby/errors"
4
4
 
5
- module CufinderRuby
5
+ module Cufinder
6
6
  class Services
7
7
  def initialize(client)
8
8
  @client = client
@@ -164,6 +164,70 @@ module CufinderRuby
164
164
  response = @client.post("/lbs", params)
165
165
  LbsResponse.new(response)
166
166
  end
167
+
168
+ # BCD Service - B2B Customers Finder
169
+ def extract_b2b_customers(params)
170
+ validate_required(params, [:url])
171
+
172
+ response = @client.post("/bcd", params)
173
+ BcdResponse.new(response)
174
+ end
175
+
176
+ # CCP Service - Company Career Page Finder
177
+ def find_company_careers_page(params)
178
+ validate_required(params, [:url])
179
+
180
+ response = @client.post("/ccp", params)
181
+ CcpResponse.new(response)
182
+ end
183
+
184
+ # ISC Service - Company Saas Checker
185
+ def is_saas(params)
186
+ validate_required(params, [:url])
187
+
188
+ response = @client.post("/isc", params)
189
+ IscResponse.new(response)
190
+ end
191
+
192
+ # CBC Service - Company B2B or B2C Checker
193
+ def get_company_business_type(params)
194
+ validate_required(params, [:url])
195
+
196
+ response = @client.post("/cbc", params)
197
+ CbcResponse.new(response)
198
+ end
199
+
200
+ # CSC Service - Company Mission Statement
201
+ def get_company_mission_statement(params)
202
+ validate_required(params, [:url])
203
+
204
+ response = @client.post("/csc", params)
205
+ CscResponse.new(response)
206
+ end
207
+
208
+ # CSN Service - Company Snapshot
209
+ def get_company_snapshot(params)
210
+ validate_required(params, [:url])
211
+
212
+ response = @client.post("/csn", params)
213
+ CsnResponse.new(response)
214
+ end
215
+
216
+ # Nao Service - Phone Number Normalizer
217
+ def normalize_phone(params)
218
+ validate_required(params, [:phone])
219
+
220
+ response = @client.post("/nao", params)
221
+ NaoResponse.new(response)
222
+ end
223
+
224
+ # Naa Service - Address Normalizer
225
+ def normalize_address(params)
226
+ validate_required(params, [:address])
227
+
228
+ response = @client.post("/naa", params)
229
+ NaaResponse.new(response)
230
+ end
167
231
 
168
232
  private
169
233
 
@@ -1,4 +1,4 @@
1
- module CufinderRuby
1
+ module Cufinder
2
2
  # Base response structure for all CUFinder API responses
3
3
  class BaseResponse
4
4
  attr_accessor :query, :credit_count, :meta_data, :confidence_level
@@ -518,4 +518,87 @@ module CufinderRuby
518
518
  @companies = (data["companies"] || []).map { |c| Company.new(c) }
519
519
  end
520
520
  end
521
+
522
+ class BcdResponse < BaseResponse
523
+ attr_accessor :customers
524
+
525
+ def initialize(data = {})
526
+ super(data)
527
+ @customers = data["customers"] || []
528
+ end
529
+ end
530
+
531
+ class CcpResponse < BaseResponse
532
+ attr_accessor :customers
533
+
534
+ def initialize(data = {})
535
+ super(data)
536
+ @careers_page_url = data["careers_page_url"]
537
+ end
538
+ end
539
+
540
+ class IscResponse < BaseResponse
541
+ attr_accessor :is_saas
542
+
543
+ def initialize(data = {})
544
+ super(data)
545
+ @is_saas = data["is_saas"]
546
+ end
547
+ end
548
+
549
+ class CbcResponse < BaseResponse
550
+ attr_accessor :business_type
551
+
552
+ def initialize(data = {})
553
+ super(data)
554
+ @business_type = data["business_type"]
555
+ end
556
+ end
557
+
558
+ class CscResponse < BaseResponse
559
+ attr_accessor :mission_statement
560
+
561
+ def initialize(data = {})
562
+ super(data)
563
+ @mission_statement = data["mission_statement"]
564
+ end
565
+ end
566
+
567
+ class CsnSnapshotInfo
568
+ attr_accessor :icp, :target_industries, :target_personas, :value_proposition
569
+
570
+ def initialize(data = {})
571
+ @icp = data["icp"]
572
+ @target_industries = data["target_industries"] || []
573
+ @target_personas = data["target_personas"]
574
+ @value_proposition = data["value_proposition"]
575
+ end
576
+ end
577
+
578
+ class CsnResponse < BaseResponse
579
+ attr_accessor :company_snapshot
580
+
581
+ def initialize(data = {})
582
+ super(data)
583
+ @company_snapshot = data["company_snapshot"] ? CsnSnapshotInfo.new(data["company_snapshot"]) : nil
584
+ end
585
+ end
586
+
587
+ class NaoResponse < BaseResponse
588
+ attr_accessor :phone
589
+
590
+ def initialize(data = {})
591
+ super(data)
592
+ @phone = data["phone"]
593
+ end
594
+ end
595
+
596
+ class NaaResponse < BaseResponse
597
+ attr_accessor :address
598
+
599
+ def initialize(data = {})
600
+ super(data)
601
+ @address = data["address"]
602
+ end
603
+ end
521
604
  end
@@ -1,3 +1,3 @@
1
- module CufinderRuby
2
- VERSION = "0.0.1"
1
+ module Cufinder
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/cufinder_ruby.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  require "cufinder_ruby/version"
2
+ require "cufinder_ruby/base_api_client"
2
3
  require "cufinder_ruby/client"
3
- require "cufinder_ruby/sdk"
4
4
  require "cufinder_ruby/errors"
5
5
 
6
- module CufinderRuby
6
+ module Cufinder
7
7
  class Error < StandardError; end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cufinder-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - CUFinder Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-12 00:00:00.000000000 Z
11
+ date: 2026-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -89,15 +89,16 @@ extra_rdoc_files: []
89
89
  files:
90
90
  - ".gitignore"
91
91
  - ".rspec"
92
+ - CHANGELOG.md
92
93
  - Gemfile
93
94
  - LICENSE
94
95
  - README.md
95
96
  - Rakefile
96
97
  - cufinder-ruby.gemspec
97
98
  - lib/cufinder_ruby.rb
99
+ - lib/cufinder_ruby/base_api_client.rb
98
100
  - lib/cufinder_ruby/client.rb
99
101
  - lib/cufinder_ruby/errors.rb
100
- - lib/cufinder_ruby/sdk.rb
101
102
  - lib/cufinder_ruby/services.rb
102
103
  - lib/cufinder_ruby/types.rb
103
104
  - lib/cufinder_ruby/version.rb
@@ -1,99 +0,0 @@
1
- require "cufinder_ruby/client"
2
- require "cufinder_ruby/services"
3
-
4
- module CufinderRuby
5
- class SDK
6
- attr_reader :client, :services
7
-
8
- def initialize(api_key:, base_url: "https://api.cufinder.io/v2", timeout: 30, max_retries: 3)
9
- @client = Client.new(
10
- api_key: api_key,
11
- base_url: base_url,
12
- timeout: timeout,
13
- max_retries: max_retries
14
- )
15
- @services = Services.new(@client)
16
- end
17
-
18
- # Convenience methods for each service
19
- def cuf(company_name:, country_code:)
20
- @services.get_domain(company_name: company_name, country_code: country_code)
21
- end
22
-
23
- def lcuf(company_name:)
24
- @services.get_linkedin_url(company_name: company_name)
25
- end
26
-
27
- def dtc(company_website:)
28
- @services.get_company_name(company_website: company_website)
29
- end
30
-
31
- def dte(company_website:)
32
- @services.get_emails(company_website: company_website)
33
- end
34
-
35
- def ntp(company_name:)
36
- @services.get_phones(company_name: company_name)
37
- end
38
-
39
- def rel(email:)
40
- @services.get_person_by_email(email: email)
41
- end
42
-
43
- def fcl(query:)
44
- @services.find_company_lookalikes(query: query)
45
- end
46
-
47
- def elf(query:)
48
- @services.enrich_linkedin_fundraising(query: query)
49
- end
50
-
51
- def car(query:)
52
- @services.get_annual_revenue(query: query)
53
- end
54
-
55
- def fcc(query:)
56
- @services.find_company_children(query: query)
57
- end
58
-
59
- def fts(query:)
60
- @services.find_tech_stack(query: query)
61
- end
62
-
63
- def epp(linkedin_url:)
64
- @services.enrich_person_profile(linkedin_url: linkedin_url)
65
- end
66
-
67
- def fwe(linkedin_url:)
68
- @services.find_work_email(linkedin_url: linkedin_url)
69
- end
70
-
71
- def tep(full_name:, company:)
72
- @services.get_title_email_phone(full_name: full_name, company: company)
73
- end
74
-
75
- def enc(query:)
76
- @services.enrich_company(query: query)
77
- end
78
-
79
- def cec(query:)
80
- @services.get_company_employee_count(query: query)
81
- end
82
-
83
- def clo(query:)
84
- @services.get_company_locations(query: query)
85
- end
86
-
87
- def cse(**params)
88
- @services.search_companies(params)
89
- end
90
-
91
- def pse(**params)
92
- @services.search_people(params)
93
- end
94
-
95
- def lbs(**params)
96
- @services.search_local_businesses(params)
97
- end
98
- end
99
- end