zerobounce-sdk 2.0.13 → 2.1.1

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: 0ad61a7b25f176cba88173c9da307a70ac39a4526ff754f249c6a1d5aa58c598
4
- data.tar.gz: 2de69f283fcfaeb2b1dfa7a8737c52353a7a3e54a7db40af28d0841ccb271a33
3
+ metadata.gz: 60c469eb651d7c50fcd27c4fa2ccfe184ea153865eea585831e05307a8e245b4
4
+ data.tar.gz: e065cdbfc1c0f70ee90e269510de7303f97f359e2e4df4949ab7eea987a00c36
5
5
  SHA512:
6
- metadata.gz: d822a0fbfbded2214b11769169462c9148afac977edf7975e1ba960710e78fce5ac8b104b896779177e1e9685ec7fa39153dca00d0e6ded5f934ab8738969ae9
7
- data.tar.gz: e0e097b43500401d4c0f8c737ffd9cabf9254132aa7da5774603db371363487277fc4738c15738881ef95b50535b555e3a723619a2fffef47d1c555ac57971c3
6
+ metadata.gz: 6c7032ef36844f5efbf3c77b26865b39da3dd70c771650d058a769542e9088b69d49fb394edd71f826180b8fae56a7554f9b54f654f01b946a7e6abf1a7868f1
7
+ data.tar.gz: 00d077d6a89832700cd8818870f915aabbedc8b13c498e7c57861cef763316a6ecdffe38ec7f41d2f6538af05d0844c401e81319df70dc7703df9e0e2a22f225
data/.dockerignore ADDED
@@ -0,0 +1,17 @@
1
+ # Keep .git so gemspec `git ls-files` works during `bundle install` in the image.
2
+
3
+ # Docs and tooling not needed to run specs in the image
4
+ *.md
5
+ documentation*.md
6
+ .spec
7
+ .rspec_status
8
+ coverage/
9
+ tmp/
10
+ pkg/
11
+ vendor/bundle
12
+
13
+ # OS & env
14
+ .DS_Store
15
+ Thumbs.db
16
+ .env
17
+ .env.*
@@ -0,0 +1,35 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#versioning-strategy
4
+
5
+ version: 2
6
+ updates:
7
+ # Keep the Ruby dependencies up to date
8
+ - package-ecosystem: "bundler"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
12
+ day: "monday"
13
+ target-branch: "develop"
14
+ labels:
15
+ - "ruby dependencies"
16
+ groups:
17
+ bundler:
18
+ applies-to: version-updates
19
+ patterns:
20
+ - "*"
21
+
22
+ # Keep the Github Actions dependencies up to date
23
+ - package-ecosystem: "github-actions"
24
+ directory: "/"
25
+ schedule:
26
+ interval: "weekly"
27
+ day: "monday"
28
+ target-branch: "develop"
29
+ labels:
30
+ - "github dependencies"
31
+ groups:
32
+ github:
33
+ applies-to: version-updates
34
+ patterns:
35
+ - "*"
@@ -16,6 +16,6 @@ jobs:
16
16
  name: Auto assign (me only)
17
17
  runs-on: ubuntu-latest
18
18
  steps:
19
- - uses: kentaro-m/auto-assign-action@v2.0.1
19
+ - uses: kentaro-m/auto-assign-action@v2.0.2
20
20
  with:
21
21
  configuration-path: ".github/auto_assign.yml"
data/.gitignore CHANGED
@@ -64,4 +64,7 @@ output.err
64
64
  output.log
65
65
 
66
66
  .DS_Store
67
+ Thumbs.db
68
+ .idea/
69
+ .cursor/
67
70
  .env
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 2.1.1
2
+
3
+ * Raise development and transitive dependency floors to address security advisories for REXML, Addressable, and YARD (updated `Gemfile.lock`; see `Gemfile` and `zerobounce.gemspec`).
4
+
1
5
  # 0.3.0
2
6
  * Update ruby and bundler version
3
7
 
data/Dockerfile CHANGED
@@ -6,10 +6,12 @@ RUN apk add --no-cache build-base git
6
6
  WORKDIR /app
