zerobounce-sdk 0.4.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 +7 -0
- data/.env.sample +3 -0
- data/.gitignore +59 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +21 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +121 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +391 -0
- data/Rakefile +26 -0
- data/bin/bundle +105 -0
- data/bin/console +7 -0
- data/bin/setup +6 -0
- data/data/zerobounce-ai-scoring.csv +31 -0
- data/data/zerobounce-batch-validation.csv +31 -0
- data/files/scoring.csv +1 -0
- data/files/validation.csv +1 -0
- data/files/zerobounce-ai-scoring.csv +31 -0
- data/files/zerobounce-batch-validation.csv +31 -0
- data/lib/zerobounce/base_request.rb +55 -0
- data/lib/zerobounce/configuration.rb +36 -0
- data/lib/zerobounce/error.rb +84 -0
- data/lib/zerobounce/mock_request.rb +63 -0
- data/lib/zerobounce/request.rb +63 -0
- data/lib/zerobounce/version.rb +6 -0
- data/lib/zerobounce.rb +370 -0
- data/output.err +737 -0
- data/output.log +250 -0
- data/zerobounce.gemspec +44 -0
- metadata +278 -0
data/lib/zerobounce.rb
ADDED
@@ -0,0 +1,370 @@
|
|
1
|
+
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
require 'zerobounce/error'
|
7
|
+
require 'zerobounce/version'
|
8
|
+
require 'zerobounce/request'
|
9
|
+
require 'zerobounce/mock_request'
|
10
|
+
require 'zerobounce/configuration'
|
11
|
+
|
12
|
+
# Validate an email address with Zerobounce.net
|
13
|
+
module Zerobounce
|
14
|
+
|
15
|
+
API_ROOT_URL = 'https://api.zerobounce.net/v2'
|
16
|
+
BULK_API_ROOT_URL = 'https://bulkapi.zerobounce.net/v2'
|
17
|
+
|
18
|
+
class << self
|
19
|
+
attr_writer :configuration
|
20
|
+
|
21
|
+
@@request = ENV['TEST']=='unit' ? MockRequest : Request
|
22
|
+
|
23
|
+
# Zerobounce configuration
|
24
|
+
#
|
25
|
+
# @return [Zerobounce::Configuration]
|
26
|
+
def configuration
|
27
|
+
@configuration ||= Configuration.new
|
28
|
+
end
|
29
|
+
alias config configuration
|
30
|
+
|
31
|
+
# Configure Zerobounce inside a block.
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# Zerobounce.configure do |config|
|
35
|
+
# config.apikey = 'api-key'
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# @yieldparam [Zerobounce::Configuration] config
|
39
|
+
def configure
|
40
|
+
yield configuration
|
41
|
+
end
|
42
|
+
|
43
|
+
# Validates the email address and gets geoip information for an IP if provided.
|
44
|
+
#
|
45
|
+
# @param [String] :email The email address to validate.
|
46
|
+
# @option [String] :ip_address IP address corresponding to the email.
|
47
|
+
#
|
48
|
+
# @return [Hash]
|
49
|
+
# {
|
50
|
+
# "address": "valid@example.com",
|
51
|
+
# "status": "valid",
|
52
|
+
# "sub_status": "",
|
53
|
+
# "free_email": false,
|
54
|
+
# "did_you_mean": null,
|
55
|
+
# "account": null,
|
56
|
+
# "domain": null,
|
57
|
+
# "domain_age_days": "9692",
|
58
|
+
# "smtp_provider": "example",
|
59
|
+
# "mx_found": "true",
|
60
|
+
# "mx_record": "mx.example.com",
|
61
|
+
# "firstname": "zero",
|
62
|
+
# "lastname": "bounce",
|
63
|
+
# "gender": "male",
|
64
|
+
# "country": null,
|
65
|
+
# "region": null,
|
66
|
+
# "city": null,
|
67
|
+
# "zipcode": null,
|
68
|
+
# "processed_at": "2023-04-18 12:09:39.074"
|
69
|
+
# }
|
70
|
+
def validate(email, ip_address=nil)
|
71
|
+
params = {email: email, ip_address: ip_address}
|
72
|
+
@@request.get('validate', params)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Get the number of remaining credits on the account.
|
76
|
+
#
|
77
|
+
# @return [Integer] amount of credits left
|
78
|
+
def credits()
|
79
|
+
json = @@request.get('getcredits', {})
|
80
|
+
credits = json['Credits']
|
81
|
+
credits_i = credits.to_i
|
82
|
+
return credits_i
|
83
|
+
end
|
84
|
+
|
85
|
+
# Convenience method for checking if an email address is valid.
|
86
|
+
#
|
87
|
+
# @param [String] email
|
88
|
+
# @return [Boolean]
|
89
|
+
# def valid?(email)
|
90
|
+
# # todo:
|
91
|
+
# validate(email: email).valid?
|
92
|
+
# end
|
93
|
+
|
94
|
+
# Convenience method for checking if an email address is invalid.
|
95
|
+
#
|
96
|
+
# @param [String] email
|
97
|
+
# @return [Boolean]
|
98
|
+
# def invalid?(email)
|
99
|
+
# # todo:
|
100
|
+
# validate(email: email).invalid?
|
101
|
+
# end
|
102
|
+
|
103
|
+
# Get API usage
|
104
|
+
#
|
105
|
+
# @param [Date] start_date
|
106
|
+
# @param [Date] end_date
|
107
|
+
#
|
108
|
+
# @return [Hash]
|
109
|
+
# {
|
110
|
+
# "total": 5,
|
111
|
+
# "status_valid": 4,
|
112
|
+
# "status_invalid": 1,
|
113
|
+
# "status_catch_all": 0,
|
114
|
+
# "status_do_not_mail": 0,
|
115
|
+
# "status_spamtrap": 0,
|
116
|
+
# "status_unknown": 0,
|
117
|
+
# "sub_status_toxic": 0,
|
118
|
+
# "sub_status_disposable": 0,
|
119
|
+
# "sub_status_role_based": 0,
|
120
|
+
# "sub_status_possible_trap": 0,
|
121
|
+
# "sub_status_global_suppression": 0,
|
122
|
+
# "sub_status_timeout_exceeded": 0,
|
123
|
+
# "sub_status_mail_server_temporary_error": 0,
|
124
|
+
# "sub_status_mail_server_did_not_respond": 0,
|
125
|
+
# "sub_status_greylisted": 0,
|
126
|
+
# "sub_status_antispam_system": 0,
|
127
|
+
# "sub_status_does_not_accept_mail": 0,
|
128
|
+
# "sub_status_exception_occurred": 0,
|
129
|
+
# "sub_status_failed_syntax_check": 1,
|
130
|
+
# "sub_status_mailbox_not_found": 0,
|
131
|
+
# "sub_status_unroutable_ip_address": 0,
|
132
|
+
# "sub_status_possible_typo": 0,
|
133
|
+
# "sub_status_no_dns_entries": 0,
|
134
|
+
# "sub_status_role_based_catch_all": 0,
|
135
|
+
# "sub_status_mailbox_quota_exceeded": 0,
|
136
|
+
# "sub_status_forcible_disconnect": 0,
|
137
|
+
# "sub_status_failed_smtp_connection": 0,
|
138
|
+
# "sub_status_mx_forward": 0,
|
139
|
+
# "sub_status_alternate": 0,
|
140
|
+
# "sub_status_blocked": 0,
|
141
|
+
# "sub_status_allowed": 0,
|
142
|
+
# "start_date": "1/1/2018",
|
143
|
+
# "end_date": "12/12/2023"
|
144
|
+
# }
|
145
|
+
def api_usage(start_date, end_date)
|
146
|
+
begin
|
147
|
+
start_date_f = start_date.strftime('%Y-%m-%d')
|
148
|
+
end_date_f = end_date.strftime('%Y-%m-%d')
|
149
|
+
rescue NoMethodError => e
|
150
|
+
raise ArgumentError.new('strftime method not found for provided arguments')
|
151
|
+
end
|
152
|
+
params = {start_date: start_date_f, end_date: end_date_f}
|
153
|
+
@@request.get('getapiusage', params)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Validate email batch
|
157
|
+
#
|
158
|
+
# @param [Array] :emails List of email addresses to validate.
|
159
|
+
# @option [Array] :ip_addresses Corresponding list of IP addresses.
|
160
|
+
#
|
161
|
+
# @return [Array] list of validate result for each element
|
162
|
+
# [
|
163
|
+
# {
|
164
|
+
# "address": "disposable@example.com",
|
165
|
+
# "status": "do_not_mail",
|
166
|
+
# "sub_status": "disposable",
|
167
|
+
# "free_email": false,
|
168
|
+
# "did_you_mean": null,
|
169
|
+
# "account": null,
|
170
|
+
# "domain": null,
|
171
|
+
# "domain_age_days": "9692",
|
172
|
+
# "smtp_provider": "example",
|
173
|
+
# "mx_found": "true",
|
174
|
+
# "mx_record": "mx.example.com",
|
175
|
+
# "firstname": "zero",
|
176
|
+
# "lastname": "bounce",
|
177
|
+
# "gender": "male",
|
178
|
+
# "country": null,
|
179
|
+
# "region": null,
|
180
|
+
# "city": null,
|
181
|
+
# "zipcode": null,
|
182
|
+
# "processed_at": "2023-04-18 12:27:39.529"
|
183
|
+
# },
|
184
|
+
# {
|
185
|
+
# ...
|
186
|
+
# },
|
187
|
+
# ...
|
188
|
+
# ]
|
189
|
+
def validate_batch(emails, ip_addresses=[])
|
190
|
+
|
191
|
+
raise ArgumentError.new if emails.class != Array
|
192
|
+
emails.each do |email|
|
193
|
+
raise ArgumentError if email.class != String
|
194
|
+
end
|
195
|
+
|
196
|
+
email_batch = []
|
197
|
+
emails.each_index do |i|
|
198
|
+
email_batch.push({
|
199
|
+
email_address: emails[i],
|
200
|
+
ip_address: ip_addresses[i]
|
201
|
+
})
|
202
|
+
end
|
203
|
+
params = {email_batch: email_batch}
|
204
|
+
results = @@request.bulk_post('validatebatch', params)
|
205
|
+
return results['email_batch']
|
206
|
+
end
|
207
|
+
|
208
|
+
# Validate CSV file
|
209
|
+
#
|
210
|
+
# @param [String] :filepath Path to the file to be uploaded
|
211
|
+
# @option [Int] :email_address_column Specify which column the email address is on
|
212
|
+
# @option [Int] :first_name_column Specify which column the first name is on
|
213
|
+
# @option [Int] :last_name_column Specify which column the last name is on
|
214
|
+
# @option [Int] :gender_column Specify which column the gender is on
|
215
|
+
# @option [Int] :has_header_row Specify whether the file includes a header row or not
|
216
|
+
# @option [Int] :return_url Specify a callback URL (if nil, no callback will be performed)
|
217
|
+
#
|
218
|
+
# @return [Hash]
|
219
|
+
# {
|
220
|
+
# "success": true,
|
221
|
+
# "message": "File Accepted",
|
222
|
+
# "file_name": "zerobounce-batch-validation.csv",
|
223
|
+
# "file_id": "6d44a908-7283-42a9-aa5f-9e57b16f84bd"
|
224
|
+
# }
|
225
|
+
def validate_file_send(
|
226
|
+
filepath,
|
227
|
+
email_address_column: 1,
|
228
|
+
first_name_column: 2,
|
229
|
+
last_name_column: 3,
|
230
|
+
gender_column: 4,
|
231
|
+
has_header_row: true,
|
232
|
+
return_url: nil
|
233
|
+
)
|
234
|
+
params = {
|
235
|
+
email_address_column: email_address_column,
|
236
|
+
first_name_column: first_name_column,
|
237
|
+
last_name_column: last_name_column,
|
238
|
+
gender_column: gender_column,
|
239
|
+
has_header_row: has_header_row,
|
240
|
+
}
|
241
|
+
params[:return_url] = return_url if return_url
|
242
|
+
@@request.bulk_post('sendfile', params, 'multipart/form-data', filepath)
|
243
|
+
end
|
244
|
+
|
245
|
+
# Get validate file status
|
246
|
+
#
|
247
|
+
# @param [String] :file_id Id of the file.
|
248
|
+
#
|
249
|
+
# @return [Hash]
|
250
|
+
# {
|
251
|
+
# "success": true,
|
252
|
+
# "file_id": "6d44a908-7283-42a9-aa5f-9e57b16f84bd",
|
253
|
+
# "file_name": "zerobounce-batch-validation.csv",
|
254
|
+
# "upload_date": "2023-04-18T14:40:08Z",
|
255
|
+
# "file_status": "Complete",
|
256
|
+
# "complete_percentage": "100%",
|
257
|
+
# "error_reason": null,
|
258
|
+
# "return_url": null
|
259
|
+
# }
|
260
|
+
def validate_file_check(file_id)
|
261
|
+
# todo:
|
262
|
+
params = {file_id: file_id}
|
263
|
+
@@request.bulk_get('filestatus', params)
|
264
|
+
end
|
265
|
+
|
266
|
+
# Get validate results file
|
267
|
+
#
|
268
|
+
# @param [String] :file_id Id of the file.
|
269
|
+
#
|
270
|
+
# @return [String/File?]
|
271
|
+
def validate_file_get(file_id)
|
272
|
+
# todo:
|
273
|
+
params = {file_id: file_id}
|
274
|
+
@@request.bulk_get('getfile', params)
|
275
|
+
end
|
276
|
+
|
277
|
+
# Delete validate file
|
278
|
+
#
|
279
|
+
# @param file_id Id of the file.
|
280
|
+
#
|
281
|
+
# @return [Hash]
|
282
|
+
# {
|
283
|
+
# "success": true,
|
284
|
+
# "message": "File Deleted",
|
285
|
+
# "file_name": "zerobounce-batch-validation.csv",
|
286
|
+
# "file_id": "6d44a908-7283-42a9-aa5f-9e57b16f84bd"
|
287
|
+
# }
|
288
|
+
def validate_file_delete(file_id)
|
289
|
+
# todo:
|
290
|
+
params = {file_id: file_id}
|
291
|
+
@@request.bulk_get('deletefile', params)
|
292
|
+
end
|
293
|
+
|
294
|
+
# Score CSV file
|
295
|
+
#
|
296
|
+
# @param [String] :filepath Path to the file to be uploaded
|
297
|
+
# @option [Int] :email_address_column Specify which column the email address is on
|
298
|
+
# @option [Int] :has_header_row Specify whether the file includes a header row or not
|
299
|
+
# @option [Int] :return_url Specify a callback URL (if nil, no callback will be performed)
|
300
|
+
#
|
301
|
+
# @return [Hash]
|
302
|
+
# {
|
303
|
+
# "success": true,
|
304
|
+
# "message": "File Accepted",
|
305
|
+
# "file_name": "zerobounce-ai-scoring.csv",
|
306
|
+
# "file_id": "6d44a908-7283-42a9-aa5f-9e57b16f84bd"
|
307
|
+
# }
|
308
|
+
def scoring_file_send(
|
309
|
+
filepath,
|
310
|
+
email_address_column: 1,
|
311
|
+
has_header_row: true,
|
312
|
+
return_url: nil
|
313
|
+
)
|
314
|
+
params = {
|
315
|
+
email_address_column: email_address_column,
|
316
|
+
has_header_row: has_header_row,
|
317
|
+
}
|
318
|
+
params[:return_url] = return_url if return_url
|
319
|
+
@@request.bulk_post('scoring/sendfile', params, 'multipart/form-data', filepath)
|
320
|
+
end
|
321
|
+
|
322
|
+
# Get validate results file
|
323
|
+
#
|
324
|
+
# @param [String] :file_id Id of the file.
|
325
|
+
#
|
326
|
+
# @return [String/File?]
|
327
|
+
def scoring_file_get(file_id)
|
328
|
+
# todo:
|
329
|
+
params = {file_id: file_id}
|
330
|
+
@@request.bulk_get('scoring/getfile', params)
|
331
|
+
end
|
332
|
+
|
333
|
+
# Get validate file status
|
334
|
+
#
|
335
|
+
# @param [String] :file_id Id of the file.
|
336
|
+
#
|
337
|
+
# @return [Hash]
|
338
|
+
# {
|
339
|
+
# "success": true,
|
340
|
+
# "file_id": "d391b463-cb56-4fb3-a9c0-9817653ff725",
|
341
|
+
# "file_name": "zerobounce-ai-scoring.csv",
|
342
|
+
# "upload_date": "2023-04-18T15:13:56Z",
|
343
|
+
# "file_status": "Complete",
|
344
|
+
# "complete_percentage": "100% Complete.",
|
345
|
+
# "return_url": null
|
346
|
+
# }
|
347
|
+
def scoring_file_check(file_id)
|
348
|
+
params = {file_id: file_id}
|
349
|
+
@@request.bulk_get('scoring/filestatus', params)
|
350
|
+
end
|
351
|
+
|
352
|
+
# Delete validate file
|
353
|
+
#
|
354
|
+
# @param file_id Id of the file.
|
355
|
+
#
|
356
|
+
# @return [Hash]
|
357
|
+
# {
|
358
|
+
# "success": true,
|
359
|
+
# "message": "File Deleted",
|
360
|
+
# "file_name": "zerobounce-ai-scoring.csv",
|
361
|
+
# "file_id": "6d44a908-7283-42a9-aa5f-9e57b16f84bd"
|
362
|
+
# }
|
363
|
+
def scoring_file_delete(file_id)
|
364
|
+
# todo:
|
365
|
+
params = {file_id: file_id}
|
366
|
+
@@request.bulk_get('scoring/deletefile', params)
|
367
|
+
end
|
368
|
+
|
369
|
+
end
|
370
|
+
end
|