loqate 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,149 @@
1
+ require 'loqate/address/address'
2
+ require 'loqate/address/detailed_address'
3
+ require 'loqate/error'
4
+ require 'loqate/client'
5
+ require 'loqate/result'
6
+ require 'loqate/mappers/error_mapper'
7
+ require 'loqate/mappers/generic_mapper'
8
+
9
+ module Loqate
10
+ module Address
11
+ # Address Verification consists of two main API requests: a Find request is used to narrow down a possible
12
+ # list of addresses; and a Retrieve request is used to retrieve a fully formatted address.
13
+ #
14
+ # A typical address search is made up of a series of Find requests, followed by a Retrieve based on the
15
+ # user selection. Choose a service below to find out how to use each request.
16
+ #
17
+ class Gateway
18
+ FIND_ENDPOINT = '/Capture/Interactive/Find/v1.00/json3.ws'.freeze
19
+ RETRIEVE_ENDPOINT = '/Capture/Interactive/Retrieve/v1.00/json3.ws'.freeze
20
+
21
+ include Result::Mixin
22
+
23
+ # Creates an address gateway
24
+ #
25
+ # @param [Client] client The client responsible for the HTTP interactions
26
+ #
27
+ def initialize(client)
28
+ @client = client
29
+ @mapper = Mappers::GenericMapper.new
30
+ @error_mapper = Mappers::ErrorMapper.new
31
+ end
32
+
33
+ # Find addresses and places.
34
+ #
35
+ # @param [Hash] options The options to find an address or a list of addresses.
36
+ # @option options [String] :text The search text to find. Ideally a postcode or the start of the address.
37
+ # @option options [String] countries A comma separated list of ISO 2 or 3 character country codes to limit
38
+ # the search within.
39
+ # @option options [String] origin A starting location for the search. This can be the name or ISO 2 or 3
40
+ # character code of a country, WGS84 coordinates (comma separated) or IP address to search from.
41
+ # @option options [String] container A container for the search. This should only be another Id previously
42
+ # returned from this service when the Type of the result was not 'Address'.
43
+ # @option options [Integer] limit The maximum number of results to return.
44
+ # @option options [String] language The preferred language for results. This should be a 2 or 4 character
45
+ # language code e.g. (en, fr, en-gb, en-us etc).
46
+ #
47
+ # @example Retrieving an address in the UK
48
+ # address = address_gateway.find(countries: 'GB', text: 'Scrubs Lane')
49
+ #
50
+ # @return [Result] A result wrapping a list of addresses
51
+ #
52
+ def find(options)
53
+ response = client.get(FIND_ENDPOINT, options)
54
+
55
+ response.errors? && build_error_from(response.items.first) || build_addresses_from(response.items)
56
+ end
57
+
58
+ # Returns the full address details based on the id.
59
+ #
60
+ # @param [Hash] options The options to retrieve the address.
61
+ # @option options [String] :id The Id from a Find method to retrieve the details for.
62
+ # @option options [String] :field_1_format Format of a custom address field.
63
+ # @option options [String] :field_2_format Format of a custom address field.
64
+ # @option options [String] :field_3_format Format of a custom address field.
65
+ # @option options [String] :field_4_format Format of a custom address field.
66
+ # @option options [String] :field_5_format Format of a custom address field.
67
+ #
68
+ # @example Retrieving the details of an address
69
+ # detailed_address = gateway.retrieve(id: 'GB|RM|ENG|6RB-NW10')
70
+ #
71
+ # @return [Result] A result wrapping a detailed address
72
+ #
73
+ def retrieve(options)
74
+ response = client.get(RETRIEVE_ENDPOINT, options)
75
+
76
+ response.errors? && build_error_from(response.items.first) || build_detailed_address_from(response.items.first)
77
+ end
78
+
79
+ # Find addresses and places.
80
+ #
81
+ # @param [Hash] options The options to find an address or a list of addresses.
82
+ # @option options [String] :text The search text to find. Ideally a postcode or the start of the address.
83
+ # @option options [String] countries A comma separated list of ISO 2 or 3 character country codes to limit
84
+ # the search within.
85
+ # @option options [String] origin A starting location for the search. This can be the name or ISO 2 or 3
86
+ # character code of a country, WGS84 coordinates (comma separated) or IP address to search from.
87
+ # @option options [String] container A container for the search. This should only be another Id previously
88
+ # returned from this service when the Type of the result was not 'Address'.
89
+ # @option options [Integer] limit The maximum number of results to return.
90
+ # @option options [String] language The preferred language for results. This should be a 2 or 4 character
91
+ # language code e.g. (en, fr, en-gb, en-us etc).
92
+ #
93
+ # @example Retrieving addresses in the UK
94
+ # addresses = address_gateway.find!(countries: 'GB', text: 'Scrubs Lane')
95
+ #
96
+ # @raise [Error] If the result is not a success
97
+ #
98
+ # @return [Array<Address>] A list of addresses
99
+ #
100
+ def find!(options)
101
+ unwrap_result_or_raise { find(options) }
102
+ end
103
+
104
+ # Returns the full address details based on the id.
105
+ #
106
+ # @param [Hash] options The options to retrieve the address.
107
+ # @option options [String] :id The Id from a Find method to retrieve the details for.
108
+ # @option options [String] :field_1_format Format of a custom address field.
109
+ # @option options [String] :field_2_format Format of a custom address field.
110
+ # @option options [String] :field_3_format Format of a custom address field.
111
+ # @option options [String] :field_4_format Format of a custom address field.
112
+ # @option options [String] :field_5_format Format of a custom address field.
113
+ #
114
+ # @example Retrieving the details of an address
115
+ # detailed_address = gateway.retrieve!(id: 'GB|RM|ENG|6RB-NW10')
116
+ #
117
+ # @raise [Error] If the result is not a success
118
+ #
119
+ # @return [DetailedAddress] A detailed address
120
+ #
121
+ def retrieve!(options)
122
+ unwrap_result_or_raise { retrieve(options) }
123
+ end
124
+
125
+ private
126
+
127
+ # @api private
128
+ attr_reader :client, :mapper, :error_mapper
129
+
130
+ # @api private
131
+ def build_error_from(item)
132
+ error = error_mapper.map_one(item)
133
+ Failure(error)
134
+ end
135
+
136
+ # @api private
137
+ def build_addresses_from(items)
138
+ address = mapper.map(items, Address)
139
+ Success(address)
140
+ end
141
+
142
+ # @api private
143
+ def build_detailed_address_from(item)
144
+ detailed_address = mapper.map_one(item, DetailedAddress)
145
+ Success(detailed_address)
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,68 @@
1
+ module Loqate
2
+ module Email
3
+ # Result of a batch email address validation.
4
+ class BatchEmailValidation < Dry::Struct::Value
5
+ Status = Types::Strict::String.enum('Valid', 'Invalid', 'Unknown', 'Accept_All')
6
+
7
+ # Valid - The email address is valid
8
+ # Invalid - The email address is invalid and shouldn't be accepted
9
+ # Unknown - Unable to complete the verification process (normally due to SMTP timeout)
10
+ # Accept_All - The mail server is set to accept all verification requests so full verification isn't possible
11
+ #
12
+ # @return ['Valid', 'Invalid', 'Unknown', 'Accept_All']
13
+ #
14
+ attribute :status, Status
15
+
16
+ # The email address that verification was attempted on.
17
+ #
18
+ # @return [String]
19
+ #
20
+ attribute :email_address, Types::Strict::String
21
+
22
+ # The account portion of the email address provided.
23
+ #
24
+ # @return [String
25
+ #
26
+ attribute :account, Types::Strict::String
27
+
28
+ # The domain portion of the email address provided.
29
+ #
30
+ # @return [String]
31
+ #
32
+ attribute :domain, Types::Strict::String
33
+
34
+ # Whether the email address provided is a disposable mailbox (some companies create temporary mailboxes
35
+ # which shouldn't be used for marketing communications).
36
+ #
37
+ # @return [Boolean]
38
+ #
39
+ attribute :is_disposible, Types::Strict::Bool
40
+
41
+ # Whether the email address provided is a system mailbox (e.g. sales@, support@, accounts@ etc).
42
+ #
43
+ # @return [Boolean]
44
+ #
45
+ attribute :is_system_mailbox, Types::Strict::Bool
46
+
47
+ # Whether the email was fully validated (including the account portion).
48
+ def valid?
49
+ status == 'Valid'
50
+ end
51
+
52
+ # Whether the email is invalid and shouldn't be accepted.
53
+ def invalid?
54
+ status == 'Invalid'
55
+ end
56
+
57
+ # Whether the email wasn't verified (normally due to SMTP timeout)
58
+ def unknown?
59
+ status == 'Unknown'
60
+ end
61
+
62
+ # Whether the email could be verified
63
+ def unverified?
64
+ status == 'Accept_All'
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,83 @@
1
+ module Loqate
2
+ module Email
3
+ # Result of a email address validation.
4
+ class EmailValidation < Dry::Struct::Value
5
+ ResponseCode = Types::Strict::String.enum('Valid', 'Valid_CatchAll', 'Invalid', 'Timeout')
6
+
7
+ # Valid - The email address has been fully validated (including the account portion)
8
+ # Valid_CatchAll - The domain has been validated but the account could not be validated
9
+ # Invalid - The email address is invalid and shouldn't be accepted
10
+ # Timeout - The validation could not be completed within the timeout specified (try increasing the timeout value)
11
+ #
12
+ # @return ['Valid', 'Valid_CatchAll', 'Invalid', 'Timeout']
13
+ #
14
+ attribute :response_code, ResponseCode
15
+
16
+ # A textual description of the ResponseCode returned
17
+ #
18
+ # @return [String]
19
+ #
20
+ attribute :response_message, Types::Strict::String
21
+
22
+ # The email address that verification was attempted on.
23
+ #
24
+ # @return [String]
25
+ #
26
+ attribute :email_address, Types::Strict::String
27
+
28
+ # The account portion of the email address provided.
29
+ #
30
+ # @return [String
31
+ #
32
+ attribute :user_account, Types::Strict::String
33
+
34
+ # The domain portion of the email address provided.
35
+ #
36
+ # @return [String]
37
+ #
38
+ attribute :domain, Types::Strict::String
39
+
40
+ # Whether the email address provided is a disposable mailbox (some companies create temporary mailboxes
41
+ # which shouldn't be used for marketing communications).
42
+ #
43
+ # @return [Boolean]
44
+ #
45
+ attribute :is_disposable_or_temporary, Types::Strict::Bool
46
+
47
+ # True if we recognise the email address against known lists of complainers and/or the email address has been
48
+ # used to defraud.
49
+ #
50
+ # @return [Boolean]
51
+ #
52
+ attribute :is_complainer_or_fraud_risk, Types::Strict::Bool
53
+
54
+ # The duration (in seconds) that the email validation took (maximum timeout enforced at 15 seconds).
55
+ # We recommend a high timeout (at least 5 seconds) value as it will minimise the number of "Timeout"
56
+ # responses returned.
57
+ #
58
+ # @return [Float]
59
+ #
60
+ attribute :duration, Types::Strict::Float
61
+
62
+ # Whether the email was fully validated (including the account portion).
63
+ def valid?
64
+ response_code == 'Valid'
65
+ end
66
+
67
+ # Whether the domain has been validated but the account hasn't.
68
+ def valid_domain?
69
+ response_code == 'Valid' || response_code == 'Valid_CatchAll'
70
+ end
71
+
72
+ # Whether the email is invalid and shouldn't be accepted.
73
+ def invalid?
74
+ response_code == 'Invalid'
75
+ end
76
+
77
+ # Whether the validation could not be completed within the timeout specified.
78
+ def timeout?
79
+ response_code == 'Timeout'
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,124 @@
1
+ require 'loqate/client'
2
+ require 'loqate/result'
3
+ require 'loqate/email/email_validation'
4
+ require 'loqate/email/batch_email_validation'
5
+ require 'loqate/mappers/error_mapper'
6
+ require 'loqate/mappers/generic_mapper'
7
+
8
+ module Loqate
9
+ module Email
10
+ # Validates the existence of email addresses.
11
+ #
12
+ class Gateway
13
+ BATCH_VALIDATE_ENDPOINT = '/EmailValidation/Batch/Validate/v1.20/json3.ws'.freeze
14
+ VALIDATE_ENDPOINT = '/EmailValidation/Interactive/Validate/v2.00/json3.ws'.freeze
15
+
16
+ include Result::Mixin
17
+
18
+ # Creates an email gateway.
19
+ #
20
+ # @param [Client] client The client responsible for the HTTP interactions
21
+ #
22
+ def initialize(client)
23
+ @client = client
24
+ @mapper = Mappers::GenericMapper.new
25
+ @error_mapper = Mappers::ErrorMapper.new
26
+ end
27
+
28
+ # Verifies the existence of an email address.
29
+ #
30
+ # @param [Hash] options The options to validate an email address.
31
+ # @option options [String] :email The email address to verify.
32
+ # @option options [Integer] :timeout The time (in milliseconds) you want to give for the validation attempt to be
33
+ # executed within. Value must be between 1 and 15000 (values outside of these ranges will fallback to the
34
+ # default of 15000).
35
+ #
36
+ # @example
37
+ # email_validation = email_gateway.validate(email: 'spam@example.com')
38
+ #
39
+ # @return [Result] A result wrapping an email address validation
40
+ #
41
+ def validate(options)
42
+ response = client.get(VALIDATE_ENDPOINT, options)
43
+
44
+ response.errors? && build_error_from(response.items.first) || build_email_validation_from(response.items.first)
45
+ end
46
+
47
+ # Verifies the existence of an email address.
48
+ #
49
+ # @param [Hash] options The options to validate an email address.
50
+ # @option options [String] :email The email address to verify.
51
+ # @option options [Integer] :timeout The time (in milliseconds) you want to give for the validation attempt to be
52
+ # executed within. Value must be between 1 and 15000 (values outside of these ranges will fallback to the
53
+ # default of 15000).
54
+ #
55
+ # @example
56
+ # email_validation = email_gateway.validate!(email: 'spam@example.com')
57
+ #
58
+ # @raise [Error] If the result is not a success
59
+ #
60
+ # @return [EmailValidation> An email address validation
61
+ #
62
+ def validate!(options)
63
+ unwrap_result_or_raise { validate(options) }
64
+ end
65
+
66
+ # Verifies up to 100 emails per batch.
67
+ #
68
+ # @param [Hash] options The options to validate an email address.
69
+ # @option options [Array<String>] :emails The email addresses to verify. Maximum 100 records.
70
+ #
71
+ # @example
72
+ # result = email_gateway.batch_validate(emails: %w[spam@example.com example@example.com])
73
+ # result.value # => [#<Loqate::Email::BatchEmailValidation status="Invalid" ...]
74
+ #
75
+ # @return [Result] A result wrapping a list of email address validations
76
+ #
77
+ def batch_validate(options)
78
+ options[:emails] = options[:emails].join(',') if options[:emails]
79
+ response = client.get(BATCH_VALIDATE_ENDPOINT, options)
80
+
81
+ response.errors? && build_error_from(response.items.first) || build_email_validations_from(response.items)
82
+ end
83
+
84
+ # Verifies up to 100 emails per batch.
85
+ #
86
+ # @param [Hash] options The options to validate an email address.
87
+ # @option options [Array<String>] :emails The email addresses to verify. Maximum 100 records.
88
+ #
89
+ # @example
90
+ # email_validations = email_gateway.batch_validate!(emails: %w[spam@example.com example@example.com])
91
+ #
92
+ # @raise [Error] If the result is not a success
93
+ #
94
+ # @return [Array<BatchEmailValidation>] A list of email address validations
95
+ #
96
+ def batch_validate!(options)
97
+ unwrap_result_or_raise { batch_validate(options) }
98
+ end
99
+
100
+ private
101
+
102
+ # @api private
103
+ attr_reader :client, :mapper, :error_mapper
104
+
105
+ # @api private
106
+ def build_error_from(item)
107
+ error = error_mapper.map_one(item)
108
+ Failure(error)
109
+ end
110
+
111
+ # @api private
112
+ def build_email_validation_from(item)
113
+ email_validation = mapper.map_one(item, EmailValidation)
114
+ Success(email_validation)
115
+ end
116
+
117
+ # @api private
118
+ def build_email_validations_from(item)
119
+ email_validation = mapper.map(item, BatchEmailValidation)
120
+ Success(email_validation)
121
+ end
122
+ end
123
+ end
124
+ end
@@ -1,7 +1,7 @@
1
- require 'loqate/address_gateway'
1
+ require 'loqate/address/gateway'
2
2
  require 'loqate/bank/gateway'