7
7
 
8
8
  COPY . .
9
- RUN bundle config set --local path 'vendor/bundle' && \
10
- bundle install
9
+ # Gemfile.lock expects Bundler 2.4.x (see gemspec); Ruby 3.2 image may ship Bundler 4.x.
10
+ RUN gem install bundler -v 2.4.22 && \
11
+ bundle config set --local path 'vendor/bundle' && \
12
+ bundle _2.4.22_ install
11
13
 
12
14
  # Dummy key for VCR/cassette-based specs; override with env for live API
13
15
  ENV ZEROBOUNCE_API_KEY="${ZEROBOUNCE_API_KEY:-invalid_key_for_tests}"
14
16
 
15
- CMD ["bundle", "exec", "rspec"]
17
+ CMD ["bundle", "_2.4.22_", "exec", "rspec"]
data/Gemfile CHANGED
@@ -7,3 +7,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
7
7
  # Specify your gem's dependencies in zerobounce.gemspec
8
8
  gemspec
9
9
 
10
+ # Transitive dependency floors (security advisories: REXML DoS/ReDoS, Addressable ReDoS).
11
+ gem 'rexml', '>= 3.4.4'
12
+ gem 'addressable', '>= 2.8.10'
13
+
data/Gemfile.lock CHANGED
@@ -1,15 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zerobounce-sdk (2.0.13)
4
+ zerobounce-sdk (2.1.1)
5
5
  dotenv
