zerobounceindia-sdk 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.env.sample +3 -0
- data/.gitignore +63 -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 +393 -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/zerobounce.gemspec +44 -0
- metadata +276 -0
data/README.md
ADDED
@@ -0,0 +1,393 @@
|
|
1
|
+
|
2
|
+
# Zerobounce India
|
3
|
+
Ruby client for Zerobounce.net API. Developed based on [this version](https://github.com/afrase/zerobounce) by Aaron Frase.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
```ruby
|
8
|
+
gem 'zerobounceindia-sdk'
|
9
|
+
```
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
```bash
|
13
|
+
$bundle
|
14
|
+
```
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
```bash
|
18
|
+
$gem install zerobounceindia-sdk
|
19
|
+
```
|
20
|
+
|
21
|
+
Import
|
22
|
+
```ruby
|
23
|
+
require 'zerobounce'
|
24
|
+
```
|
25
|
+
|
26
|
+
Set a valid ZeroBounce API key.
|
27
|
+
```ruby
|
28
|
+
Zerobounce.configure do |config|
|
29
|
+
config.apikey = '<zerobounce-api-key>'
|
30
|
+
...
|
31
|
+
end
|
32
|
+
```
|
33
|
+
or
|
34
|
+
```
|
35
|
+
Zerobounce.config.apikey = '<zerobounce-api-key>'
|
36
|
+
...
|
37
|
+
```
|
38
|
+
|
39
|
+
Credits
|
40
|
+
```ruby
|
41
|
+
Zerobounce.credits
|
42
|
+
=> 79 # returns -1 for invalid key
|
43
|
+
```
|
44
|
+
|
45
|
+
Usage statistics
|
46
|
+
```ruby
|
47
|
+
Zerobounce.api_usage(Date.today, Date.today)
|
48
|
+
=>
|
49
|
+
{"total"=>0,
|
50
|
+
"status_valid"=>0,
|
51
|
+
"status_invalid"=>0,
|
52
|
+
"status_catch_all"=>0,
|
53
|
+
"status_do_not_mail"=>0,
|
54
|
+
"status_spamtrap"=>0,
|
55
|
+
"status_unknown"=>0,
|
56
|
+
"sub_status_toxic"=>0,
|
57
|
+
"sub_status_disposable"=>0,
|
58
|
+
"sub_status_role_based"=>0,
|
59
|
+
"sub_status_possible_trap"=>0,
|
60
|
+
"sub_status_global_suppression"=>0,
|
61
|
+
"sub_status_timeout_exceeded"=>0,
|
62
|
+
"sub_status_mail_server_temporary_error"=>0,
|
63
|
+
"sub_status_mail_server_did_not_respond"=>0,
|
64
|
+
"sub_status_greylisted"=>0,
|
65
|
+
"sub_status_antispam_system"=>0,
|
66
|
+
"sub_status_does_not_accept_mail"=>0,
|
67
|
+
"sub_status_exception_occurred"=>0,
|
68
|
+
"sub_status_failed_syntax_check"=>0,
|
69
|
+
"sub_status_mailbox_not_found"=>0,
|
70
|
+
"sub_status_unroutable_ip_address"=>0,
|
71
|
+
"sub_status_possible_typo"=>0,
|
72
|
+
"sub_status_no_dns_entries"=>0,
|
73
|
+
"sub_status_role_based_catch_all"=>0,
|
74
|
+
"sub_status_mailbox_quota_exceeded"=>0,
|
75
|
+
"sub_status_forcible_disconnect"=>0,
|
76
|
+
"sub_status_failed_smtp_connection"=>0,
|
77
|
+
"sub_status_mx_forward"=>0,
|
78
|
+
"sub_status_alternate"=>0,
|
79
|
+
"sub_status_blocked"=>0,
|
80
|
+
"sub_status_allowed"=>0,
|
81
|
+
"start_date"=>"4/28/2023",
|
82
|
+
"end_date"=>"4/28/2023"}
|
83
|
+
```
|
84
|
+
|
85
|
+
### Email Validation
|
86
|
+
|
87
|
+
Validate single eMail
|
88
|
+
```ruby
|
89
|
+
Zerobounce.validate('valid@example.com')
|
90
|
+
# Zerobounce.validate('valid@example.com', '192.168.0.1') # optional IP address
|
91
|
+
=>
|
92
|
+
{"address"=>"valid@example.com",
|
93
|
+
"status"=>"valid",
|
94
|
+
"sub_status"=>"",
|
95
|
+
"free_email"=>false,
|
96
|
+
"did_you_mean"=>nil,
|
97
|
+
"account"=>nil,
|
98
|
+
"domain"=>nil,
|
99
|
+
"domain_age_days"=>"9692",
|
100
|
+
"smtp_provider"=>"example",
|
101
|
+
"mx_found"=>"true",
|
102
|
+
"mx_record"=>"mx.example.com",
|
103
|
+
"firstname"=>"zero",
|
104
|
+
"lastname"=>"bounce",
|
105
|
+
"gender"=>"male",
|
106
|
+
"country"=>nil,
|
107
|
+
"region"=>nil,
|
108
|
+
"city"=>nil,
|
109
|
+
"zipcode"=>nil,
|
110
|
+
"processed_at"=>"2023-04-28 15:18:45.631"}
|
111
|
+
```
|
112
|
+
|
113
|
+
Validate batch
|
114
|
+
```ruby
|
115
|
+
emails
|
116
|
+
=>
|
117
|
+
["disposable@example.com",
|
118
|
+
"invalid@example.com",
|
119
|
+
"valid@example.com",
|
120
|
+
"toxic@example.com",
|
121
|
+
"donotmail@example.com",
|
122
|
+
"spamtrap@example.com"]
|
123
|
+
|
124
|
+
# ip_addresses
|
125
|
+
=> ["192.168.0.1", "192.168.0.1", "192.168.0.1", "192.168.0.1", "192.168.0.1", "192.168.0.1"]
|
126
|
+
# Zerobounce.validate_batch(emails, ip_addresses) # optional ip_addresses parameter
|
127
|
+
|
128
|
+
Zerobounce.validate_batch(emails)
|
129
|
+
=>
|
130
|
+
[{"address"=>"disposable@example.com",
|
131
|
+
"status"=>"do_not_mail",
|
132
|
+
"sub_status"=>"disposable",
|
133
|
+
"free_email"=>false,
|
134
|
+
"did_you_mean"=>nil,
|
135
|
+
"account"=>nil,
|
136
|
+
"domain"=>nil,
|
137
|
+
"domain_age_days"=>"9692",
|
138
|
+
"smtp_provider"=>"example",
|
139
|
+
"mx_found"=>"true",
|
140
|
+
"mx_record"=>"mx.example.com",
|
141
|
+
"firstname"=>"zero",
|
142
|
+
"lastname"=>"bounce",
|
143
|
+
"gender"=>"male",
|
144
|
+
"country"=>nil,
|
145
|
+
"region"=>nil,
|
146
|
+
"city"=>nil,
|
147
|
+
"zipcode"=>nil,
|
148
|
+
"processed_at"=>"2023-04-28 15:21:44.340"},
|
149
|
+
{"address"=>"invalid@example.com",
|
150
|
+
"status"=>"invalid",
|
151
|
+
"sub_status"=>"mailbox_not_found",
|
152
|
+
"free_email"=>false,
|
153
|
+
"did_you_mean"=>nil,
|
154
|
+
"account"=>nil,
|
155
|
+
"domain"=>nil,
|
156
|
+
"domain_age_days"=>"9692",
|
157
|
+
"smtp_provider"=>"example",
|
158
|
+
"mx_found"=>"true",
|
159
|
+
"mx_record"=>"mx.example.com",
|
160
|
+
"firstname"=>"zero",
|
161
|
+
"lastname"=>"bounce",
|
162
|
+
"gender"=>"male",
|
163
|
+
"country"=>nil,
|
164
|
+
"region"=>nil,
|
165
|
+
"city"=>nil,
|
166
|
+
"zipcode"=>nil,
|
167
|
+
"processed_at"=>"2023-04-28 15:21:44.340"},
|
168
|
+
{"address"=>"valid@example.com",
|
169
|
+
"status"=>"valid",
|
170
|
+
"sub_status"=>"",
|
171
|
+
"free_email"=>false,
|
172
|
+
"did_you_mean"=>nil,
|
173
|
+
"account"=>nil,
|
174
|
+
"domain"=>nil,
|
175
|
+
"domain_age_days"=>"9692",
|
176
|
+
"smtp_provider"=>"example",
|
177
|
+
"mx_found"=>"true",
|
178
|
+
"mx_record"=>"mx.example.com",
|
179
|
+
"firstname"=>"zero",
|
180
|
+
"lastname"=>"bounce",
|
181
|
+
"gender"=>"male",
|
182
|
+
"country"=>nil,
|
183
|
+
"region"=>nil,
|
184
|
+
"city"=>nil,
|
185
|
+
"zipcode"=>nil,
|
186
|
+
"processed_at"=>"2023-04-28 15:21:44.340"},
|
187
|
+
{"address"=>"toxic@example.com",
|
188
|
+
"status"=>"do_not_mail",
|
189
|
+
"sub_status"=>"toxic",
|
190
|
+
"free_email"=>false,
|
191
|
+
"did_you_mean"=>nil,
|
192
|
+
"account"=>nil,
|
193
|
+
"domain"=>nil,
|
194
|
+
"domain_age_days"=>"9692",
|
195
|
+
"smtp_provider"=>"example",
|
196
|
+
"mx_found"=>"true",
|
197
|
+
"mx_record"=>"mx.example.com",
|
198
|
+
"firstname"=>"zero",
|
199
|
+
"lastname"=>"bounce",
|
200
|
+
"gender"=>"male",
|
201
|
+
"country"=>nil,
|
202
|
+
"region"=>nil,
|
203
|
+
"city"=>nil,
|
204
|
+
"zipcode"=>nil,
|
205
|
+
"processed_at"=>"2023-04-28 15:21:44.340"},
|
206
|
+
{"address"=>"donotmail@example.com",
|
207
|
+
"status"=>"do_not_mail",
|
208
|
+
"sub_status"=>"role_based",
|
209
|
+
"free_email"=>false,
|
210
|
+
"did_you_mean"=>nil,
|
211
|
+
"account"=>nil,
|
212
|
+
"domain"=>nil,
|
213
|
+
"domain_age_days"=>"9692",
|
214
|
+
"smtp_provider"=>"example",
|
215
|
+
"mx_found"=>"true",
|
216
|
+
"mx_record"=>"mx.example.com",
|
217
|
+
"firstname"=>"zero",
|
218
|
+
"lastname"=>"bounce",
|
219
|
+
"gender"=>"male",
|
220
|
+
"country"=>nil,
|
221
|
+
"region"=>nil,
|
222
|
+
"city"=>nil,
|
223
|
+
"zipcode"=>nil,
|
224
|
+
"processed_at"=>"2023-04-28 15:21:44.340"},
|
225
|
+
{"address"=>"spamtrap@example.com",
|
226
|
+
"status"=>"spamtrap",
|
227
|
+
"sub_status"=>"",
|
228
|
+
"free_email"=>false,
|
229
|
+
"did_you_mean"=>nil,
|
230
|
+
"account"=>nil,
|
231
|
+
"domain"=>nil,
|
232
|
+
"domain_age_days"=>"9692",
|
233
|
+
"smtp_provider"=>"example",
|
234
|
+
"mx_found"=>"true",
|
235
|
+
"mx_record"=>"mx.example.com",
|
236
|
+
"firstname"=>"zero",
|
237
|
+
"lastname"=>"bounce",
|
238
|
+
"gender"=>"male",
|
239
|
+
"country"=>nil,
|
240
|
+
"region"=>nil,
|
241
|
+
"city"=>nil,
|
242
|
+
"zipcode"=>nil,
|
243
|
+
"processed_at"=>"2023-04-28 15:21:44.340"}]
|
244
|
+
```
|
245
|
+
|
246
|
+
#### Batch File Validation
|
247
|
+
|
248
|
+
Send file
|
249
|
+
```ruby
|
250
|
+
# sample file can be found in the files folder of this repository
|
251
|
+
validate_file_path = File.join(Dir.pwd, 'files', 'validation.csv')
|
252
|
+
=> "/home/zb/wrappers/ruby-test/files/validation.csv"
|
253
|
+
Zerobounce.validate_file_send(validate_file_path)
|
254
|
+
=>
|
255
|
+
{"success"=>true,
|
256
|
+
"message"=>"File Accepted",
|
257
|
+
"file_name"=>"validation.csv",
|
258
|
+
"file_id"=>"75d854a6-565c-49f9-b4c8-b3344480ec4c"}
|
259
|
+
# file_id will be required for next steps
|
260
|
+
# optional named parameters:
|
261
|
+
email_address_column: 1,
|
262
|
+
first_name_column: 2,
|
263
|
+
last_name_column: 3,
|
264
|
+
gender_column: 4,
|
265
|
+
has_header_row: true,
|
266
|
+
return_url: nil # results callback url
|
267
|
+
# Zerobounce.validate_file_send(validate_file_path, email_address_column: 1, gender_column: 4)
|
268
|
+
```
|
269
|
+
|
270
|
+
Check file
|
271
|
+
```ruby
|
272
|
+
file_id = "75d854a6-565c-49f9-b4c8-b3344480ec4c"
|
273
|
+
=> "75d854a6-565c-49f9-b4c8-b3344480ec4c"
|
274
|
+
Zerobounce.validate_file_check(file_id)
|
275
|
+
=>
|
276
|
+
{"success"=>true,
|
277
|
+
"file_id"=>"75d854a6-565c-49f9-b4c8-b3344480ec4c",
|
278
|
+
"file_name"=>"validation.csv",
|
279
|
+
"upload_date"=>"2023-04-28T15:25:41Z",
|
280
|
+
"file_status"=>"Greylisted",
|
281
|
+
"complete_percentage"=>"0%",
|
282
|
+
"error_reason"=>nil,
|
283
|
+
"return_url"=>nil}
|
284
|
+
```
|
285
|
+
|
286
|
+
Get file
|
287
|
+
```ruby
|
288
|
+
file_id = "75d854a6-565c-49f9-b4c8-b3344480ec4c"
|
289
|
+
=> "75d854a6-565c-49f9-b4c8-b3344480ec4c"
|
290
|
+
Zerobounce.validate_file_get(file_id)
|
291
|
+
=> "\"email\",\"first\",\"last\",\"gender\",\"ip\",\"ZB Status\",\"ZB Sub Status\",\"ZB Account\",\"ZB Domain\",\"ZB First Name\",\"ZB Last Name\",\"ZB Gender\",\"ZB Free Email\",\"ZB MX Found\",\"ZB MX Record\",\"ZB SMTP Provider\",\"ZB Did You Mean\"\n\"disposable@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"do_not_mail\",\"disposable\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"invalid@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"invalid\",\"mailbox_not_found\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"valid@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"valid\",\"\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"toxic@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"do_not_mail\",\"toxic\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"donotmail@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"do_not_mail\",\"role_based\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"spamtrap@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"spamtrap\",\"\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"abuse@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"abuse\",\"\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"unknown@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"unknown\",\"mail_server_temporary_error\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"catch_all@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"catch-all\",\"\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"antispam_system@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"unknown\",\"antispam_system\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"does_not_accept_mail@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"invalid\",\"does_not_accept_mail\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"exception_occurred@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"unknown\",\"exception_occurred\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"failed_smtp_connection@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"unknown\",\"failed_smtp_connection\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"failed_syntax_check@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"invalid\",\"failed_syntax_check\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"forcible_disconnect@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"unknown\",\"forcible_disconnect\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"global_suppression@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"do_not_mail\",\"global_suppression\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"greylisted@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"unknown\",\"greylisted\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"leading_period_removed@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"valid\",\"leading_period_removed\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"mail_server_did_not_respond@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"unknown\",\"mail_server_did_not_respond\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"mail_server_temporary_error@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"unknown\",\"mail_server_temporary_error\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"mailbox_quota_exceeded@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"invalid\",\"mailbox_quota_exceeded\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"mailbox_not_found@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"invalid\",\"mailbox_not_found\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"no_dns_entries@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"invalid\",\"no_dns_entries\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"possible_trap@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"do_not_mail\",\"possible_trap\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"possible_typo@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"invalid\",\"possible_typo\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"role_based@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"do_not_mail\",\"role_based\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"timeout_exceeded@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"unknown\",\"timeout_exceeded\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"unroutable_ip_address@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"invalid\",\"unroutable_ip_address\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"free_email@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"valid\",\"\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"True\",\"true\",\"mx.example.com\",\"example\",\"\"\n\"role_based_catch_all@example.com\",\"First\",\"Last\",\"male\",\"127.0.0.1\",\"do_not_mail\",\"role_based_catch_all\",\"\",\"\",\"zero\",\"bounce\",\"male\",\"False\",\"true\",\"mx.example.com\",\"example\",\"\"\n"
|
292
|
+
```
|
293
|
+
|
294
|
+
Delete file
|
295
|
+
```ruby
|
296
|
+
file_id = "75d854a6-565c-49f9-b4c8-b3344480ec4c"
|
297
|
+
=> "75d854a6-565c-49f9-b4c8-b3344480ec4c"
|
298
|
+
Zerobounce.validate_file_delete(file_id)
|
299
|
+
=>
|
300
|
+
{"success"=>true,
|
301
|
+
"message"=>"File Deleted",
|
302
|
+
"file_name"=>"validation.csv",
|
303
|
+
"file_id"=>"75d854a6-565c-49f9-b4c8-b3344480ec4c"}
|
304
|
+
```
|
305
|
+
|
306
|
+
### AI Scoring
|
307
|
+
|
308
|
+
Send file
|
309
|
+
```ruby
|
310
|
+
scoring_file_path = File.join(Dir.pwd, 'files', 'scoring.csv')
|
311
|
+
=> "/home/odin/zb/wrappers/ruby-test/files/scoring.csv"
|
312
|
+
Zerobounce.scoring_file_send(scoring_file_path)
|
313
|
+
=>
|
314
|
+
{"success"=>true,
|
315
|
+
"message"=>"File Accepted",
|
316
|
+
"file_name"=>"scoring.csv",
|
317
|
+
"file_id"=>"89fb7262-b845-4fa1-aa25-e486347ec64e"}
|
318
|
+
# file_id will be required for the next steps
|
319
|
+
# optional named parameters
|
320
|
+
email_address_column: 1,
|
321
|
+
has_header_row: true,
|
322
|
+
return_url: nil # results callback url
|
323
|
+
# Zerobounce.scoring_file_send(scoring_file_path, email_address_column: 1)
|
324
|
+
```
|
325
|
+
|
326
|
+
File check
|
327
|
+
```ruby
|
328
|
+
file_id = "89fb7262-b845-4fa1-aa25-e486347ec64e"
|
329
|
+
=> "89fb7262-b845-4fa1-aa25-e486347ec64e"
|
330
|
+
Zerobounce.scoring_file_check(file_id)
|
331
|
+
=>
|
332
|
+
{"success"=>true,
|
333
|
+
"file_id"=>"89fb7262-b845-4fa1-aa25-e486347ec64e",
|
334
|
+
"file_name"=>"scoring.csv",
|
335
|
+
"upload_date"=>"2023-04-28T16:57:18Z",
|
336
|
+
"file_status"=>"Complete",
|
337
|
+
"complete_percentage"=>"100% Complete.",
|
338
|
+
"return_url"=>nil}
|
339
|
+
```
|
340
|
+
|
341
|
+
Get file
|
342
|
+
```ruby
|
343
|
+
file_id = "89fb7262-b845-4fa1-aa25-e486347ec64e"
|
344
|
+
=> "89fb7262-b845-4fa1-aa25-e486347ec64e"
|
345
|
+
Zerobounce.scoring_file_get(file_id)
|
346
|
+
=> "\"email\",\"ZeroBounceQualityScore\"\r\n\"disposable@example.com\",\"0\"\r\n\"invalid@example.com\",\"10\"\r\n\"valid@example.com\",\"10\"\r\n\"toxic@example.com\",\"2\"\r\n\"donotmail@example.com\",\"0\"\r\n\"spamtrap@example.com\",\"0\"\r\n\"abuse@example.com\",\"10\"\r\n\"unknown@example.com\",\"10\"\r\n\"catch_all@example.com\",\"10\"\r\n\"antispam_system@example.com\",\"0\"\r\n\"does_not_accept_mail@example.com\",\"0\"\r\n\"exception_occurred@example.com\",\"0\"\r\n\"failed_smtp_connection@example.com\",\"0\"\r\n\"failed_syntax_check@example.com\",\"0\"\r\n\"forcible_disconnect@example.com\",\"0\"\r\n\"global_suppression@example.com\",\"0\"\r\n\"greylisted@example.com\",\"0\"\r\n\"leading_period_removed@example.com\",\"0\"\r\n\"mail_server_did_not_respond@example.com\",\"0\"\r\n\"mail_server_temporary_error@example.com\",\"0\"\r\n\"mailbox_quota_exceeded@example.com\",\"0\"\r\n\"mailbox_not_found@example.com\",\"0\"\r\n\"no_dns_entries@example.com\",\"0\"\r\n\"possible_trap@example.com\",\"0\"\r\n\"possible_typo@example.com\",\"0\"\r\n\"role_based@example.com\",\"0\"\r\n\"timeout_exceeded@example.com\",\"0\"\r\n\"unroutable_ip_address@example.com\",\"0\"\r\n\"free_email@example.com\",\"0\"\r\n\"role_based_catch_all@example.com\",\"0\""
|
347
|
+
```
|
348
|
+
|
349
|
+
Delete file
|
350
|
+
```ruby
|
351
|
+
file_id = "89fb7262-b845-4fa1-aa25-e486347ec64e"
|
352
|
+
=> "89fb7262-b845-4fa1-aa25-e486347ec64e"
|
353
|
+
Zerobounce.validate_file_delete(file_id)
|
354
|
+
=> {"success"=>false, "message"=>"File cannot be found."}
|
355
|
+
```
|
356
|
+
|
357
|
+
|
358
|
+
## Development
|
359
|
+
|
360
|
+
After checking out the repo run tests
|
361
|
+
```bash
|
362
|
+
rspec --init # if needed
|
363
|
+
bundle exec rspec
|
364
|
+
```
|
365
|
+
|
366
|
+
You should see an output like this
|
367
|
+
```bash
|
368
|
+
Run options: include {:focus=>true}
|
369
|
+
running live tests
|
370
|
+
.....................................................
|
371
|
+
|
372
|
+
Finished in 6.81 seconds (files took 0.40587 seconds to load)
|
373
|
+
53 examples, 0 failures
|
374
|
+
```
|
375
|
+
|
376
|
+
### Test parameters
|
377
|
+
The tests use the following environment parameters:
|
378
|
+
TEST {unit|live} influences whether mocked unit tests are run or the live server is used (credits may be used if you choose to do this)
|
379
|
+
ZEROBOUNCE_API_KEY {<zerobounce-api-key-value>} this key is used to make requests to the live server; it is also used in mock tests as a valid key sample (any value will work for mock tests)
|
380
|
+
INCORRECT_API_KEY {any non whitespace string value that is not a valid key} used for tests where the requests are meant to fail due to the API key value.
|
381
|
+
|
382
|
+
|
383
|
+
To set them
|
384
|
+
```bash
|
385
|
+
export ZEROBOUNCE_API_KEY=99e7ef20ceea4480a173b07b1be75371
|
386
|
+
export INCORRECT_API_KEY=thiskeyisinvalidorotherwiseincorrect
|
387
|
+
export TEST=unit
|
388
|
+
```
|
389
|
+
|
390
|
+
A .env.sample file is provided.
|
391
|
+
|
392
|
+
Mock tests were generated using webmock and vcr. This means that actual requests were made and recorded in the spec/cassettes with an (at the time) valid API key used for testing purposes. This key has been invalidated in the meantime, however it is provided in the .env.sample file for the mock tests to work. If you do not wish to use this key for mocks, you can replace it with any value in the .yml files under spec/cassettes or delete all of them and rerun the tests so that vcr records them with a new key.
|
393
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yard'
|
4
|
+
require 'bundler/gem_tasks'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
require 'rubocop/rake_task'
|
7
|
+
require 'zerobounce/version'
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new
|
10
|
+
|
11
|
+
RuboCop::RakeTask.new do |task|
|
12
|
+
task.requires << 'rubocop-rspec'
|
13
|
+
end
|
14
|
+
|
15
|
+
YARD::Rake::YardocTask.new do |task|
|
16
|
+
task.options += ['--title', "Zerobounce #{Zerobounce::VERSION} Documentation"]
|
17
|
+
task.options += ['--protected']
|
18
|
+
task.options += ['--no-private']
|
19
|
+
task.stats_options = ['--list-undoc']
|
20
|
+
|
21
|
+
# has to be last
|
22
|
+
extra_files = %w[CODE_OF_CONDUCT.md LICENSE.txt]
|
23
|
+
task.options += ['-'] + extra_files
|
24
|
+
end
|
25
|
+
|
26
|
+
task default: %i[rubocop spec]
|
data/bin/bundle
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'bundle' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "rubygems"
|
12
|
+
|
13
|
+
m = Module.new do
|
14
|
+
module_function
|
15
|
+
|
16
|
+
def invoked_as_script?
|
17
|
+
File.expand_path($0) == File.expand_path(__FILE__)
|
18
|
+
end
|
19
|
+
|
20
|
+
def env_var_version
|
21
|
+
ENV["BUNDLER_VERSION"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def cli_arg_version
|
25
|
+
return unless invoked_as_script? # don't want to hijack other binstubs
|
26
|
+
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
|
27
|
+
bundler_version = nil
|
28
|
+
update_index = nil
|
29
|
+
ARGV.each_with_index do |a, i|
|
30
|
+
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
|
31
|
+
bundler_version = a
|
32
|
+
end
|
33
|
+
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
|
34
|
+
bundler_version = $1 || ">= 0.a"
|
35
|
+
update_index = i
|
36
|
+
end
|
37
|
+
bundler_version
|
38
|
+
end
|
39
|
+
|
40
|
+
def gemfile
|
41
|
+
gemfile = ENV["BUNDLE_GEMFILE"]
|
42
|
+
return gemfile if gemfile && !gemfile.empty?
|
43
|
+
|
44
|
+
File.expand_path("../../Gemfile", __FILE__)
|
45
|
+
end
|
46
|
+
|
47
|
+
def lockfile
|
48
|
+
lockfile =
|
49
|
+
case File.basename(gemfile)
|
50
|
+
when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
|
51
|
+
else "#{gemfile}.lock"
|
52
|
+
end
|
53
|
+
File.expand_path(lockfile)
|
54
|
+
end
|
55
|
+
|
56
|
+
def lockfile_version
|
57
|
+
return unless File.file?(lockfile)
|
58
|
+
lockfile_contents = File.read(lockfile)
|
59
|
+
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
|
60
|
+
Regexp.last_match(1)
|
61
|
+
end
|
62
|
+
|
63
|
+
def bundler_version
|
64
|
+
@bundler_version ||= begin
|
65
|
+
env_var_version || cli_arg_version ||
|
66
|
+
lockfile_version || "#{Gem::Requirement.default}.a"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def load_bundler!
|
71
|
+
ENV["BUNDLE_GEMFILE"] ||= gemfile
|
72
|
+
|
73
|
+
# must dup string for RG < 1.8 compatibility
|
74
|
+
activate_bundler(bundler_version.dup)
|
75
|
+
end
|
76
|
+
|
77
|
+
def activate_bundler(bundler_version)
|
78
|
+
if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0")
|
79
|
+
bundler_version = "< 2"
|
80
|
+
end
|
81
|
+
gem_error = activation_error_handling do
|
82
|
+
gem "bundler", bundler_version
|
83
|
+
end
|
84
|
+
return if gem_error.nil?
|
85
|
+
require_error = activation_error_handling do
|
86
|
+
require "bundler/version"
|
87
|
+
end
|
88
|
+
return if require_error.nil? && Gem::Requirement.new(bundler_version).satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
89
|
+
warn "Activating bundler (#{bundler_version}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_version}'`"
|
90
|
+
exit 42
|
91
|
+
end
|
92
|
+
|
93
|
+
def activation_error_handling
|
94
|
+
yield
|
95
|
+
nil
|
96
|
+
rescue StandardError, LoadError => e
|
97
|
+
e
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
m.load_bundler!
|
102
|
+
|
103
|
+
if m.invoked_as_script?
|
104
|
+
load Gem.bin_path("bundler", "bundle")
|
105
|
+
end
|
data/bin/console
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
email
|
2
|
+
disposable@example.com
|
3
|
+
invalid@example.com
|
4
|
+
valid@example.com
|
5
|
+
toxic@example.com
|
6
|
+
donotmail@example.com
|
7
|
+
spamtrap@example.com
|
8
|
+
abuse@example.com
|
9
|
+
unknown@example.com
|
10
|
+
catch_all@example.com
|
11
|
+
antispam_system@example.com
|
12
|
+
does_not_accept_mail@example.com
|
13
|
+
exception_occurred@example.com
|
14
|
+
failed_smtp_connection@example.com
|
15
|
+
failed_syntax_check@example.com
|
16
|
+
forcible_disconnect@example.com
|
17
|
+
global_suppression@example.com
|
18
|
+
greylisted@example.com
|
19
|
+
leading_period_removed@example.com
|
20
|
+
mail_server_did_not_respond@example.com
|
21
|
+
mail_server_temporary_error@example.com
|
22
|
+
mailbox_quota_exceeded@example.com
|
23
|
+
mailbox_not_found@example.com
|
24
|
+
no_dns_entries@example.com
|
25
|
+
possible_trap@example.com
|
26
|
+
possible_typo@example.com
|
27
|
+
role_based@example.com
|
28
|
+
timeout_exceeded@example.com
|
29
|
+
unroutable_ip_address@example.com
|
30
|
+
free_email@example.com
|
31
|
+
role_based_catch_all@example.com
|
@@ -0,0 +1,31 @@
|
|
1
|
+
email,first,last,gender,ip
|
2
|
+
disposable@example.com,First,Last,male,127.0.0.1
|
3
|
+
invalid@example.com,First,Last,male,127.0.0.1
|
4
|
+
valid@example.com,First,Last,male,127.0.0.1
|
5
|
+
toxic@example.com,First,Last,male,127.0.0.1
|
6
|
+
donotmail@example.com,First,Last,male,127.0.0.1
|
7
|
+
spamtrap@example.com,First,Last,male,127.0.0.1
|
8
|
+
abuse@example.com,First,Last,male,127.0.0.1
|
9
|
+
unknown@example.com,First,Last,male,127.0.0.1
|
10
|
+
catch_all@example.com,First,Last,male,127.0.0.1
|
11
|
+
antispam_system@example.com,First,Last,male,127.0.0.1
|
12
|
+
does_not_accept_mail@example.com,First,Last,male,127.0.0.1
|
13
|
+
exception_occurred@example.com,First,Last,male,127.0.0.1
|
14
|
+
failed_smtp_connection@example.com,First,Last,male,127.0.0.1
|
15
|
+
failed_syntax_check@example.com,First,Last,male,127.0.0.1
|
16
|
+
forcible_disconnect@example.com,First,Last,male,127.0.0.1
|
17
|
+
global_suppression@example.com,First,Last,male,127.0.0.1
|
18
|
+
greylisted@example.com,First,Last,male,127.0.0.1
|
19
|
+
leading_period_removed@example.com,First,Last,male,127.0.0.1
|
20
|
+
mail_server_did_not_respond@example.com,First,Last,male,127.0.0.1
|
21
|
+
mail_server_temporary_error@example.com,First,Last,male,127.0.0.1
|
22
|
+
mailbox_quota_exceeded@example.com,First,Last,male,127.0.0.1
|
23
|
+
mailbox_not_found@example.com,First,Last,male,127.0.0.1
|
24
|
+
no_dns_entries@example.com,First,Last,male,127.0.0.1
|
25
|
+
possible_trap@example.com,First,Last,male,127.0.0.1
|
26
|
+
possible_typo@example.com,First,Last,male,127.0.0.1
|
27
|
+
role_based@example.com,First,Last,male,127.0.0.1
|
28
|
+
timeout_exceeded@example.com,First,Last,male,127.0.0.1
|
29
|
+
unroutable_ip_address@example.com,First,Last,male,127.0.0.1
|
30
|
+
free_email@example.com,First,Last,male,127.0.0.1
|
31
|
+
role_based_catch_all@example.com,First,Last,male,127.0.0.1
|
data/files/scoring.csv
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
zerobounce-ai-scoring.csv
|
@@ -0,0 +1 @@
|
|
1
|
+
zerobounce-batch-validation.csv
|
@@ -0,0 +1,31 @@
|
|
1
|
+
email
|
2
|
+
disposable@example.com
|
3
|
+
invalid@example.com
|
4
|
+
valid@example.com
|
5
|
+
toxic@example.com
|
6
|
+
donotmail@example.com
|
7
|
+
spamtrap@example.com
|
8
|
+
abuse@example.com
|
9
|
+
unknown@example.com
|
10
|
+
catch_all@example.com
|
11
|
+
antispam_system@example.com
|
12
|
+
does_not_accept_mail@example.com
|
13
|
+
exception_occurred@example.com
|
14
|
+
failed_smtp_connection@example.com
|
15
|
+
failed_syntax_check@example.com
|
16
|
+
forcible_disconnect@example.com
|
17
|
+
global_suppression@example.com
|
18
|
+
greylisted@example.com
|
19
|
+
leading_period_removed@example.com
|
20
|
+
mail_server_did_not_respond@example.com
|
21
|
+
mail_server_temporary_error@example.com
|
22
|
+
mailbox_quota_exceeded@example.com
|
23
|
+
mailbox_not_found@example.com
|
24
|
+
no_dns_entries@example.com
|
25
|
+
possible_trap@example.com
|
26
|
+
possible_typo@example.com
|
27
|
+
role_based@example.com
|
28
|
+
timeout_exceeded@example.com
|
29
|
+
unroutable_ip_address@example.com
|
30
|
+
free_email@example.com
|
31
|
+
role_based_catch_all@example.com
|