emailhunter 1.0.0 → 2.0.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: aa2d9e9cc40ed470a2704f6cb875ade4b23bfb3f256ea535fc9ec772aa6d36f7
4
- data.tar.gz: b16e0822b7b5362ac3ce01435467db482dd867d97abd9a394b40394c7f67989a
3
+ metadata.gz: 2006e973eb996d6b4285c772c1af115e0d96091c403fff927381233f4ebeed94
4
+ data.tar.gz: 51433f5603cbb512baedb0342eb83f7655505ae4a4ee5f4deac18d317d8861ae
5
5
  SHA512:
6
- metadata.gz: 119c49c0e20229684a533a5bd000c33b5ba7470d2bc0ddcb075bfab48b705b1f0fe84e59227e2ed621c4ec27b335328189d7920b9db80037a5ad674864f94c22
7
- data.tar.gz: 1de4508d1b3289004fe3a5603e48c2f03ce1b5cd4334c6a2b2efcf846e52a4f9966a2224639a342d790f0bd05b1adbcb5e322358567cae8d979930e526d7f6f4
6
+ metadata.gz: 71a8eebcf7e1c0452a08d0d8ef4c79d980b1d48dbe0d898dab096b8012267dc2d7e7d4ade75ea861635dfa78690522b409993a60f065d3901299f85de161715f
7
+ data.tar.gz: 27c55a270224f1a9bc513c54903d0e5c16598bc939270dd331422dea13487c2fb733f5cb90f47efd83dd4628180730cf3baf9b1f90ff6ecff9bc1d2871c5103f
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in emailhunter.gemspec
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.io](https://hunter.io/) (formerly Email Hunter) API, providing direct access to email search, verification, and company insights.
6
4
 
7
5
  ## Installation
8
6
 
@@ -12,30 +10,51 @@ 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
+ **Core APIs:**
37
+
38
+ 1. **Domain Search API** - Retrieve all email addresses associated with a domain
39
+ 2. **Email Verification API** - Check the deliverability of an email address
40
+ 3. **Email Finder API** - Find the most likely email using name and domain
41
+ 4. **Count API** - Get the number of email addresses for a domain (FREE)
42
+ 5. **Account Information API** - Retrieve details about your Hunter account
43
+ 6. **Company Information API** - Get company details using a domain name
44
+ 7. **People Search API** - Find key individuals associated with a company
45
+
46
+ ---
47
+
48
+ ### 1. Domain Search API
49
+
50
+ Retrieve all email addresses associated with a given domain.
51
+
34
52
  ```ruby
35
53
  result = email_hunter.search('stripe.com')
36
54
  ```
37
55
 
38
- ## Accessing domain search response
56
+ #### Response Fields:
57
+
39
58
  ```ruby
40
59
  result.fetch(:meta)
41
60
  result.fetch(:webmail)
@@ -43,13 +62,17 @@ result.fetch(:emails)
43
62
  result.fetch(:pattern)
44
63
  result.fetch(:domain)
45
64
  ```
46
- ## Email Verify API
47
- Allows you to verify the deliverability of an email address.
65
+
66
+ ### 2. Email Verification API
67
+
68
+ Check the deliverability of an email address.
69
+
48
70
  ```ruby
49
- email_hunter.verify('bonjour@firmapi.com')
71
+ result = email_hunter.verify('bonjour@firmapi.com')
50
72
  ```
51
73
 
52
- ## Accessing email verify response
74
+ #### Response Fields:
75
+
53
76
  ```ruby
54
77
  result.fetch(:result)
55
78
  result.fetch(:score)
@@ -62,90 +85,281 @@ result.fetch(:smtp_check)
62
85
  result.fetch(:accept_all)
63
86
  result.fetch(:sources)
64
87
  result.fetch(:meta)
88
+ ```
89
+
90
+ ### 3. Email Finder API
91
+
92
+ Guess the most likely email of a person using their first name, last name, and domain.
93
+
94
+ ```ruby
95
+ result = email_hunter.finder('gmail.com', 'Davide', 'Santangelo')
96
+ ```
97
+
98
+ #### Response Fields:
99
+
100
+ ```ruby
101
+ result.fetch(:email)
102
+ result.fetch(:score)
103
+ result.fetch(:sources)
104
+ result.fetch(:domain)
105
+ result.fetch(:meta)
106
+ ```
107
+
108
+ ### 4. Count API
65
109
 
110
+ Retrieve the number of email addresses associated with a domain (FREE API call).
111
+
112
+ ```ruby
113
+ result = email_hunter.count('gmail.com')
66
114
  ```
67
115
 
68
- ## Email Exist API (only for V1)
69
- This API call is deprecated, please use the email verification call instead.
116
+ #### Response Fields:
117
+
118
+ ```ruby
119
+ result.fetch(:data)
120
+ result.fetch(:meta)
121
+ ```
70
122
 
123
+ ### 5. Company Information API (New Feature)
71
124
 
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.
125
+ Retrieve company details using a domain name.
73
126
 
74
127
  ```ruby
75
- email_hunter.exist('bonjour@firmapi.com')
128
+ result = email_hunter.company('stripe.com')
76
129
  ```
77
130
 
78
- ## Accessing email verify response
131
+ #### Response Fields:
132
+
79
133
  ```ruby
80
- result.status
81
- result.email
82
- result.exist
83
- result.sources
134
+ result.fetch(:name)
135
+ result.fetch(:industry)
136
+ result.fetch(:employees)
137
+ result.fetch(:country)
138
+ result.fetch(:meta)
84
139
  ```
85
140
 
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.
141
+ ### 6. People Search API (New Feature)
142
+
143
+ Retrieve key individuals associated with a company based on a domain name.
144
+
88
145
  ```ruby
89
- email_hunter.finder('gmail.com', 'Davide', 'Santangelo')
146
+ result = email_hunter.people('stripe.com')
90
147
  ```
91
- ## Accessing finder response
148
+
149
+ #### Response Fields:
150
+
92
151
  ```ruby
152
+ result.fetch(:employees)
153
+ result.fetch(:position)
93
154
  result.fetch(:email)
94
- result.fetch(:score)
95
- result.fetch(:sources)
96
- result.fetch(:domain)
97
155
  result.fetch(:meta)
98
156
  ```
99
157
 
100
- ## Count API
101
- Returns the number of email addresses found for a domain. This is a FREE API call.
158
+ ### 7. Discover API (New in v2.0.0)
159
+
160
+ Search for companies using natural language queries.
161
+
102
162
  ```ruby
103
- email_hunter.count('gmail.com')
163
+ result = email_hunter.discover('US-based Software companies', limit: 10)
104
164
  ```
105
165
 
106
- ## Accessing count response
166
+ #### Response Fields:
167
+
107
168
  ```ruby
108
- result.fetch(:data)
109
- result.fetch(:meta)
169
+ result.data # Array of companies
170
+ result.meta.fetch(:results)
171
+ result.meta.fetch(:limit)
172
+ result.meta.fetch(:offset)
173
+ ```
174
+
175
+ ### 8. Leads Management API (New in v2.0.0)
176
+
177
+ Manage your leads stored in Hunter.
178
+
179
+ #### List Leads:
180
+
181
+ ```ruby
182
+ result = email_hunter.leads(limit: 20, offset: 0)
110
183
  ```
111
184
 
112
- ## Account Information
113
- This method enables you to get information regarding your Hunter account at any time. This call is free.
185
+ #### Create Lead:
186
+
114
187
  ```ruby
115
- email_hunter.account
188
+ lead_data = {
189
+ email: 'john@example.com',
190
+ first_name: 'John',
191
+ last_name: 'Doe',
192
+ company: 'Example Inc',
193
+ position: 'CEO'
194
+ }
195
+ result = email_hunter.lead_create(lead_data)
116
196
  ```
117
197
 
118
- ## Accessing account response
198
+ #### Update Lead:
199
+
119
200
  ```ruby
120
- result.fetch(:data)
201
+ update_data = { position: 'CTO' }
202
+ result = email_hunter.lead_update(lead_id, update_data)
203
+ ```
204
+
205
+ #### Delete Lead:
206
+
207
+ ```ruby
208
+ success = email_hunter.lead_delete(lead_id)
209
+ ```
210
+
211
+ #### Response Fields:
212
+
213
+ ```ruby
214
+ result.data.leads # Array of lead objects
215
+ result.data.leads.first.email
216
+ result.data.leads.first.company
217
+ result.meta.fetch(:count)
218
+ ```
219
+
220
+ ### 9. Campaigns Management API (New in v2.0.0)
221
+
222
+ Manage your email campaigns and recipients.
223
+
224
+ #### List Campaigns:
225
+
226
+ ```ruby
227
+ result = email_hunter.campaigns(limit: 20)
228
+ ```
229
+
230
+ #### Get Campaign Recipients:
231
+
232
+ ```ruby
233
+ result = email_hunter.campaign_recipients(campaign_id, limit: 20)
234
+ ```
235
+
236
+ #### Add Recipient to Campaign:
237
+
238
+ ```ruby
239
+ recipient_data = {
240
+ email: 'john@example.com',
241
+ first_name: 'John',
242
+ last_name: 'Doe'
243
+ }
244
+ result = email_hunter.campaign_add_recipient(campaign_id, recipient_data)
245
+ ```
246
+
247
+ #### Remove Recipient from Campaign:
248
+
249
+ ```ruby
250
+ success = email_hunter.campaign_delete_recipient(campaign_id, 'john@example.com')
251
+ ```
252
+
253
+ #### Response Fields:
254
+
255
+ ```ruby
256
+ result.data.campaigns # Array of campaign objects
257
+ result.data.recipients # Array of recipient objects
258
+ result.meta.fetch(:limit)
259
+ ```
260
+
261
+ ### 10. Lead Enrichment API (New in v2.0.0)
262
+
263
+ Enrich person data with 100+ attributes using email or LinkedIn.
264
+
265
+ ```ruby
266
+ # Using email
267
+ result = email_hunter.lead_enrichment(email: 'matt@hunter.io')
268
+
269
+ # Using LinkedIn
270
+ result = email_hunter.lead_enrichment(linkedin: 'matttharp')
271
+ ```
272
+
273
+ #### Response Fields:
274
+
275
+ ```ruby
276
+ result.data.name.fullName
277
+ result.data.email
278
+ result.data.location
279
+ result.data.timeZone
280
+ result.data.employment.domain
281
+ result.data.employment.title
282
+ result.data.employment.name
283
+ result.data.twitter.handle
284
+ result.data.linkedin.handle
285
+ result.meta.fetch(:email)
286
+ ```
287
+
288
+ ### 11. Company Enrichment API (New in v2.0.0)
289
+
290
+ Enrich company data with detailed firmographic information.
291
+
292
+ ```ruby
293
+ result = email_hunter.company_enrichment('stripe.com')
294
+ ```
295
+
296
+ #### Response Fields:
297
+
298
+ ```ruby
299
+ result.data.name
300
+ result.data.description
301
+ result.data.foundedYear
302
+ result.data.location
303
+ result.data.category.industry
304
+ result.data.metrics.employees
305
+ result.data.tech # Array of technologies used
306
+ result.data.site.emailAddresses
307
+ result.meta.fetch(:domain)
308
+ ```
309
+
310
+ ### 12. Combined Enrichment API (New in v2.0.0)
311
+
312
+ Get both lead and company data in a single call.
313
+
314
+ ```ruby
315
+ result = email_hunter.combined_enrichment(email: 'patrick@stripe.com')
316
+ ```
317
+
318
+ #### Response Fields:
319
+
320
+ ```ruby
321
+ result.lead.data # Lead enrichment data
322
+ result.company.data # Company enrichment data
323
+ result.meta.email
324
+ result.meta.domain
325
+ ```
326
+
327
+ ### 13. Account Information API
328
+
329
+ Retrieve details about your Hunter account.
330
+
331
+ ```ruby
332
+ result = email_hunter.account
121
333
  ```
122
334
 
335
+ #### Response Example:
336
+
123
337
  ```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
136
- }
137
- }
338
+ {
339
+ "data": {
340
+ "first_name": "Davide",
341
+ "last_name": "Santangelo",
342
+ "email": "davide.santangelo@gmail.com",
343
+ "plan_name": "Free",
344
+ "plan_level": 0,
345
+ "reset_date": "2025-06-29",
346
+ "team_id": 349,
347
+ "calls": {
348
+ "used": 4,
349
+ "available": 50
350
+ }
351
+ }
138
352
  }
139
353
  ```
140
354
 
141
355
  ## License
142
- The emailhunter GEM is released under the MIT License.
143
356
 
357
+ The EmailHunter gem is released under the [MIT License](https://opensource.org/licenses/MIT).
144
358
 
145
359
  ## Contributing
146
360
 
147
- 1. Fork it ( https://github.com/[my-github-username]/emailhunter/fork )
361
+ 1. Fork it ( https://github.com/[your-github-username]/emailhunter/fork )
148
362
  2. Create your feature branch (`git checkout -b my-new-feature`)
149
- 3. Commit your changes (`git commit -am 'Add some feature'`)
363
+ 3. Commit your changes (`git commit -am 'Add new feature'`)
150
364
  4. Push to the branch (`git push origin my-new-feature`)
151
365
  5. Create a new Pull Request
data/Rakefile CHANGED
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
data/bin/console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'emailhunter'
data/emailhunter.gemspec CHANGED
@@ -1,6 +1,7 @@
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
+ # frozen_string_literal: true
2
+
3
+ # Use require_relative to load the version file
4
+ require_relative 'lib/email_hunter/version'
4
5
 
5
6
  Gem::Specification.new do |spec|
6
7
  spec.name = 'emailhunter'
@@ -8,23 +9,36 @@ Gem::Specification.new do |spec|
8
9
  spec.authors = ['Davide Santangelo']
9
10
  spec.email = ['davide.santangelo@gmail.com']
10
11
 
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. '
12
+ spec.summary = 'A tiny Ruby wrapper around the Hunter.io API'
13
+ spec.description = <<~DESC
14
+ EmailHunter is a minimalistic Ruby wrapper for the Hunter.io API.
15
+ It provides a straightforward interface to integrate Hunter.io's
16
+ email discovery capabilities into your sales and marketing workflows.
17
+ DESC
13
18
  spec.license = 'MIT'
14
19
 
15
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ # Adding additional metadata improves discoverability
21
+ spec.homepage = 'https://github.com/davidesantangelo/emailhunter'
22
+ spec.metadata = {
23
+ 'source_code_uri' => 'https://github.com/davidesantangelo/emailhunter'
24
+ }
25
+
26
+ # Automatically include all version-controlled files except tests and specs
27
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f =~ %r{^(test|spec|features)/} }
16
28
  spec.bindir = 'exe'
17
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
30
  spec.require_paths = ['lib']
19
31
 
32
+ # Development dependencies
20
33
  spec.add_development_dependency 'bundler', '~> 2.1'
21
34
  spec.add_development_dependency 'rake', '~> 10.0'
22
35
  spec.add_development_dependency 'rspec'
23
36
  spec.add_development_dependency 'typhoeus'
24
37
  spec.add_development_dependency 'vcr'
25
38
 
26
- spec.required_ruby_version = '>= 1.9.3'
39
+ spec.required_ruby_version = '>= 3.0.0'
27
40
 
41
+ # Runtime dependencies
28
42
  spec.add_dependency 'faraday'
29
43
  spec.add_dependency 'json'
30
44
  end
@@ -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 = apiresponse
19
- Struct.new(*response.keys).new(*response.values) unless response.empty?
18
+ response = fetch_account_data
19
+ parse_response(response)
20
20
  end
21
21
 
22
22
  private
23
23
 
24
- def apiresponse
25
- response = Faraday.new("#{API_ACCOUNT_URL}&api_key=#{@key}").get
26
- 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)
27
36
  end
28
37
  end
29
38
  end
@@ -2,14 +2,13 @@
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 discover leads campaigns lead_enrichment company_enrichment
6
+ combined_enrichment].each do |file|
7
+ require_relative file
8
+ end
11
9
 
12
10
  module EmailHunter
11
+ # Main API client for EmailHunter services
13
12
  class Api
14
13
  attr_reader :key
15
14
 
@@ -19,17 +18,17 @@ module EmailHunter
19
18
 
20
19
  # Domain search API
21
20
  def search(domain, params = {})
22
- EmailHunter::Search.new(domain, key, params).hunt
21
+ execute_hunt(Search, domain, params)
23
22
  end
24
23
 
25
24
  # Email exist API
26
25
  def exist(email)
27
- EmailHunter::Exist.new(email, key).hunt
26
+ execute_hunt(Exist, email)
28
27
  end
29
28
 
30
29
  # Email verify API
31
30
  def verify(email)
32
- EmailHunter::Verify.new(email, key).hunt
31
+ execute_hunt(Verify, email)
33
32
  end
34
33
 
35
34
  # Email Finder API
@@ -39,12 +38,105 @@ module EmailHunter
39
38
 
40
39
  # Email Count API
41
40
  def count(domain)
42
- EmailHunter::Count.new(domain).hunt
41
+ execute_hunt(Count, domain)
43
42
  end
44
43
 
45
44
  # Account Information API
46
45
  def account
47
- EmailHunter::Account.new(key).hunt
46
+ execute_hunt(Account)
47
+ end
48
+
49
+ # Company Information API
50
+ def company(domain)
51
+ execute_hunt(Company, domain)
52
+ end
53
+
54
+ # People Information API
55
+ def people(domain)
56
+ execute_hunt(People, domain)
57
+ end
58
+
59
+ # Discover API - Search companies using natural language
60
+ def discover(query, params = {})
61
+ execute_hunt(Discover, query, params)
62
+ end
63
+
64
+ # Leads API - List leads
65
+ def leads(params = {})
66
+ Leads.new(key, action: :list, params: params).hunt
67
+ end
68
+
69
+ # Leads API - Create lead
70
+ def lead_create(data)
71
+ Leads.new(key, action: :create, data: data).hunt
72
+ end
73
+
74
+ # Leads API - Update lead
75
+ def lead_update(id, data)
76
+ Leads.new(key, action: :update, lead_id: id, data: data).hunt
77
+ end
78
+
79
+ # Leads API - Delete lead
80
+ def lead_delete(id)
81
+ Leads.new(key, action: :delete, lead_id: id).hunt
82
+ end
83
+
84
+ # Campaigns API - List campaigns
85
+ def campaigns(params = {})
86
+ Campaigns.new(key, action: :list, params: params).hunt
87
+ end
88
+
89
+ # Campaigns API - Get campaign recipients
90
+ def campaign_recipients(campaign_id, params = {})
91
+ Campaigns.new(key, action: :recipients, campaign_id: campaign_id, params: params).hunt
92
+ end
93
+
94
+ # Campaigns API - Add recipient to campaign
95
+ def campaign_add_recipient(campaign_id, data)
96
+ Campaigns.new(key, action: :add_recipient, campaign_id: campaign_id, data: data).hunt
97
+ end
98
+
99
+ # Campaigns API - Delete recipient from campaign
100
+ def campaign_delete_recipient(campaign_id, email)
101
+ Campaigns.new(key, action: :delete_recipient, campaign_id: campaign_id, data: { email: email }).hunt
102
+ end
103
+
104
+ # Lead Enrichment API - Enrich person data
105
+ def lead_enrichment(email: nil, linkedin: nil)
106
+ LeadEnrichment.new(key, email: email, linkedin: linkedin).hunt
107
+ end
108
+
109
+ # Company Enrichment API - Enrich company data
110
+ def company_enrichment(domain)
111
+ CompanyEnrichment.new(domain, key).hunt
112
+ end
113
+
114
+ # Combined Enrichment API - Enrich both lead and company data
115
+ def combined_enrichment(email: nil, linkedin: nil)
116
+ CombinedEnrichment.new(key, email: email, linkedin: linkedin).hunt
117
+ end
118
+
119
+ private
120
+
121
+ # Helper method to reduce repetition
122
+ def execute_hunt(klass, *args)
123
+ case klass.name.split('::').last
124
+ when 'Search', 'Discover'
125
+ # Search and Discover expect (value, key, params)
126
+ value, params = args
127
+ klass.new(value, key, params || {}).hunt
128
+ when 'Count'
129
+ # Count doesn't need key
130
+ domain = args.first
131
+ klass.new(domain).hunt
132
+ when 'Account'
133
+ # Account only needs key
134
+ klass.new(key).hunt
135
+ else
136
+ # Other classes expect (value, key)
137
+ value = args.first
138
+ klass.new(value, key).hunt
139
+ end
48
140
  end
49
141
  end
50
142
  end