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.
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