emailhunter 0.9.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: d9cca816b859af71470e2f574c274e195f40957e90a2824874f6f674a39d0198
4
- data.tar.gz: a77dff70b14ff58e51da7ba5593aa6b224dcfed6f15da4781a77c0e77ed4ff49
3
+ metadata.gz: b4783ca3e6457c776875732582c772c3d1d112934384922f9816f22a401107b0
4
+ data.tar.gz: 2a12c9cb64c3ad77b9e902d0113ddc68b4c56c04c0530aa21e72b02523f9f58b
5
5
  SHA512:
6
- metadata.gz: 9b890e80434096d88af8414aaa387a28d1ff0afbbdc177eddd8284e191092d8335b06c50d874bbc48c23e5d80271b289db98ad85c63c5664e0819f90e3545227
7
- data.tar.gz: fab3c8de09ef1c3ae7ad59c82519422123982e3f996d9b53b5f65bd6b7cb15e98139542d5541b2f6e289f394772b996a141bf89e01528c46a9934bb10ad42200
6
+ metadata.gz: 5e2b5c05259327cd62ceef07587518f755e57d4d577fff2bd4f38f1afba24b920d7d8ab0528ac27d86c80d53e4bdd3984a0a7d992a2d26d7f30141945b06bc32
7
+ data.tar.gz: 1ab01074fbe447ad24b2d39ce89bdf444b0b2cbdf280a615b94a17642bc350147135468d2651a7558fb00f6dc2cf271ca946e0291e3f5529d500d12bbc3f71d2
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # Emailhunter
1
+ # EmailHunter
2
2
 
3
- A tiny ruby wrapper around Hunter (former Email Hunter) API. Direct access to all the web's email addresses.
4
-
5
- UPDATE (2016-12-02): gem updated with V2 API.
3
+ A lightweight Ruby wrapper around Hunter (formerly Email Hunter) API, providing direct access to email search, verification, and company insights.
6
4
 
7
5
  ## Installation
8
6
 
@@ -12,30 +10,37 @@ Add this line to your application's Gemfile:
12
10
  gem 'emailhunter'
13
11
  ```
14
12
 
15
- And then execute:
13
+ Then execute:
16
14
 
17
- $ bundle
15
+ ```sh
16
+ $ bundle install
17
+ ```
18
18
 
19
- Or install it yourself as:
19
+ Or install it yourself with:
20
20
 
21
- $ gem install emailhunter
21
+ ```sh
22
+ $ gem install emailhunter
23
+ ```
22
24
 
23
25
  ## Usage
24
26
 
25
27
  ```ruby
26
28
  require 'emailhunter'
27
- email_hunter = EmailHunter.new('Your secret API key')
28
-
29
+ email_hunter = EmailHunter.new('Your API Key')
29
30
  ```
30
- Your secret API key. You can generate it in your dashboard from https://hunter.io
31
31
 
32
- ## Domain search API
33
- Returns all the email addresses found using one given domain name, with our sources.
32
+ Your API key can be generated in your [Hunter dashboard](https://hunter.io).
33
+
34
+ ## Features
35
+
36
+ ### 1. Domain Search API
37
+ Retrieve all email addresses associated with a given domain.
38
+
34
39
  ```ruby
35
40
  result = email_hunter.search('stripe.com')
36
41
  ```
37
42
 
38
- ## Accessing domain search response
43
+ #### Response Fields:
39
44
  ```ruby
40
45
  result.fetch(:meta)
41
46
  result.fetch(:webmail)
@@ -43,13 +48,15 @@ result.fetch(:emails)
43
48
  result.fetch(:pattern)
44
49
  result.fetch(:domain)
45
50
  ```
46
- ## Email Verify API
47
- Allows you to verify the deliverability of an email address.
51
+
52
+ ### 2. Email Verification API
53
+ Check the deliverability of an email address.
54
+
48
55
  ```ruby