6
6
  rest-client (~> 2.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- addressable (2.8.4)
12
- public_suffix (>= 2.0.2, < 6.0)
11
+ addressable (2.9.0)
12
+ public_suffix (>= 2.0.2, < 8.0)
13
13
  ast (2.4.2)
14
14
  base64 (0.3.0)
15
15
  bigdecimal (4.0.1)
@@ -37,7 +37,7 @@ GEM
37
37
  pry (0.14.2)
38
38
  coderay (~> 1.1)
39
39
  method_source (~> 1.0)
40
- public_suffix (5.0.1)
40
+ public_suffix (7.0.5)
41
41
  rainbow (3.1.1)
42
42
  rake (13.0.6)
43
43
  regexp_parser (2.7.0)
@@ -46,7 +46,7 @@ GEM
46
46
  http-cookie (>= 1.0.2, < 2.0)
47
47
  mime-types (>= 1.16, < 4.0)
48
48
  netrc (~> 0.8)
49
- rexml (3.2.5)
49
+ rexml (3.4.4)
50
50
  rspec (3.12.0)
51
51
  rspec-core (~> 3.12.0)
52
52
  rspec-expectations (~> 3.12.0)
@@ -100,18 +100,20 @@ GEM
100
100
  addressable (>= 2.8.0)
101
101
  crack (>= 0.3.2)
102
102
  hashdiff (>= 0.4.0, < 2.0.0)
103
- yard (0.9.32)
103
+ yard (0.9.38)
104
104
 
105
105
  PLATFORMS
106
106
  arm64-darwin-24
107
107
  x86_64-linux
108
108
 
109
109
  DEPENDENCIES
110
+ addressable (>= 2.8.10)
110
111
  base64
111
112
  bigdecimal
112
113
  bundler (~> 2.4.6)
113
114
  pry (~> 0.14.1)
114
115
  rake (~> 13.0)
116
+ rexml (>= 3.4.4)
115
117
  rspec (~> 3.0)
116
118
  rspec_junit_formatter (~> 0.4.1)
117
119
  rubocop (~> 1.15)
@@ -121,8 +123,8 @@ DEPENDENCIES
121
123
  simplecov (~> 0.21.2)
122
124
  vcr (~> 6.1.0)
123
125
  webmock (~> 3.18)
124
- yard (~> 0.9.26)
126
+ yard (~> 0.9.36)
125
127
  zerobounce-sdk!
126
128
 
127
129
  BUNDLED WITH
128
- 2.4.6
130
+ 2.4.22
data/README.md CHANGED
@@ -381,10 +381,13 @@ Send file
381
381
  last_name_column: 3,
382
382
  gender_column: 4,
383
383
  has_header_row: true,
384
- return_url: nil # results callback url
384
+ return_url: nil, # results callback url
385
+ allow_phase_2: true # optional; validation bulk sendfile only (omit or nil to skip)
385
386
  # Zerobounce.validate_file_send(validate_file_path, email_address_column: 1, gender_column: 4)
386
387
  ```
387
388
 
389
+ Bulk validation uses `https://bulkapi.zerobounce.net/v2`. See [v2 send file](https://www.zerobounce.net/docs/email-validation-api-quickstart/v2-send-file), [v2 file status](https://www.zerobounce.net/docs/email-validation-api-quickstart/v2-file-status), and [v2 get file](https://www.zerobounce.net/docs/email-validation-api-quickstart/v2-get-file).
390
+
388
391
  Check file
389
392
  ```ruby
390
393
  file_id = "75d854a6-565c-49f9-b4c8-b3344480ec4c"
@@ -397,6 +400,7 @@ Zerobounce.validate_file_check(file_id)
397
400
  "upload_date"=>"2023-04-28T15:25:41Z",
398
401
  "file_status"=>"Greylisted",
399
402
  "complete_percentage"=>"0%",
403
+ "file_phase_2_status"=>"N/A", # when present (validation bulk v2)
400
404
  "error_reason"=>nil,
401
405
  "return_url"=>nil}
402
406
  ```
@@ -409,6 +413,18 @@ Zerobounce.validate_file_get(file_id)
409
413
  => "\"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"
410
414
  ```
411
415
 
416
+ Optional [v2 get file](https://www.zerobounce.net/docs/email-validation-api-quickstart/v2-get-file) query parameters use `Zerobounce::GetFileOptions` and `Zerobounce::DownloadType` (`PHASE_1`, `PHASE_2`, `COMBINED`). Set `activity_data` for validation `validate_file_get` only; it is not sent for `scoring_file_get`.
417
+
418
+ ```ruby
419
+ opts = Zerobounce::GetFileOptions.new(
420
+ download_type: Zerobounce::DownloadType::COMBINED,
421
+ activity_data: true
422
+ )
423
+ csv = Zerobounce.validate_file_get(file_id, opts)
424
+ ```
425
+
426
+ Non-success HTTP responses or JSON error bodies (including some HTTP 200 responses with `"success": false`) raise `RuntimeError` with the API message. To inspect a raw body string, use `Zerobounce.get_file_json_indicates_error?(body)`.
427
+
412
428
  Delete file
413
429
  ```ruby
414
430
  file_id = "75d854a6-565c-49f9-b4c8-b3344480ec4c"
@@ -462,13 +478,15 @@ file_id = "89fb7262-b845-4fa1-aa25-e486347ec64e"
462
478
  => "89fb7262-b845-4fa1-aa25-e486347ec64e"
463
479
  Zerobounce.scoring_file_get(file_id)
464
480
  => "\"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\""
481
+ # Optional second argument: GetFileOptions with download_type only (activity_data is not sent for scoring getfile)
482
+ # Zerobounce.scoring_file_get(file_id, Zerobounce::GetFileOptions.new(download_type: Zerobounce::DownloadType::PHASE_2))
465
483
  ```
466
484
 
467
485
  Delete file
468
486
  ```ruby
469
487
  file_id = "89fb7262-b845-4fa1-aa25-e486347ec64e"
470
488
  => "89fb7262-b845-4fa1-aa25-e486347ec64e"
471
- Zerobounce.validate_file_delete(file_id)
489
+ Zerobounce.scoring_file_delete(file_id)
472
490
  => {"success"=>false, "message"=>"File cannot be found."}
473
491
  ```
474
492
 
@@ -716,6 +734,13 @@ docker compose build ruby
716
734
  docker compose run --rm ruby
717
735
  ```
718
736
 
737
+ Or from this directory:
738
+
739
+ ```bash
740
+ docker build -t zb-ruby-sdk .
741
+ docker run --rm zb-ruby-sdk
742
+ ```
743
+
719
744
  ### Run tests (local)
720
745
  ```bash
721
746
  bundle exec rspec
data/documentation.md CHANGED
@@ -268,10 +268,13 @@ Send file
268
268
  last_name_column: 3,
269
269
  gender_column: 4,
270
270
  has_header_row: true,
271
- return_url: nil ### results callback url
271
+ return_url: nil, ### results callback url
272
+ allow_phase_2: true ### optional; validation bulk sendfile only (omit or nil to skip)
272
273
  ### Zerobounce.validate_file_send(validate_file_path, email_address_column: 1, gender_column: 4)
273
274
  ```
274
275
 
276
+ Bulk validation uses `https://bulkapi.zerobounce.net/v2`. See [v2 send file](https://www.zerobounce.net/docs/email-validation-api-quickstart/v2-send-file), [v2 file status](https://www.zerobounce.net/docs/email-validation-api-quickstart/v2-file-status), and [v2 get file](https://www.zerobounce.net/docs/email-validation-api-quickstart/v2-get-file).
277
+
275
278
  Check file
276
279
  ```ruby
277
280
  file_id = "75d854a6-565c-49f9-b4c8-b3344480ec4c"
@@ -284,6 +287,7 @@ Zerobounce.validate_file_check(file_id)
284
287
  "upload_date"=>"2023-04-28T15:25:41Z",
285
288
  "file_status"=>"Greylisted",
286
289
  "complete_percentage"=>"0%",
290
+ "file_phase_2_status"=>"N/A", ### when present (validation bulk v2)
287
291
  "error_reason"=>nil,
288
292
  "return_url"=>nil}
289
293
  ```
@@ -296,6 +300,16 @@ Zerobounce.validate_file_get(file_id)
296
300
  => "\"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"
297
301
  ```
298
302
 
303
+ Optional [v2 get file](https://www.zerobounce.net/docs/email-validation-api-quickstart/v2-get-file) query parameters: `Zerobounce::GetFileOptions` and `Zerobounce::DownloadType` (`PHASE_1`, `PHASE_2`, `COMBINED`). Use `activity_data` on the options for validation `validate_file_get` only. JSON error bodies (including some HTTP 200 responses) raise `RuntimeError`; use `Zerobounce.get_file_json_indicates_error?(body)` on a raw string if needed.
304
+
305
+ ```ruby
306
+ opts = Zerobounce::GetFileOptions.new(
307
+ download_type: Zerobounce::DownloadType::COMBINED,
308
+ activity_data: true
309
+ )
310
+ csv = Zerobounce.validate_file_get(file_id, opts)
311
+ ```
312
+
299
313
  Delete file
300
314
  ```ruby
301
315
  file_id = "75d854a6-565c-49f9-b4c8-b3344480ec4c"
@@ -349,13 +363,14 @@ file_id = "89fb7262-b845-4fa1-aa25-e486347ec64e"
349
363
  => "89fb7262-b845-4fa1-aa25-e486347ec64e"
350
364
  Zerobounce.scoring_file_get(file_id)
351
365
  => "\"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\""
366
+ ### Optional second argument: GetFileOptions with download_type only (activity_data is not sent for scoring getfile)
352
367
  ```
353
368
 
354
369
  Delete file
355
370
  ```ruby
356
371
  file_id = "89fb7262-b845-4fa1-aa25-e486347ec64e"
357
372
  => "89fb7262-b845-4fa1-aa25-e486347ec64e"
358
- Zerobounce.validate_file_delete(file_id)
373
+ Zerobounce.scoring_file_delete(file_id)
359
374
  => {"success"=>false, "message"=>"File cannot be found."}
360
375
  ```
361
376
 
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zerobounce
4
+ # Values for bulk getfile query parameter +download_type+ (validation and scoring).
5
+ module DownloadType
6
+ PHASE_1 = 'phase_1'
7
+ PHASE_2 = 'phase_2'
8
+ COMBINED = 'combined'
9
+ end
10
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'stringio'
5
+
6
+ module Zerobounce
7
+ # Bulk getfile response handling (v2): HTTP errors, JSON error bodies (including HTTP 200).
8
+ module GetFileHelper
9
+ module_function
10
+
11
+ # @param [String] body
12
+ # @return [Boolean]
13
+ def json_indicates_error?(body)
14
+ t = body.to_s.lstrip
15
+ return false if t.empty? || t[0] != '{'
16
+
17
+ o = JSON.parse(t)
18
+ return false unless o.is_a?(Hash)
19
+
20
+ if o.key?('success')
21
+ s = o['success']
22
+ return true if s == false || s == 'False' || s == 'false'
23
+ end
24
+
25
+ %w[message error error_message].each do |k|
26
+ v = o[k]
27
+ next if v.nil?
28
+
29
+ return true if v.is_a?(String) && !v.strip.empty?
30
+ return true if v.is_a?(Array) && !v.empty?
31
+ end
32
+
33
+ o.key?('success')
34
+ rescue JSON::ParserError
35
+ false
36
+ end
37
+
38
+ # @param [String] body
39
+ # @return [String]
40
+ def format_error_message(body)
41
+ o = JSON.parse(body.to_s)
42
+ return body.to_s unless o.is_a?(Hash)
43
+
44
+ %w[message error error_message].each do |k|
45
+ v = o[k]
46
+ next if v.nil?
47
+ return v.strip if v.is_a?(String) && !v.strip.empty?
48
+ return v[0].strip if v.is_a?(Array) && v[0].is_a?(String)
49
+ end
50
+ body.to_s
51
+ rescue JSON::ParserError
52
+ body.to_s.empty? ? 'Invalid getfile response' : body.to_s
53
+ end
54
+
55
+ # @param [String] body
56
+ # @param [String] content_type
57
+ # @return [Boolean]
58
+ def should_treat_as_error?(body, content_type)
59
+ ct = content_type.to_s.downcase
60
+ return true if ct.include?('application/json')
61
+
62
+ json_indicates_error?(body)
63
+ end
64
+
65
+ # @param [RestClient::Response] response
66
+ # @return [String] CSV/text body on success
67
+ def process_getfile_response(response)
68
+ code = response.code.to_i
69
+ body_str = response.body.to_s
70
+ ct = (response.headers[:content_type] || response.headers['Content-Type'] || '').to_s
71
+
72
+ if code > 299
73
+ msg = if body_str.lstrip.start_with?('{')
74
+ format_error_message(body_str)
75
+ else
76
+ body_str.empty? ? "HTTP #{code}" : body_str
77
+ end
78
+ raise msg
79
+ end
80
+
81
+ if should_treat_as_error?(body_str, ct)
82
+ raise format_error_message(body_str)
83
+ end
84
+
85
+ io = StringIO.new(response.body)
86
+ io.set_encoding_by_bom
87
+ io.string
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zerobounce
4
+ # Optional query parameters for bulk getfile.
5
+ # +activity_data+ applies to validation +validate_file_get+ only; scoring getfile does not send it.
6
+ class GetFileOptions
7
+ attr_accessor :download_type, :activity_data
8
+
9
+ def initialize(download_type: nil, activity_data: nil)
10
+ @download_type = download_type
11
+ @activity_data = activity_data
12
+ end
13
+ end
14
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'zerobounce/base_request'
4
+ require 'zerobounce/get_file_helper'
4
5
 
5
6
  module Zerobounce
6
7
 
@@ -41,6 +42,11 @@ module Zerobounce
41
42
  end
42
43
  end
43
44
 
45
+ def self.bulk_getfile(path, params)
46
+ response = self._get(Zerobounce.configuration.bulk_api_root_url, path, params, 'application/json')
47
+ GetFileHelper.process_getfile_response(response)
48
+ end
49
+
44
50
  def self.bulk_post(path, params, content_type='application/json', filepath=nil)
45
51
  response = self._post(Zerobounce.configuration.bulk_api_root_url, path, params, \
46
52
  content_type, filepath)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'stringio'
4
4
  require 'zerobounce/base_request'
5
+ require 'zerobounce/get_file_helper'
5
6
 
6
7
  module Zerobounce
7
8
 
@@ -47,6 +48,12 @@ module Zerobounce
47
48
  end
48
49
  end
49
50
 
51
+ # Bulk getfile only: treats non-2xx and JSON error payloads (including HTTP 200) as failures.
52
+ def self.bulk_getfile(path, params)
53
+ response = self._get(Zerobounce.configuration.bulk_api_root_url, path, params, 'application/json')
54
+ GetFileHelper.process_getfile_response(response)
55
+ end
56
+
50
57
  def self.bulk_post(path, params, content_type='application/json', filepath=nil)
51
58
  response = self._post(Zerobounce.configuration.bulk_api_root_url, path, params, \
52
59
  content_type, filepath)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Zerobounce
4
4
  # The version of the gem.
5
- VERSION = '2.0.13'
5
+ VERSION = '2.1.1'
6
6
  end
data/lib/zerobounce.rb CHANGED
@@ -6,6 +6,9 @@ require 'tempfile'
6
6
 
7
7
  require 'zerobounce/error'
8
8
  require 'zerobounce/version'
9
+ require 'zerobounce/download_type'
10
+ require 'zerobounce/get_file_options'
11
+ require 'zerobounce/get_file_helper'
9
12
  require 'zerobounce/validate_status'
10
13
  require 'zerobounce/validate_sub_status'
11
14
  require 'zerobounce/request'
@@ -29,6 +32,14 @@ module Zerobounce
29
32
  end
30
33
  alias config configuration
31
34
 
35
+ # Whether a getfile response body looks like a JSON error payload (including HTTP 200).
36
+ #
37
+ # @param [String] body
38
+ # @return [Boolean]
39
+ def get_file_json_indicates_error?(body)
40
+ GetFileHelper.json_indicates_error?(body)
41
+ end
42
+
32
43
  # Configure Zerobounce inside a block.
33
44
  #
34
45
  # @example
@@ -247,7 +258,8 @@ module Zerobounce
247
258
  last_name_column: 3,
248
259
  gender_column: 4,
249
260
  has_header_row: true,
250
- return_url: nil
261
+ return_url: nil,
262
+ allow_phase_2: nil
251
263
  )
252
264
  params = {
253
265
  email_address_column: email_address_column,
@@ -257,6 +269,9 @@ module Zerobounce
257
269
  params[:last_name_column] = last_name_column if last_name_column
258
270
  params[:gender_column] = gender_column if gender_column
259
271
  params[:return_url] = return_url if return_url
272
+ unless allow_phase_2.nil?
273
+ params[:allow_phase_2] = allow_phase_2 ? 'true' : 'false'
274
+ end
260
275
  @@request.bulk_post('sendfile', params, 'multipart/form-data', filepath)
261
276
  end
262
277
 
@@ -270,6 +285,7 @@ module Zerobounce
270
285
  # @option [Int] :gender_column
271
286
  # @option [Int] :has_header_row
272
287
  # @option [Int] :return_url
288
+ # @option [Boolean] :allow_phase_2 When set, sends allow_phase_2 (validation bulk only).
273
289
  # @return [Hash] same as validate_file_send
274
290
  def validate_file_send_stream(io, file_name, **opts)
275
291
  content = io.respond_to?(:read) ? io.read : io.to_s
@@ -304,13 +320,20 @@ module Zerobounce
304
320
 
305
321
  # Get validate results file
306
322
  #
307
- # @param [String] :file_id Id of the file.
308
- #
309
- # @return [String/File?]
310
- def validate_file_get(file_id)
311
- # todo:
312
- params = {file_id: file_id}
313
- @@request.bulk_get('getfile', params)
323
+ # @param [String] file_id Id of the file.
324
+ # @param [Zerobounce::GetFileOptions, nil] options Optional +download_type+ and +activity_data+ (validation bulk only).
325
+ #
326
+ # @return [String] file body on success
327
+ # @raise [RuntimeError] on API/JSON error responses
328
+ def validate_file_get(file_id, options = nil)
329
+ params = { file_id: file_id }
330
+ if options
331
+ params[:download_type] = options.download_type if options.download_type
332
+ unless options.activity_data.nil?
333
+ params[:activity_data] = options.activity_data ? 'true' : 'false'
334
+ end
335
+ end
336
+ @@request.bulk_getfile('getfile', params)
314
337
  end
315
338
 
316
339
  # Delete validate file
@@ -376,15 +399,19 @@ module Zerobounce
376
399
  end
377
400
  end
378
401
 
379
- # Get validate results file
402
+ # Get scoring bulk results file
380
403
  #
381
- # @param [String] :file_id Id of the file.
404
+ # @param [String] file_id Id of the file.
405
+ # @param [Zerobounce::GetFileOptions, nil] options Optional +download_type+; +activity_data+ is not sent.
382
406
  #
383
- # @return [String/File?]
384
- def scoring_file_get(file_id)
385
- # todo:
386
- params = {file_id: file_id}
387
- @@request.bulk_get('scoring/getfile', params)
407
+ # @return [String] file body on success
408
+ # @raise [RuntimeError] on API/JSON error responses
409
+ def scoring_file_get(file_id, options = nil)
410
+ params = { file_id: file_id }
411
+ if options && options.download_type
412
+ params[:download_type] = options.download_type
413
+ end
414
+ @@request.bulk_getfile('scoring/getfile', params)
388
415
  end
389
416
 
390
417
  # Get validate file status
data/zerobounce.gemspec CHANGED
@@ -41,7 +41,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
41
41
  spec.add_development_dependency 'rubocop-rake', '~> 0.5.1'
42
42
  spec.add_development_dependency 'rubocop-rspec', '~> 2.3'
43
43
  spec.add_development_dependency 'simplecov', '~> 0.21.2'
44
- spec.add_development_dependency 'yard', '~> 0.9.26'
44
+ spec.add_development_dependency 'yard', '~> 0.9.36'
45
45
  spec.add_development_dependency 'webmock', '~> 3.18'
46
46
  spec.add_development_dependency 'vcr', '~> 6.1.0'
47
47
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zerobounce-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.13
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zero Bounce
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-03-03 00:00:00.000000000 Z
10
+ date: 2026-04-09 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rest-client
@@ -217,14 +217,14 @@ dependencies:
217
217
  requirements:
218
218
  - - "~>"
219
219
  - !ruby/object:Gem::Version
220
- version: 0.9.26
220
+ version: 0.9.36
221
221
  type: :development
222
222
  prerelease: false
223
223
  version_requirements: !ruby/object:Gem::Requirement
224
224
  requirements:
225
225
  - - "~>"
226
226
  - !ruby/object:Gem::Version
227
- version: 0.9.26
227
+ version: 0.9.36
228
228
  - !ruby/object:Gem::Dependency
229
229
  name: webmock
230
230
  requirement: !ruby/object:Gem::Requirement
@@ -260,8 +260,10 @@ executables: []
260
260
  extensions: []
261
261
  extra_rdoc_files: []
262
262
  files:
263
+ - ".dockerignore"
263
264
  - ".env.example"
264
265
  - ".github/auto_assign.yml"
266
+ - ".github/dependabot.yml"
265
267
  - ".github/workflows/auto_assign_ci.yaml"
266
268
  - ".github/workflows/codeql.yml"
267
269
  - ".github/workflows/sdk_ci.yml"
@@ -293,7 +295,10 @@ files:
293
295
  - lib/zerobounce/api_urls.rb
294
296
  - lib/zerobounce/base_request.rb
295
297
  - lib/zerobounce/configuration.rb
298
+ - lib/zerobounce/download_type.rb
296
299
  - lib/zerobounce/error.rb
300
+ - lib/zerobounce/get_file_helper.rb
301
+ - lib/zerobounce/get_file_options.rb
297
302
  - lib/zerobounce/mock_request.rb
298
303
  - lib/zerobounce/request.rb
299
304
  - lib/zerobounce/validate_status.rb