3
- require 'loqate/email_gateway'
4
- require 'loqate/phone_gateway'
3
+ require 'loqate/email/gateway'
4
+ require 'loqate/phone/gateway'
5
5
 
6
6
  module Loqate
7
7
  # Acts as a single point of entry for a defined group of API's.
@@ -28,31 +28,31 @@ module Loqate
28
28
 
29
29
  # Gateway to the Address APIs.
30
30
  #
31
- # @return [AddressGateway] An instance of an address gateway.
31
+ # @return [Address::Gateway] An instance of an address gateway.
32
32
  #
33
33
  def address
34
- @address ||= AddressGateway.new(client)
34
+ @address ||= Address::Gateway.new(client)
35
35
  end
36
36
 
37
37
  # Gateway to the Phone number API.
38
38
  #
39
- # @return [PhoneGateway] An instance of a phone gateway.
39
+ # @return [Phone::Gateway] An instance of a phone gateway.
40
40
  #
41
41
  def phone
42
- @phone ||= PhoneGateway.new(client)
42
+ @phone ||= Phone::Gateway.new(client)
43
43
  end
44
44
 
45
45
  # Gateway to the Email verification APIs.
46
46
  #
47
- # @return [EmailGateway] An instance of an email gateway.
47
+ # @return [Email::Gateway] An instance of an email gateway.
48
48
  #
49
49
  def email
50
- @email ||= EmailGateway.new(client)
50
+ @email ||= Email::Gateway.new(client)
51
51
  end
52
52
 
53
53
  # Gateway to the Bank verification APIs.
54
54
  #
55
- # @return [BankGateway] An instance of a bank gateway.
55
+ # @return [Bank::Gateway] An instance of a bank gateway.
56
56
  #
57
57
  def bank
58
58
  @bank ||= Bank::Gateway.new(client)