49
- email_hunter.verify('bonjour@firmapi.com')
56
+ result = email_hunter.verify('bonjour@firmapi.com')
50
57
  ```
51
58
 
52
- ## Accessing email verify response
59
+ #### Response Fields:
53
60
  ```ruby
54
61
  result.fetch(:result)
55
62
  result.fetch(:score)
@@ -62,33 +69,16 @@ result.fetch(:smtp_check)
62
69
  result.fetch(:accept_all)
63
70
  result.fetch(:sources)
64
71
  result.fetch(:meta)
65
-
66
72
  ```
67
73
 
68
- ## Email Exist API (only for V1)
69
- This API call is deprecated, please use the email verification call instead.
70
-
71
-
72
- This API endpoint allows you to check if a given email address has been found on the web. If it has been found, it returns all the sources with the dates of the last crawls.
74
+ ### 3. Email Finder API
75
+ Guess the most likely email of a person using their first name, last name, and domain.
73
76
 
74
77
  ```ruby
75
- email_hunter.exist('bonjour@firmapi.com')
78
+ result = email_hunter.finder('gmail.com', 'Davide', 'Santangelo')
76
79
  ```
77
80
 
78
- ## Accessing email verify response
79
- ```ruby
80
- result.status
81
- result.email
82
- result.exist
83
- result.sources
84
- ```
85
-
86
- ## Finder API (legacy generate)
87
- Guesses the most likely email of a person from his first name, his last name and a domain name.
88
- ```ruby
89
- email_hunter.finder('gmail.com', 'Davide', 'Santangelo')
90
- ```
91
- ## Accessing finder response
81
+ #### Response Fields:
92
82
  ```ruby
93
83
  result.fetch(:email)
94
84
  result.fetch(:score)
@@ -97,55 +87,85 @@ result.fetch(:domain)
97
87
  result.fetch(:meta)
98
88
  ```
99
89
 
100
- ## Count API
101
- Returns the number of email addresses found for a domain. This is a FREE API call.
90
+ ### 4. Count API
91
+ Retrieve the number of email addresses associated with a domain (FREE API call).
92
+
102
93
  ```ruby
103
- email_hunter.count('gmail.com')
94
+ result = email_hunter.count('gmail.com')
104
95
  ```
105
96
 
106
- ## Accessing count response
97
+ #### Response Fields:
107
98
  ```ruby
108
99
  result.fetch(:data)
109
100
  result.fetch(:meta)
110
101
  ```
111
102
 
112
- ## Account Information
113
- This method enables you to get information regarding your Hunter account at any time. This call is free.
103
+ ### 5. Company Information API (New Feature)
104
+ Retrieve company details using a domain name.
105
+
114
106
  ```ruby
115
- email_hunter.account
107
+ result = email_hunter.company('stripe.com')
116
108
  ```
117
109
 
118
- ## Accessing account response
110
+ #### Response Fields:
119
111
  ```ruby
120
- result.fetch(:data)
112
+ result.fetch(:name)
113
+ result.fetch(:industry)
114
+ result.fetch(:employees)
115
+ result.fetch(:country)
116
+ result.fetch(:meta)
121
117
  ```
122
118
 
119
+ ### 6. People Search API (New Feature)
120
+ Retrieve key individuals associated with a company based on a domain name.
121
+
122
+ ```ruby
123
+ result = email_hunter.people('stripe.com')
124
+ ```
125
+
126
+ #### Response Fields:
127
+ ```ruby
128
+ result.fetch(:employees)
129
+ result.fetch(:position)
130
+ result.fetch(:email)
131
+ result.fetch(:meta)
132
+ ```
133
+
134
+ ### 7. Account Information API
135
+ Retrieve details about your Hunter account.
136
+
137
+ ```ruby
138
+ result = email_hunter.account
139
+ ```
140
+
141
+ #### Response Example:
123
142
  ```json
