neverbounce-api 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +8 -0
- data/.gitignore +21 -0
- data/.rspec +4 -0
- data/.rubocop.yml +1161 -0
- data/.travis.yml +27 -0
- data/.yardopts +2 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +48 -0
- data/LICENSE +9 -0
- data/README.md +235 -0
- data/lib/never_bounce/api/client.rb +259 -0
- data/lib/never_bounce/api/error.rb +21 -0
- data/lib/never_bounce/api/feature/basic_initialize.rb +20 -0
- data/lib/never_bounce/api/feature/eigencache.rb +48 -0
- data/lib/never_bounce/api/feature/igetset.rb +41 -0
- data/lib/never_bounce/api/feature/oattrs.rb +100 -0
- data/lib/never_bounce/api/feature/require_attr.rb +27 -0
- data/lib/never_bounce/api/request/account_info.rb +29 -0
- data/lib/never_bounce/api/request/base.rb +102 -0
- data/lib/never_bounce/api/request/jobs_create.rb +90 -0
- data/lib/never_bounce/api/request/jobs_delete.rb +34 -0
- data/lib/never_bounce/api/request/jobs_download.rb +34 -0
- data/lib/never_bounce/api/request/jobs_parse.rb +55 -0
- data/lib/never_bounce/api/request/jobs_results.rb +53 -0
- data/lib/never_bounce/api/request/jobs_search.rb +57 -0
- data/lib/never_bounce/api/request/jobs_start.rb +47 -0
- data/lib/never_bounce/api/request/jobs_status.rb +37 -0
- data/lib/never_bounce/api/request/single_check.rb +67 -0
- data/lib/never_bounce/api/response/account_info.rb +39 -0
- data/lib/never_bounce/api/response/account_info/job_counts.rb +26 -0
- data/lib/never_bounce/api/response/address_info.rb +43 -0
- data/lib/never_bounce/api/response/base.rb +15 -0
- data/lib/never_bounce/api/response/container.rb +126 -0
- data/lib/never_bounce/api/response/credits_info/base.rb +30 -0
- data/lib/never_bounce/api/response/credits_info/monthly.rb +16 -0
- data/lib/never_bounce/api/response/credits_info/paid.rb +20 -0
- data/lib/never_bounce/api/response/error_message.rb +17 -0
- data/lib/never_bounce/api/response/feature/job_status_fields.rb +68 -0
- data/lib/never_bounce/api/response/feature/job_status_fields/total.rb +46 -0
- data/lib/never_bounce/api/response/jobs_create.rb +10 -0
- data/lib/never_bounce/api/response/jobs_delete.rb +8 -0
- data/lib/never_bounce/api/response/jobs_download.rb +19 -0
- data/lib/never_bounce/api/response/jobs_parse.rb +10 -0
- data/lib/never_bounce/api/response/jobs_results.rb +34 -0
- data/lib/never_bounce/api/response/jobs_results/item.rb +65 -0
- data/lib/never_bounce/api/response/jobs_results/query.rb +20 -0
- data/lib/never_bounce/api/response/jobs_search.rb +33 -0
- data/lib/never_bounce/api/response/jobs_search/query.rb +16 -0
- data/lib/never_bounce/api/response/jobs_search/result.rb +13 -0
- data/lib/never_bounce/api/response/jobs_start.rb +10 -0
- data/lib/never_bounce/api/response/jobs_status.rb +11 -0
- data/lib/never_bounce/api/response/message.rb +32 -0
- data/lib/never_bounce/api/response/single_check.rb +68 -0
- data/lib/never_bounce/api/response/status_message.rb +17 -0
- data/lib/never_bounce/api/response/success_message.rb +12 -0
- data/lib/never_bounce/api/session.rb +141 -0
- data/lib/never_bounce/api/version.rb +4 -0
- data/lib/neverbounce-api.rb +4 -0
- data/lib/neverbounce.rb +3 -0
- data/neverbounce-api.gemspec +20 -0
- data/spec/lib/never_bounce/api/client_spec.rb +199 -0
- data/spec/lib/never_bounce/api/feature/basic_initialize_spec.rb +25 -0
- data/spec/lib/never_bounce/api/feature/eigencache_spec.rb +28 -0
- data/spec/lib/never_bounce/api/feature/igetset_spec.rb +45 -0
- data/spec/lib/never_bounce/api/feature/oattrs_spec.rb +72 -0
- data/spec/lib/never_bounce/api/feature/require_attr_spec.rb +25 -0
- data/spec/lib/never_bounce/api/request/account_info_spec.rb +29 -0
- data/spec/lib/never_bounce/api/request/base_spec.rb +6 -0
- data/spec/lib/never_bounce/api/request/jobs_create_spec.rb +89 -0
- data/spec/lib/never_bounce/api/request/jobs_delete_spec.rb +31 -0
- data/spec/lib/never_bounce/api/request/jobs_download_spec.rb +31 -0
- data/spec/lib/never_bounce/api/request/jobs_parse_spec.rb +44 -0
- data/spec/lib/never_bounce/api/request/jobs_results_spec.rb +42 -0
- data/spec/lib/never_bounce/api/request/jobs_search_spec.rb +40 -0
- data/spec/lib/never_bounce/api/request/jobs_start_spec.rb +44 -0
- data/spec/lib/never_bounce/api/request/jobs_status_spec.rb +31 -0
- data/spec/lib/never_bounce/api/request/single_check_spec.rb +44 -0
- data/spec/lib/never_bounce/api/response/account_info/job_counts_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/account_info_spec.rb +9 -0
- data/spec/lib/never_bounce/api/response/address_info_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/base_spec.rb +6 -0
- data/spec/lib/never_bounce/api/response/container_spec.rb +142 -0
- data/spec/lib/never_bounce/api/response/credits_info/base_spec.rb +31 -0
- data/spec/lib/never_bounce/api/response/credits_info/monthly_spec.rb +11 -0
- data/spec/lib/never_bounce/api/response/credits_info/paid_spec.rb +11 -0
- data/spec/lib/never_bounce/api/response/feature/job_status_fields/total_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/feature/job_status_fields_spec.rb +42 -0
- data/spec/lib/never_bounce/api/response/jobs_create_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_delete_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_download_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_parse_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_results/jobs_results_item_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_results/jobs_results_query_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_results_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_search/jobs_search_query_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_search/jobs_search_result_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_search_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_start_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/jobs_status_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/single_check_spec.rb +7 -0
- data/spec/lib/never_bounce/api/response/spec_helper.rb +8 -0
- data/spec/lib/never_bounce/api/session_spec.rb +140 -0
- data/spec/lib/never_bounce/api_spec.rb +8 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/spec_support/include_dir_context.rb +22 -0
- data/spec/spec_support/simplecov.rb +18 -0
- metadata +210 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
require_relative "container"
|
3
|
+
|
4
|
+
module NeverBounce; module API; module Response
|
5
|
+
# Generic address info used in a number of responses.
|
6
|
+
class AddressInfo < Container
|
7
|
+
# @!attribute addr
|
8
|
+
# @return [String]
|
9
|
+
oattr :addr, :scalar
|
10
|
+
|
11
|
+
# @!attribute alias
|
12
|
+
# @return [String]
|
13
|
+
oattr :alias, :scalar
|
14
|
+
|
15
|
+
# @!attribute domain
|
16
|
+
# @return [String]
|
17
|
+
oattr :domain, :scalar
|
18
|
+
|
19
|
+
# @!attribute fqdn
|
20
|
+
# @return [String]
|
21
|
+
oattr :fqdn, :scalar
|
22
|
+
|
23
|
+
# @!attribute host
|
24
|
+
# @return [String]
|
25
|
+
oattr :host, :scalar
|
26
|
+
|
27
|
+
# @!attribute normalized_email
|
28
|
+
# @return [String]
|
29
|
+
oattr :normalized_email, :scalar
|
30
|
+
|
31
|
+
# @!attribute original_email
|
32
|
+
# @return [String]
|
33
|
+
oattr :original_email, :scalar
|
34
|
+
|
35
|
+
# @!attribute subdomain
|
36
|
+
# @return [String]
|
37
|
+
oattr :subdomain, :scalar
|
38
|
+
|
39
|
+
# @!attribute tld
|
40
|
+
# @return [String]
|
41
|
+
oattr :tld, :scalar
|
42
|
+
end
|
43
|
+
end; end; end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
require "never_bounce/api/feature/basic_initialize"
|
3
|
+
require "never_bounce/api/feature/igetset"
|
4
|
+
require "never_bounce/api/feature/require_attr"
|
5
|
+
|
6
|
+
module NeverBounce; module API; module Response
|
7
|
+
# @see API::Feature::BasicInitialize
|
8
|
+
# @see API::Feature::Igetset
|
9
|
+
# @see API::Feature::RequireAttr
|
10
|
+
class Base
|
11
|
+
API::Feature::BasicInitialize.load(self)
|
12
|
+
API::Feature::Igetset.load(self)
|
13
|
+
API::Feature::RequireAttr.load(self)
|
14
|
+
end
|
15
|
+
end; end; end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
require "never_bounce/api/feature/eigencache"
|
5
|
+
require "never_bounce/api/feature/oattrs"
|
6
|
+
require "never_bounce/api/feature/require_attr"
|
7
|
+
|
8
|
+
require_relative "base"
|
9
|
+
|
10
|
+
module NeverBounce; module API; module Response
|
11
|
+
# A container with values, by default supports JSON parsing.
|
12
|
+
# @see API::Feature::Eigencache
|
13
|
+
# @see API::Feature::Oattrs
|
14
|
+
# @see API::Feature::RequireAttr
|
15
|
+
class Container < Base
|
16
|
+
API::Feature::Eigencache.load(self)
|
17
|
+
API::Feature::Oattrs.load(self)
|
18
|
+
API::Feature::RequireAttr.load(self)
|
19
|
+
|
20
|
+
# Container data. Default is JSON-parsed {#raw}.
|
21
|
+
# @!attribute body_hash
|
22
|
+
# @return [Hash]
|
23
|
+
def body_hash
|
24
|
+
_cache[:body_hash] ||= JSON.parse(require_attr(:raw))
|
25
|
+
end
|
26
|
+
|
27
|
+
def body_hash=(value)
|
28
|
+
_cache[:body_hash] = value
|
29
|
+
end
|
30
|
+
|
31
|
+
# Raw response body.
|
32
|
+
# @!attribute raw
|
33
|
+
# @return [String]
|
34
|
+
def raw
|
35
|
+
_cache[:raw]
|
36
|
+
end
|
37
|
+
|
38
|
+
def raw=(value)
|
39
|
+
_cache[:raw] ||= value
|
40
|
+
end
|
41
|
+
|
42
|
+
#--------------------------------------- Misc
|
43
|
+
|
44
|
+
class << self
|
45
|
+
private
|
46
|
+
|
47
|
+
# Declare & register an oattr.
|
48
|
+
#
|
49
|
+
# oattr :first_name, :scalar # => :first_name
|
50
|
+
# oattr ... # Handled by `Feature::Oattrs`.
|
51
|
+
#
|
52
|
+
# @return [Symbol] <tt>name</tt>.
|
53
|
+
# @see Feature::Oattrs::ClassMethods#oattr
|
54
|
+
def oattr(name, type, *args)
|
55
|
+
if type == :scalar
|
56
|
+
scalar_oattr(name, *args)
|
57
|
+
name.tap { oattrs << name }
|
58
|
+
else
|
59
|
+
# Handle other types in parent class.
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Build a generic scalar oattr.
|
65
|
+
#
|
66
|
+
# scalar_oattr :first_name
|
67
|
+
# scalar_oattr :page, type: :integer
|
68
|
+
# scalar_oattr :total_valid, type: :integer, allow_nil: true
|
69
|
+
#
|
70
|
+
# @return [Symbol]
|
71
|
+
def scalar_oattr(name, options = {})
|
72
|
+
o, options = {}, options.dup
|
73
|
+
o[k = :allow_nil] = options.include?(k) ? options.delete(k) : false
|
74
|
+
o[k = :key] = options.delete(k) || name
|
75
|
+
o[k = :type] = options.delete(k) || :any
|
76
|
+
raise ArgumentError, "Unknown options: #{options.inspect}" if not options.empty?
|
77
|
+
|
78
|
+
code = []
|
79
|
+
code << %{attr_writer :#{name}}
|
80
|
+
|
81
|
+
code << case o[:type]
|
82
|
+
when :any
|
83
|
+
%{def #{name}; @#{name} ||= body_hash.fetch("#{o[:key]}"); end}
|
84
|
+
when :float
|
85
|
+
if o[:allow_nil]
|
86
|
+
%{
|
87
|
+
def #{name}
|
88
|
+
@#{name} ||= unless (v = body_hash.fetch("#{o[:key]}")).nil?
|
89
|
+
Float(v)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
}
|
93
|
+
else
|
94
|
+
%{def #{name}; @#{name} ||= Float(body_hash.fetch("#{o[:key]}")); end}
|
95
|
+
end
|
96
|
+
when :integer
|
97
|
+
if o[:allow_nil]
|
98
|
+
%{
|
99
|
+
def #{name}
|
100
|
+
@#{name} ||= unless (v = body_hash.fetch("#{o[:key]}")).nil?
|
101
|
+
Integer(v)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
}
|
105
|
+
else
|
106
|
+
%{def #{name}; @#{name} ||= Integer(body_hash.fetch("#{o[:key]}")); end}
|
107
|
+
end
|
108
|
+
else
|
109
|
+
raise ArgumentError, "Unknown type: #{o[:type].inspect}"
|
110
|
+
end
|
111
|
+
|
112
|
+
class_eval code.join(";")
|
113
|
+
|
114
|
+
name
|
115
|
+
end
|
116
|
+
end # class << self
|
117
|
+
end
|
118
|
+
end; end; end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Implementation notes:
|
122
|
+
#
|
123
|
+
# * I go for `class_eval` rather than `define_method` in order to use Ruby's `||=`.
|
124
|
+
# Going without it would require a bunch of `instance_variable_*` calls per each attribute access.
|
125
|
+
# * The container performs its own value validation according to attribute definitions.
|
126
|
+
# Thus, when creating a sub-container, it's more correct to pass `body` or `body_hash` to let this validation happen in the sub-container class.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
require_relative "../container"
|
3
|
+
|
4
|
+
module NeverBounce; module API; module Response; module CreditsInfo
|
5
|
+
class Base < Container
|
6
|
+
# @!attribute free_credits_remaining
|
7
|
+
# @return [Integer]
|
8
|
+
oattr :free_credits_remaining, :scalar, type: :integer
|
9
|
+
|
10
|
+
# @!attribute free_credits_used
|
11
|
+
# @return [Integer]
|
12
|
+
oattr :free_credits_used, :scalar, type: :integer
|
13
|
+
|
14
|
+
# <tt>:monthly</tt> or <tt>:paid</tt>.
|
15
|
+
# @return [Symbol]
|
16
|
+
def subscription_type
|
17
|
+
raise NotImplementedError, "Redefine `subscription_type` in final class: #{self.class}"
|
18
|
+
end
|
19
|
+
|
20
|
+
# <tt>true</tt> if monthly subscription.
|
21
|
+
def monthly?
|
22
|
+
subscription_type == :monthly
|
23
|
+
end
|
24
|
+
|
25
|
+
# <tt>true</tt> if paid subscription.
|
26
|
+
def paid?
|
27
|
+
subscription_type == :paid
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end; end; end; end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
require_relative "base"
|
3
|
+
|
4
|
+
module NeverBounce; module API; module Response; module CreditsInfo
|
5
|
+
class Monthly < Base
|
6
|
+
# @!attribute monthly_api_usage
|
7
|
+
# @return [Integer]
|
8
|
+
oattr :monthly_api_usage, :scalar, type: :integer
|
9
|
+
|
10
|
+
# Always <tt>:monthly</tt>.
|
11
|
+
# @return [Symbol]
|
12
|
+
def subscription_type
|
13
|
+
:monthly
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end; end; end; end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
require_relative "base"
|
3
|
+
|
4
|
+
module NeverBounce; module API; module Response; module CreditsInfo
|
5
|
+
class Paid < Base
|
6
|
+
# @!attribute paid_credits_remaining
|
7
|
+
# @return [Integer]
|
8
|
+
oattr :paid_credits_remaining, :scalar, type: :integer
|
9
|
+
|
10
|
+
# @!attribute paid_credits_used
|
11
|
+
# @return [Integer]
|
12
|
+
oattr :paid_credits_used, :scalar, type: :integer
|
13
|
+
|
14
|
+
# Always <tt>:paid</tt>.
|
15
|
+
# @return [Symbol]
|
16
|
+
def subscription_type
|
17
|
+
:paid
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end; end; end; end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
require_relative "status_message"
|
3
|
+
|
4
|
+
module NeverBounce; module API; module Response
|
5
|
+
# A failure (error) response from the server.
|
6
|
+
# @see https://developers.neverbounce.com/v4.0/reference#error-handling
|
7
|
+
class ErrorMessage < StatusMessage
|
8
|
+
# @!attribute message
|
9
|
+
# @return [String]
|
10
|
+
oattr :message, :scalar
|
11
|
+
|
12
|
+
# @return [false]
|
13
|
+
def success?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end; end; end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
require "never_bounce/api/response/container"
|
3
|
+
|
4
|
+
module NeverBounce; module API; module Response; module Feature
|
5
|
+
# Common traits for message/container of the job status.
|
6
|
+
# @see InstanceMethods
|
7
|
+
module JobStatusFields
|
8
|
+
require_relative "job_status_fields/total"
|
9
|
+
|
10
|
+
# @param owner [Class]
|
11
|
+
# @return [nil]
|
12
|
+
def self.load(owner)
|
13
|
+
# Validate owner, or calls to `oattr` will fail.
|
14
|
+
raise ArgumentError, "Class #{owner} is not an ancestor of Response::Container" if not owner < Response::Container
|
15
|
+
|
16
|
+
return if owner < InstanceMethods
|
17
|
+
owner.send(:include, InstanceMethods)
|
18
|
+
|
19
|
+
owner.class_eval do
|
20
|
+
oattr :id, :scalar, type: :integer
|
21
|
+
|
22
|
+
oattr :job_status, :scalar
|
23
|
+
|
24
|
+
oattr :bounce_estimate, :scalar, type: :float
|
25
|
+
oattr :filename, :scalar
|
26
|
+
oattr :percent_complete, :scalar, type: :integer
|
27
|
+
|
28
|
+
oattr :total, :writer
|
29
|
+
|
30
|
+
oattr :created_at, :scalar
|
31
|
+
oattr :finished_at, :scalar
|
32
|
+
oattr :started_at, :scalar
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# @!attribute id
|
37
|
+
# @return [Integer]
|
38
|
+
# @!attribute job_status
|
39
|
+
# @return [String]
|
40
|
+
# @!attribute bounce_estimate
|
41
|
+
# @return [Float]
|
42
|
+
# @!attribute filename
|
43
|
+
# @return [String]
|
44
|
+
# @!attribute percent_complete
|
45
|
+
# @return [Integer]
|
46
|
+
# @!attribute total
|
47
|
+
# @return [Total]
|
48
|
+
# @!attribute created_at
|
49
|
+
# @return [String]
|
50
|
+
# @!attribute finished_at
|
51
|
+
# @return [String]
|
52
|
+
# @!attribute started_at
|
53
|
+
# @return [String]
|
54
|
+
module InstanceMethods
|
55
|
+
def total
|
56
|
+
@total ||= Total.new(body_hash: body_hash.fetch("total"))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end; end; end; end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Implementation notes:
|
64
|
+
#
|
65
|
+
# * (!) No means discovered to tell YARD that class A inherits methods from here.
|
66
|
+
# Thus, we use a regular `@see` in those using this and other features.
|
67
|
+
# * YARD can't read `@!attribute` from inside `class_eval`, just ignores the comments.
|
68
|
+
# * YARD sorts all attributes alphabetically, we maintain our order, which is logical+alpha.
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
require_relative "../job_status_fields"
|
3
|
+
|
4
|
+
module NeverBounce; module API; module Response; module Feature; module JobStatusFields
|
5
|
+
class Total < Container
|
6
|
+
# @!attribute bad_syntax
|
7
|
+
# @return [Integer]
|
8
|
+
oattr :bad_syntax, :scalar, type: :integer, allow_nil: true
|
9
|
+
|
10
|
+
# @!attribute billable
|
11
|
+
# @return [Integer]
|
12
|
+
oattr :billable, :scalar, type: :integer, allow_nil: true
|
13
|
+
|
14
|
+
# @!attribute catchall
|
15
|
+
# @return [Integer]
|
16
|
+
oattr :catchall, :scalar, type: :integer, allow_nil: true
|
17
|
+
|
18
|
+
# @!attribute disposable
|
19
|
+
# @return [Integer]
|
20
|
+
oattr :disposable, :scalar, type: :integer, allow_nil: true
|
21
|
+
|
22
|
+
# @!attribute duplicates
|
23
|
+
# @return [Integer]
|
24
|
+
oattr :duplicates, :scalar, type: :integer, allow_nil: true
|
25
|
+
|
26
|
+
# @!attribute invalid
|
27
|
+
# @return [Integer]
|
28
|
+
oattr :invalid, :scalar, type: :integer, allow_nil: true
|
29
|
+
|
30
|
+
# @!attribute processed
|
31
|
+
# @return [Integer]
|
32
|
+
oattr :processed, :scalar, type: :integer, allow_nil: true
|
33
|
+
|
34
|
+
# @!attribute records
|
35
|
+
# @return [Integer]
|
36
|
+
oattr :records, :scalar, type: :integer, allow_nil: true
|
37
|
+
|
38
|
+
# @!attribute unknown
|
39
|
+
# @return [Integer]
|
40
|
+
oattr :unknown, :scalar, type: :integer, allow_nil: true
|
41
|
+
|
42
|
+
# @!attribute valid
|
43
|
+
# @return [Integer]
|
44
|
+
oattr :valid, :scalar, type: :integer, allow_nil: true
|
45
|
+
end
|
46
|
+
end; end; end; end; end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
require_relative "message"
|
3
|
+
|
4
|
+
module NeverBounce; module API; module Response
|
5
|
+
# A response to <tt>jobs/download</tt>.
|
6
|
+
# Body is an octet-stream, not a JSON structure.
|
7
|
+
# @see https://developers.neverbounce.com/v4.0/reference#jobs-download
|
8
|
+
class JobsDownload < Message
|
9
|
+
# Always <tt>true</tt>.
|
10
|
+
def success?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end; end; end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Implementation notes:
|
18
|
+
#
|
19
|
+
# * This class uses `body` in its literal form. All the rest basically JSON-parse it.
|