emailhunter 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 +4 -4
- data/README.md +83 -63
- data/emailhunter.gemspec +19 -7
- data/lib/email_hunter/account.rb +16 -7
- data/lib/email_hunter/api.rb +42 -11
- data/lib/email_hunter/company.rb +61 -0
- data/lib/email_hunter/count.rb +17 -9
- data/lib/email_hunter/exist.rb +14 -8
- data/lib/email_hunter/finder.rb +20 -6
- data/lib/email_hunter/people.rb +61 -0
- data/lib/email_hunter/search.rb +25 -11
- data/lib/email_hunter/verify.rb +15 -10
- data/lib/email_hunter/version.rb +1 -1
- metadata +14 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4783ca3e6457c776875732582c772c3d1d112934384922f9816f22a401107b0
|
4
|
+
data.tar.gz: 2a12c9cb64c3ad77b9e902d0113ddc68b4c56c04c0530aa21e72b02523f9f58b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e2b5c05259327cd62ceef07587518f755e57d4d577fff2bd4f38f1afba24b920d7d8ab0528ac27d86c80d53e4bdd3984a0a7d992a2d26d7f30141945b06bc32
|
7
|
+
data.tar.gz: 1ab01074fbe447ad24b2d39ce89bdf444b0b2cbdf280a615b94a17642bc350147135468d2651a7558fb00f6dc2cf271ca946e0291e3f5529d500d12bbc3f71d2
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# EmailHunter
|
2
2
|
|
3
|
-
A
|
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
|
-
|
13
|
+
Then execute:
|
16
14
|
|
17
|
-
|
15
|
+
```sh
|
16
|
+
$ bundle install
|
17
|
+
```
|
18
18
|
|
19
|
-
Or install it yourself
|
19
|
+
Or install it yourself with:
|
20
20
|
|
21
|
-
|
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
|
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
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
47
|
-
|
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
|
-
|
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
|
-
|
69
|
-
|
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.
|
78
|
+
result = email_hunter.finder('gmail.com', 'Davide', 'Santangelo')
|
76
79
|
```
|
77
80
|
|
78
|
-
|
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
|
-
|
101
|
-
|
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
|
-
|
97
|
+
#### Response Fields:
|
107
98
|
```ruby
|
108
99
|
result.fetch(:data)
|
109
100
|
result.fetch(:meta)
|
110
101
|
```
|
111
102
|
|
112
|
-
|
113
|
-
|
103
|
+
### 5. Company Information API (New Feature)
|
104
|
+
Retrieve company details using a domain name.
|
105
|
+
|
114
106
|
```ruby
|
115
|
-
email_hunter.
|
107
|
+
result = email_hunter.company('stripe.com')
|
116
108
|
```
|
117
109
|
|
118
|
-
|
110
|
+
#### Response Fields:
|
119
111
|
```ruby
|
120
|
-
result.fetch(:
|
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":"
|
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/[
|
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
|
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
|
-
|
2
|
-
|
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
|
12
|
-
spec.description =
|
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
|
-
|
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
|
|
30
|
+
# Development dependencies
|
20
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 = '>=
|
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
|
data/lib/email_hunter/account.rb
CHANGED
@@ -3,10 +3,10 @@
|
|
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
|
8
|
+
API_URL = 'https://api.hunter.io/v2/account'
|
9
|
+
|
10
10
|
attr_reader :result, :first_name, :last_name, :email, :plan_name, :plan_level, :reset_date, :team_id, :calls,
|
11
11
|
:requests
|
12
12
|
|
@@ -15,15 +15,24 @@ module EmailHunter
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def hunt
|
18
|
-
response =
|
19
|
-
|
18
|
+
response = fetch_account_data
|
19
|
+
parse_response(response)
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
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)
|
27
36
|
end
|
28
37
|
end
|
29
38
|
end
|
data/lib/email_hunter/api.rb
CHANGED
@@ -2,14 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'uri'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
20
|
+
execute_hunt(Search, domain, params)
|
23
21
|
end
|
24
22
|
|
25
23
|
# Email exist API
|
26
24
|
def exist(email)
|
27
|
-
|
25
|
+
execute_hunt(Exist, email)
|
28
26
|
end
|
29
27
|
|
30
28
|
# Email verify API
|
31
29
|
def verify(email)
|
32
|
-
|
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
|
-
|
40
|
+
execute_hunt(Count, domain)
|
43
41
|
end
|
44
42
|
|
45
43
|
# Account Information API
|
46
44
|
def account
|
47
|
-
|
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
|
data/lib/email_hunter/count.rb
CHANGED
@@ -1,27 +1,35 @@
|
|
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
|
-
|
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
|
-
|
17
|
+
response_data = fetch_count_data
|
18
|
+
return nil if response_data.empty?
|
19
|
+
|
20
|
+
Struct.new(*response_data.keys).new(*response_data.values)
|
16
21
|
end
|
17
22
|
|
18
|
-
|
19
|
-
@data ||= begin
|
20
|
-
response = Faraday.new("#{API_COUNT_URL}domain=#{domain}").get
|
23
|
+
private
|
21
24
|
|
22
|
-
|
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?
|
23
31
|
|
24
|
-
JSON.parse(response.body,
|
32
|
+
JSON.parse(response.body, symbolize_names: true)
|
25
33
|
end
|
26
34
|
end
|
27
35
|
end
|
data/lib/email_hunter/exist.rb
CHANGED
@@ -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
|
-
|
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,16 +15,22 @@ module EmailHunter
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def hunt
|
18
|
-
|
18
|
+
response_data = fetch_exist_data
|
19
|
+
return nil if response_data.empty?
|
20
|
+
|
21
|
+
Struct.new(*response_data.keys).new(*response_data.values)
|
19
22
|
end
|
20
23
|
|
21
|
-
|
22
|
-
@data ||= begin
|
23
|
-
response = Faraday.new("#{API_EXIST_URL}email=#{email}&api_key=#{key}").get
|
24
|
+
private
|
24
25
|
|
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
|
+
|
25
31
|
return {} unless response.success?
|
26
32
|
|
27
|
-
JSON.parse(response.body,
|
33
|
+
JSON.parse(response.body, symbolize_names: true)
|
28
34
|
end
|
29
35
|
end
|
30
36
|
end
|
data/lib/email_hunter/finder.rb
CHANGED
@@ -3,10 +3,10 @@
|
|
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
|
8
|
+
API_FINDER_URL = 'https://api.hunter.io/v2/email-finder'
|
9
|
+
|
10
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)
|
@@ -22,12 +22,26 @@ module EmailHunter
|
|
22
22
|
|
23
23
|
def data
|
24
24
|
@data ||= begin
|
25
|
-
response =
|
26
|
-
|
27
|
-
return
|
25
|
+
response = fetch_finder_data
|
26
|
+
|
27
|
+
return {} unless response.success?
|
28
28
|
|
29
|
-
JSON.parse(response.body,
|
29
|
+
JSON.parse(response.body, symbolize_names: true)
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
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)
|
45
|
+
end
|
32
46
|
end
|
33
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
|
data/lib/email_hunter/search.rb
CHANGED
@@ -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
|
-
|
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,24 +16,38 @@ module EmailHunter
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def hunt
|
19
|
-
|
19
|
+
response_data = fetch_search_data
|
20
|
+
return nil if response_data.empty?
|
21
|
+
|
22
|
+
Struct.new(*response_data.keys).new(*response_data.values)
|
20
23
|
end
|
21
24
|
|
25
|
+
private
|
26
|
+
|
22
27
|
def limit
|
23
|
-
params
|
28
|
+
params.fetch(:limit, 10).to_i
|
24
29
|
end
|
25
30
|
|
26
31
|
def offset
|
27
|
-
params
|
32
|
+
params.fetch(:offset, 0).to_i
|
28
33
|
end
|
29
34
|
|
30
|
-
def
|
31
|
-
@
|
32
|
-
|
33
|
-
|
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
|
+
|
34
48
|
return {} unless response.success?
|
35
49
|
|
36
|
-
JSON.parse(response.body,
|
50
|
+
JSON.parse(response.body, symbolize_names: true)
|
37
51
|
end
|
38
52
|
end
|
39
53
|
end
|
data/lib/email_hunter/verify.rb
CHANGED
@@ -3,12 +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
|
-
|
11
|
-
|
8
|
+
API_URL = 'https://api.hunter.io/v2/email-verifier'
|
9
|
+
|
10
|
+
attr_reader :email, :key
|
12
11
|
|
13
12
|
def initialize(email, key)
|
14
13
|
@email = email
|
@@ -16,16 +15,22 @@ module EmailHunter
|
|
16
15
|
end
|
17
16
|
|
18
17
|
def hunt
|
19
|
-
|
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
|
-
|
23
|
-
@data ||= begin
|
24
|
-
response = Faraday.new("#{API_VERIFY_URL}email=#{email}&api_key=#{key}").get
|
24
|
+
private
|
25
25
|
|
26
|
-
|
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?
|
27
32
|
|
28
|
-
JSON.parse(response.body,
|
33
|
+
JSON.parse(response.body, symbolize_names: true)
|
29
34
|
end
|
30
35
|
end
|
31
36
|
end
|
data/lib/email_hunter/version.rb
CHANGED
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: 1.
|
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:
|
11
|
+
date: 2025-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,8 +108,10 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
-
description:
|
112
|
-
|
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:
|
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.
|
164
|
+
rubygems_version: 3.3.26
|
160
165
|
signing_key:
|
161
166
|
specification_version: 4
|
162
|
-
summary: A tiny
|
167
|
+
summary: A tiny Ruby wrapper around the Hunter.io API
|
163
168
|
test_files: []
|