124
- {
125
- "data":{
126
- "first_name":"Davide",
127
- "last_name":"Santangelo",
128
- "email":"davide.santangelo@gmail.com",
129
- "plan_name":"Free",
130
- "plan_level":0,
131
- "reset_date":"2019-06-29",
132
- "team_id":349,
133
- "calls":{
134
- "used":4,
135
- "available":50
143
+ {
144
+ "data": {
145
+ "first_name": "Davide",
146
+ "last_name": "Santangelo",
147
+ "email": "davide.santangelo@gmail.com",
148
+ "plan_name": "Free",
149
+ "plan_level": 0,
150
+ "reset_date": "2025-06-29",
151
+ "team_id": 349,
152
+ "calls": {
153
+ "used": 4,
154
+ "available": 50
136
155
  }
137
156
  }
138
157
  }
139
158
  ```
140
159
 
141
160
  ## License
142
- The emailhunter GEM is released under the MIT License.
143
161
 
162
+ The EmailHunter gem is released under the [MIT License](https://opensource.org/licenses/MIT).
144
163
 
145
164
  ## Contributing
146
165
 
147
- 1. Fork it ( https://github.com/[my-github-username]/emailhunter/fork )
166
+ 1. Fork it ( https://github.com/[your-github-username]/emailhunter/fork )
148
167
  2. Create your feature branch (`git checkout -b my-new-feature`)
149
- 3. Commit your changes (`git commit -am 'Add some feature'`)
168
+ 3. Commit your changes (`git commit -am 'Add new feature'`)
150
169
  4. Push to the branch (`git push origin my-new-feature`)
151
170
  5. Create a new Pull Request
171
+
data/emailhunter.gemspec CHANGED
@@ -1,6 +1,5 @@
1
- lib = File.expand_path('lib', __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require File.expand_path('lib/email_hunter/version', __dir__)
1
+ # Use require_relative to load the version file
2
+ require_relative 'lib/email_hunter/version'
4
3
 
5
4
  Gem::Specification.new do |spec|
6
5
  spec.name = 'emailhunter'
@@ -8,23 +7,36 @@ Gem::Specification.new do |spec|
8
7
  spec.authors = ['Davide Santangelo']
9
8
  spec.email = ['davide.santangelo@gmail.com']
10
9
 
11
- spec.summary = 'A tiny ruby wrapper around Hunter.io API '
12
- spec.description = 'A tiny ruby wrapper around Hunter.io API. Hunter.io helps sales people reach their targets and increase their sales. '
10
+ spec.summary = 'A tiny Ruby wrapper around the Hunter.io API'
11
+ spec.description = <<~DESC
12
+ EmailHunter is a minimalistic Ruby wrapper for the Hunter.io API.
13
+ It provides a straightforward interface to integrate Hunter.io's
14
+ email discovery capabilities into your sales and marketing workflows.
15
+ DESC
13
16
  spec.license = 'MIT'
17
+
18
+ # Adding additional metadata improves discoverability
19
+ spec.homepage = 'https://github.com/davidesantangelo/emailhunter'
20
+ spec.metadata = {
21
+ "source_code_uri" => "https://github.com/davidesantangelo/emailhunter"
22
+ }
14
23
 
15
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ # Automatically include all version-controlled files except tests and specs
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f =~ %r{^(test|spec|features)/} }
16
26
  spec.bindir = 'exe'
17
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
28
  spec.require_paths = ['lib']
19
29
 
20
- spec.add_development_dependency 'bundler', '~> 1.8'
30
+ # Development dependencies
31
+ spec.add_development_dependency 'bundler', '~> 2.1'
21
32
  spec.add_development_dependency 'rake', '~> 10.0'
22
33
  spec.add_development_dependency 'rspec'
23
34
  spec.add_development_dependency 'typhoeus'
24
35
  spec.add_development_dependency 'vcr'
25
36
 
26
- spec.required_ruby_version = '>= 1.9.3'
37
+ spec.required_ruby_version = '>= 3.0.0'
27
38
 
39
+ # Runtime dependencies
28
40
  spec.add_dependency 'faraday'
29
41
  spec.add_dependency 'json'
30
42
  end
@@ -3,26 +3,36 @@
3
3
  require 'faraday'
4
4
  require 'json'
5
5
 
6
- API_ACCOUNT_URL = 'https://api.hunter.io/v2/account?'
7
-
8
6
  module EmailHunter
9
7
  class Account
10
- attr_reader :result, :first_name, :last_name, :email, :plan_name, :plan_level, :reset_date, :team_id, :calls, :requests
8
+ API_URL = 'https://api.hunter.io/v2/account'
9
+
10
+ attr_reader :result, :first_name, :last_name, :email, :plan_name, :plan_level, :reset_date, :team_id, :calls,
11
+ :requests
11
12
 
12
13
  def initialize(key)
13
14
  @key = key
14
15
  end
15
16
 
16
17
  def hunt
17
- response = apiresponse
18
- Struct.new(*response.keys).new(*response.values) unless response.empty?
18
+ response = fetch_account_data
19
+ parse_response(response)
19
20
  end
20
21
 
21
22
  private
22
23
 
23
- def apiresponse
24
- response = Faraday.new("#{API_ACCOUNT_URL}&api_key=#{@key}").get
25
- response.success? ? JSON.parse(response.body, { symbolize_names: true }) : []
24
+ def fetch_account_data
25
+ connection = Faraday.new
26
+ connection.get(API_URL, api_key: @key)
27
+ end
28
+
29
+ def parse_response(response)
30
+ return nil unless response.success?
31
+
32
+ data = JSON.parse(response.body, symbolize_names: true)
33
+ return nil if data.empty?
34
+
35
+ Struct.new(*data.keys).new(*data.values)
26
36
  end
27
37
  end
28
38
  end
@@ -2,14 +2,12 @@
2
2
 
3
3
  require 'uri'
4
4
 
5
- require File.expand_path(File.join(File.dirname(__FILE__), 'exist'))
6
- require File.expand_path(File.join(File.dirname(__FILE__), 'search'))
7
- require File.expand_path(File.join(File.dirname(__FILE__), 'finder'))
8
- require File.expand_path(File.join(File.dirname(__FILE__), 'verify'))
9
- require File.expand_path(File.join(File.dirname(__FILE__), 'count'))
10
- require File.expand_path(File.join(File.dirname(__FILE__), 'account'))
5
+ %w[exist search finder verify count account company people].each do |file|
6
+ require_relative file
7
+ end
11
8
 
12
9
  module EmailHunter
10
+ # Main API client for EmailHunter services
13
11
  class Api
14
12
  attr_reader :key
15
13
 
@@ -19,17 +17,17 @@ module EmailHunter
19
17
 
20
18
  # Domain search API
21
19
  def search(domain, params = {})
22
- EmailHunter::Search.new(domain, key, params).hunt
20
+ execute_hunt(Search, domain, params)
23
21
  end
24
22
 
25
23
  # Email exist API
26
24
  def exist(email)
27
- EmailHunter::Exist.new(email, key).hunt
25
+ execute_hunt(Exist, email)
28
26
  end
29
27
 
30
28
  # Email verify API
31
29
  def verify(email)
32
- EmailHunter::Verify.new(email, key).hunt
30
+ execute_hunt(Verify, email)
33
31
  end
34
32
 
35
33
  # Email Finder API
@@ -39,12 +37,45 @@ module EmailHunter
39
37
 
40
38
  # Email Count API
41
39
  def count(domain)
42
- EmailHunter::Count.new(domain).hunt
40
+ execute_hunt(Count, domain)
43
41
  end
44
42
 
45
43
  # Account Information API
46
44
  def account
47
- EmailHunter::Account.new(key).hunt
45
+ execute_hunt(Account)
46
+ end
47
+
48
+ # Company Information API
49
+ def company(domain)
50
+ execute_hunt(Company, domain)
51
+ end
52
+
53
+ # People Information API
54
+ def people(domain)
55
+ execute_hunt(People, domain)
56
+ end
57
+
58
+ private
59
+
60
+ # Helper method to reduce repetition
61
+ def execute_hunt(klass, *args)
62
+ case klass.name.split('::').last
63
+ when 'Search'
64
+ # Search expects (domain, key, params)
65
+ domain, params = args
66
+ klass.new(domain, key, params || {}).hunt
67
+ when 'Count'
68
+ # Count doesn't need key
69
+ domain = args.first
70
+ klass.new(domain).hunt
71
+ when 'Account'
72
+ # Account only needs key
73
+ klass.new(key).hunt
74
+ else
75
+ # Other classes expect (value, key)
76
+ value = args.first
77
+ klass.new(value, key).hunt
78
+ end
48
79
  end
49
80
  end
50
81
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'json'
5
+ require 'ostruct'
6
+
7
+ module EmailHunter
8
+ class Company
9
+ API_URL = 'https://api.hunter.io/v2/companies/find'
10
+
11
+ attr_reader :domain, :key
12
+
13
+ def initialize(domain, key)
14
+ @domain = domain
15
+ @key = key
16
+ end
17
+
18
+ def hunt
19
+ response_data = fetch_company_data
20
+ return nil if response_data.empty?
21
+
22
+ # Convert nested data structure to a Struct
23
+ data = response_data[:data]
24
+ meta = response_data[:meta]
25
+
26
+ result = OpenStruct.new(
27
+ data: OpenStruct.new(data),
28
+ meta: OpenStruct.new(meta)
29
+ )
30
+
31
+ # Recursively convert nested hashes to OpenStructs for deeper access
32
+ convert_hash_to_struct(result.data, data)
33
+
34
+ result
35
+ end
36
+
37
+ private
38
+
39
+ def fetch_company_data
40
+ @fetch_company_data ||= begin
41
+ connection = Faraday.new
42
+ response = connection.get(API_URL, domain: domain, api_key: key)
43
+
44
+ return {} unless response.success?
45
+
46
+ JSON.parse(response.body, symbolize_names: true)
47
+ end
48
+ end
49
+
50
+ def convert_hash_to_struct(struct, hash)
51
+ hash.each do |key, value|
52
+ if value.is_a?(Hash)
53
+ struct[key] = OpenStruct.new(value)
54
+ convert_hash_to_struct(struct[key], value)
55
+ elsif value.is_a?(Array) && value.first.is_a?(Hash)
56
+ struct[key] = value.map { |item| OpenStruct.new(item) }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,26 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
2
4
  require 'json'
3
5
 
4
- API_COUNT_URL = 'https://api.hunter.io/v2/email-count?'.freeze
5
-
6
6
  module EmailHunter
7
7
  class Count
8
- attr_reader :data, :meta
8
+ API_URL = 'https://api.hunter.io/v2/email-count'
9
+
10
+ attr_reader :domain
9
11
 
10
12
  def initialize(domain)
11
13
  @domain = domain
12
14
  end
13
15
 
14
16
  def hunt
15
- response = apiresponse
16
- Struct.new(*response.keys).new(*response.values) unless response.empty?
17
+ response_data = fetch_count_data
18
+ return nil if response_data.empty?
19
+
20
+ Struct.new(*response_data.keys).new(*response_data.values)
17
21
  end
18
22
 
19
23
  private
20
24
 
21
- def apiresponse
22
- response = Faraday.new("#{API_COUNT_URL}domain=#{@domain}").get
23
- response.success? ? JSON.parse(response.body, { symbolize_names: true }) : []
25
+ def fetch_count_data
26
+ @fetch_count_data ||= begin
27
+ connection = Faraday.new
28
+ response = connection.get(API_URL, domain: domain)
29
+
30
+ return {} unless response.success?
31
+
32
+ JSON.parse(response.body, symbolize_names: true)
33
+ end
24
34
  end
25
35
  end
26
36
  end
@@ -3,11 +3,11 @@
3
3
  require 'faraday'
4
4
  require 'json'
5
5
 
6
- API_EXIST_URL = 'https://api.emailhunter.co/v1/exist?'
7
-
8
6
  module EmailHunter
9
7
  class Exist
10
- attr_reader :status, :email, :exist, :sources
8
+ API_URL = 'https://api.emailhunter.co/v1/exist'
9
+
10
+ attr_reader :email, :key
11
11
 
12
12
  def initialize(email, key)
13
13
  @email = email
@@ -15,15 +15,23 @@ module EmailHunter
15
15
  end
16
16
 
17
17
  def hunt
18
- response = apiresponse
19
- Struct.new(*response.keys).new(*response.values) unless response.empty?
18
+ response_data = fetch_exist_data
19
+ return nil if response_data.empty?
20
+
21
+ Struct.new(*response_data.keys).new(*response_data.values)
20
22
  end
21
23
 
22
24
  private
23
25
 
24
- def apiresponse
25
- response = Faraday.new("#{API_EXIST_URL}email=#{@email}&api_key=#{@key}").get
26
- response.success? ? JSON.parse(response.body, { symbolize_names: true }) : []
26
+ def fetch_exist_data
27
+ @fetch_exist_data ||= begin
28
+ connection = Faraday.new
29
+ response = connection.get(API_URL, email: email, api_key: key)
30
+
31
+ return {} unless response.success?
32
+
33
+ JSON.parse(response.body, symbolize_names: true)
34
+ end
27
35
  end
28
36
  end
29
37
  end
@@ -3,11 +3,11 @@
3
3
  require 'faraday'
4
4
  require 'json'
5
5
 
6
- API_FINDER_URL = 'https://api.hunter.io/v2/email-finder?'
7
-
8
6
  module EmailHunter
9
7
  class Finder
10
- attr_reader :email, :score, :sources, :domain, :meta
8
+ API_FINDER_URL = 'https://api.hunter.io/v2/email-finder'
9
+
10
+ attr_reader :email, :score, :sources, :domain, :meta, :key, :first_name, :last_name
11
11
 
12
12
  def initialize(domain, first_name, last_name, key)
13
13
  @domain = domain
@@ -17,15 +17,31 @@ module EmailHunter
17
17
  end
18
18
 
19
19
  def hunt
20
- response = apiresponse
21
- Struct.new(*response.keys).new(*response.values) unless response.empty?
20
+ Struct.new(*data.keys).new(*data.values)
21
+ end
22
+
23
+ def data
24
+ @data ||= begin
25
+ response = fetch_finder_data
26
+
27
+ return {} unless response.success?
28
+
29
+ JSON.parse(response.body, symbolize_names: true)
30
+ end
22
31
  end
23
32
 
24
33
  private
25
34
 
26
- def apiresponse
27
- response = Faraday.new("#{API_FINDER_URL}domain=#{@domain}&first_name=#{@first_name}&last_name=#{@last_name}&api_key=#{@key}").get
28
- response.success? ? JSON.parse(response.body, { symbolize_names: true }) : []
35
+ def fetch_finder_data
36
+ connection = Faraday.new
37
+ params = {
38
+ domain: domain,
39
+ first_name: first_name,
40
+ last_name: last_name,
41
+ api_key: key
42
+ }
43
+
44
+ connection.get(API_FINDER_URL, params)
29
45
  end
30
46
  end
31
47
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'json'
5
+ require 'ostruct'
6
+
7
+ module EmailHunter
8
+ class People
9
+ API_URL = 'https://api.hunter.io/v2/people/find'
10
+
11
+ attr_reader :email, :key
12
+
13
+ def initialize(email, key)
14
+ @email = email
15
+ @key = key
16
+ end
17
+
18
+ def hunt
19
+ response_data = fetch_people_data
20
+ return nil if response_data.empty?
21
+
22
+ # Convert nested data structure to a Struct
23
+ data = response_data[:data]
24
+ meta = response_data[:meta]
25
+
26
+ result = OpenStruct.new(
27
+ data: OpenStruct.new(data),
28
+ meta: OpenStruct.new(meta)
29
+ )
30
+
31
+ # Recursively convert nested hashes to OpenStructs for deeper access
32
+ convert_hash_to_struct(result.data, data)
33
+
34
+ result
35
+ end
36
+
37
+ private
38
+
39
+ def fetch_people_data
40
+ @fetch_people_data ||= begin
41
+ connection = Faraday.new
42
+ response = connection.get(API_URL, email: email, api_key: key)
43
+
44
+ return {} unless response.success?
45
+
46
+ JSON.parse(response.body, symbolize_names: true)
47
+ end
48
+ end
49
+
50
+ def convert_hash_to_struct(struct, hash)
51
+ hash.each do |key, value|
52
+ if value.is_a?(Hash)
53
+ struct[key] = OpenStruct.new(value)
54
+ convert_hash_to_struct(struct[key], value)
55
+ elsif value.is_a?(Array) && value.first.is_a?(Hash)
56
+ struct[key] = value.map { |item| OpenStruct.new(item) }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -3,11 +3,11 @@
3
3
  require 'faraday'
4
4
  require 'json'
5
5
 
6
- API_SEARCH_URL = 'https://api.hunter.io/v2/domain-search?'
7
-
8
6
  module EmailHunter
9
7
  class Search
10
- attr_reader :meta, :webmail, :emails, :pattern, :domain
8
+ API_URL = 'https://api.hunter.io/v2/domain-search'
9
+
10
+ attr_reader :domain, :key, :params
11
11
 
12
12
  def initialize(domain, key, params = {})
13
13
  @domain = domain
@@ -16,15 +16,39 @@ module EmailHunter
16
16
  end
17
17
 
18
18
  def hunt
19
- response = apiresponse
20
- Struct.new(*response.keys).new(*response.values) unless response.empty?
19
+ response_data = fetch_search_data
20
+ return nil if response_data.empty?
21
+
22
+ Struct.new(*response_data.keys).new(*response_data.values)
21
23
  end
22
24
 
23
25
  private
24
26
 
25
- def apiresponse
26
- response = Faraday.new("#{API_SEARCH_URL}domain=#{@domain}&api_key=#{@key}&type=#{@params[:type]}&offset=#{@params[:offset]}&limit=#{@params[:limit]}").get
27
- response.success? ? JSON.parse(response.body, { symbolize_names: true }) : []
27
+ def limit
28
+ params.fetch(:limit, 10).to_i
29
+ end
30
+
31
+ def offset
32
+ params.fetch(:offset, 0).to_i
33
+ end
34
+
35
+ def fetch_search_data
36
+ @fetch_search_data ||= begin
37
+ connection = Faraday.new
38
+ request_params = {
39
+ domain: domain,
40
+ api_key: key,
41
+ offset: offset,
42
+ limit: limit
43
+ }
44
+
45
+ request_params[:type] = params[:type] if params[:type]
46
+ response = connection.get(API_URL, request_params)
47
+
48
+ return {} unless response.success?
49
+
50
+ JSON.parse(response.body, symbolize_names: true)
51
+ end
28
52
  end
29
53
  end
30
54
  end
@@ -3,11 +3,11 @@
3
3
  require 'faraday'
4
4
  require 'json'
5
5
 
6
- API_VERIFY_URL = 'https://api.hunter.io/v2/email-verifier?'
7
-
8
6
  module EmailHunter
9
7
  class Verify
10
- attr_reader :result, :score, :regexp, :gibberish, :disposable, :webmail, :mx_records, :smtp_server, :smtp_check, :accept_all, :sources, :meta
8
+ API_URL = 'https://api.hunter.io/v2/email-verifier'
9
+
10
+ attr_reader :email, :key
11
11
 
12
12
  def initialize(email, key)
13
13
  @email = email
@@ -15,15 +15,23 @@ module EmailHunter
15
15
  end
16
16
 
17
17
  def hunt
18
- response = apiresponse
19
- Struct.new(*response.keys).new(*response.values) unless response.empty?
18
+ response_data = fetch_verify_data
19
+ return nil if response_data.empty?
20
+
21
+ Struct.new(*response_data.keys).new(*response_data.values)
20
22
  end
21
23
 
22
24
  private
23
25
 
24
- def apiresponse
25
- response = Faraday.new("#{API_VERIFY_URL}email=#{@email}&api_key=#{@key}").get
26
- response.success? ? JSON.parse(response.body, { symbolize_names: true }) : []
26
+ def fetch_verify_data
27
+ @fetch_verify_data ||= begin
28
+ connection = Faraday.new
29
+ response = connection.get(API_URL, email: email, api_key: key)
30
+
31
+ return {} unless response.success?
32
+
33
+ JSON.parse(response.body, symbolize_names: true)
34
+ end
27
35
  end
28
36
  end
29
37
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EmailHunter
4
- VERSION = '0.9.0'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: emailhunter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davide Santangelo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-25 00:00:00.000000000 Z
11
+ date: 2025-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.8'
19
+ version: '2.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.8'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -108,8 +108,10 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
- description: 'A tiny ruby wrapper around Hunter.io API. Hunter.io helps sales people
112
- reach their targets and increase their sales. '
111
+ description: |
112
+ EmailHunter is a minimalistic Ruby wrapper for the Hunter.io API.
113
+ It provides a straightforward interface to integrate Hunter.io's
114
+ email discovery capabilities into your sales and marketing workflows.
113
115
  email:
114
116
  - davide.santangelo@gmail.com
115
117
  executables: []
@@ -130,17 +132,20 @@ files:
130
132
  - lib/email_hunter.rb
131
133
  - lib/email_hunter/account.rb
132
134
  - lib/email_hunter/api.rb
135
+ - lib/email_hunter/company.rb
133
136
  - lib/email_hunter/count.rb
134
137
  - lib/email_hunter/exist.rb
135
138
  - lib/email_hunter/finder.rb
139
+ - lib/email_hunter/people.rb
136
140
  - lib/email_hunter/search.rb
137
141
  - lib/email_hunter/verify.rb
138
142
  - lib/email_hunter/version.rb
139
143
  - lib/emailhunter.rb
140
- homepage:
144
+ homepage: https://github.com/davidesantangelo/emailhunter
141
145
  licenses:
142
146
  - MIT
143
- metadata: {}
147
+ metadata:
148
+ source_code_uri: https://github.com/davidesantangelo/emailhunter
144
149
  post_install_message:
145
150
  rdoc_options: []
146
151
  require_paths:
@@ -149,15 +154,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
149
154
  requirements:
150
155
  - - ">="
151
156
  - !ruby/object:Gem::Version
152
- version: 1.9.3
157
+ version: 3.0.0
153
158
  required_rubygems_version: !ruby/object:Gem::Requirement
154
159
  requirements:
155
160
  - - ">="
156
161
  - !ruby/object:Gem::Version
157
162
  version: '0'
158
163
  requirements: []
159
- rubygems_version: 3.0.8
164
+ rubygems_version: 3.3.26
160
165
  signing_key:
161
166
  specification_version: 4
162
- summary: A tiny ruby wrapper around Hunter.io API
167
+ summary: A tiny Ruby wrapper around the Hunter.io API
163
168
  test_files: []