lob 2.5.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/CHANGELOG.md +9 -0
  4. data/CONTRIBUTING.md +19 -0
  5. data/Gemfile +0 -2
  6. data/README.md +19 -36
  7. data/examples/README.md +14 -6
  8. data/examples/checks.rb +6 -7
  9. data/examples/csv_checks/create_checks.rb +47 -0
  10. data/examples/csv_checks/input.csv +6 -0
  11. data/examples/csv_letters/create_letters.rb +40 -0
  12. data/examples/csv_letters/input.csv +6 -0
  13. data/examples/csv_letters/letter_template.html +33 -0
  14. data/examples/csv_postcards/create_postcards.rb +2 -3
  15. data/examples/letters.rb +4 -5
  16. data/examples/postcards.rb +4 -5
  17. data/examples/verify/verify.rb +3 -4
  18. data/lib/lob.rb +1 -91
  19. data/lib/lob/client.rb +61 -0
  20. data/lib/lob/resources/address.rb +24 -0
  21. data/lib/lob/resources/area.rb +16 -0
  22. data/lib/lob/resources/bank_account.rb +24 -0
  23. data/lib/lob/resources/check.rb +14 -0
  24. data/lib/lob/resources/country.rb +16 -0
  25. data/lib/lob/resources/letter.rb +14 -0
  26. data/lib/lob/resources/postcard.rb +14 -0
  27. data/lib/lob/resources/resource_base.rb +108 -0
  28. data/lib/lob/resources/route.rb +24 -0
  29. data/lib/lob/resources/state.rb +16 -0
  30. data/lib/lob/version.rb +1 -1
  31. data/spec/lob/{v1 → resources}/address_spec.rb +15 -14
  32. data/spec/lob/{v1 → resources}/area_spec.rb +2 -2
  33. data/spec/lob/{v1 → resources}/bank_account_spec.rb +2 -2
  34. data/spec/lob/{v1 → resources}/check_spec.rb +3 -2
  35. data/spec/lob/{v1 → resources}/country_spec.rb +2 -2
  36. data/spec/lob/{v1 → resources}/letter_spec.rb +2 -2
  37. data/spec/lob/{v1 → resources}/postcard_spec.rb +2 -2
  38. data/spec/lob/resources/resource_base_spec.rb +53 -0
  39. data/spec/lob/{v1 → resources}/route_spec.rb +2 -2
  40. data/spec/lob/{v1 → resources}/state_spec.rb +2 -2
  41. data/spec/lob_spec.rb +12 -45
  42. data/spec/spec_helper.rb +2 -0
  43. metadata +86 -89
  44. data/examples/jobs.rb +0 -91
  45. data/lib/lob/v1/address.rb +0 -41
  46. data/lib/lob/v1/area.rb +0 -27
  47. data/lib/lob/v1/bank_account.rb +0 -37
  48. data/lib/lob/v1/check.rb +0 -33
  49. data/lib/lob/v1/country.rb +0 -21
  50. data/lib/lob/v1/job.rb +0 -39
  51. data/lib/lob/v1/letter.rb +0 -33
  52. data/lib/lob/v1/object.rb +0 -33
  53. data/lib/lob/v1/postcard.rb +0 -33
  54. data/lib/lob/v1/resource.rb +0 -69
  55. data/lib/lob/v1/route.rb +0 -27
  56. data/lib/lob/v1/setting.rb +0 -25
  57. data/lib/lob/v1/state.rb +0 -21
  58. data/spec/lob/v1/job_spec.rb +0 -161
  59. data/spec/lob/v1/object_spec.rb +0 -72
  60. data/spec/lob/v1/resource_spec.rb +0 -41
  61. data/spec/lob/v1/setting_spec.rb +0 -21
data/examples/letters.rb CHANGED
@@ -2,8 +2,7 @@ $:.unshift File.expand_path("../lib", File.dirname(__FILE__))
2
2
  require 'lob'
3
3
 
4
4
  # initialize Lob object
5
- Lob.api_key = 'test_799ff27291c166d10ba191902ad02fb059c'
6
- @lob = Lob.load
5
+ lob = Lob::Client.new(api_key: 'test_799ff27291c166d10ba191902ad02fb059c')
7
6
 
8
7
  html = %{
9
8
  <html>
@@ -42,7 +41,7 @@ html = %{
42
41
  }
43
42
 
44
43
  # create a to address
45
- to_address = @lob.addresses.create(
44
+ to_address = lob.addresses.create(
46
45
  name: "ToAddress",
47
46
  address_line1: "120 6th Ave",
48
47
  address_city: "Boston",
@@ -52,7 +51,7 @@ to_address = @lob.addresses.create(
52
51
  )
53
52
 
54
53
  # create a from address
55
- from_address = @lob.addresses.create(
54
+ from_address = lob.addresses.create(
56
55
  name: "FromAddress",
57
56
  address_line1: "120 6th Ave",
58
57
  address_city: "Boston",
@@ -62,7 +61,7 @@ from_address = @lob.addresses.create(
62
61
  )
63
62
 
64
63
  # send the letter
65
- puts @lob.letters.create(
64
+ puts lob.letters.create(
66
65
  description: "Test letter",
67
66
  to: to_address["id"],
68
67
  from: from_address["id"],
@@ -2,8 +2,7 @@ $:.unshift File.expand_path("../lib", File.dirname(__FILE__))
2
2
  require 'lob'
3
3
 
4
4
  # initialize Lob object
5
- Lob.api_key = 'test_799ff27291c166d10ba191902ad02fb059c'
6
- @lob = Lob.load
5
+ lob = Lob::Client.new(api_key: 'test_799ff27291c166d10ba191902ad02fb059c')
7
6
 
8
7
  # HTML to send to the server
9
8
  html = %{
@@ -56,7 +55,7 @@ html = %{
56
55
  }
57
56
 
58
57
  # create a to address
59
- to_address = @lob.addresses.create(
58
+ to_address = lob.addresses.create(
60
59
  name: "ToAddress",
61
60
  address_line1: "120 6th Ave",
62
61
  address_city: "Boston",
@@ -66,7 +65,7 @@ to_address = @lob.addresses.create(
66
65
  )
67
66
 
68
67
  # create a from address
69
- from_address = @lob.addresses.create(
68
+ from_address = lob.addresses.create(
70
69
  name: "FromAddress",
71
70
  address_line1: "120 6th Ave",
72
71
  address_city: "Boston",
@@ -76,7 +75,7 @@ from_address = @lob.addresses.create(
76
75
  )
77
76
 
78
77
  # send a postcard
79
- puts @lob.postcards.create(
78
+ puts lob.postcards.create(
80
79
  description: "Beach Postcard",
81
80
  to: to_address["id"],
82
81
  from: from_address["id"],
@@ -7,18 +7,17 @@ require 'lob'
7
7
  require 'street_address'
8
8
 
9
9
  # Initialize Lob object
10
- Lob.api_key = 'test_799ff27291c166d10ba191902ad02fb059c'
11
- @lob = Lob.load
10
+ lob = Lob::Client.new(api_key: 'test_799ff27291c166d10ba191902ad02fb059c')
12
11
 
13
12
  output = File.open(File.expand_path('../output.csv', __FILE__), 'w')
14
13
 
15
14
  output.puts ['address_line1', 'address_city', 'address_state', 'address_zip', 'address_country'].join(',')
16
15
 
17
- # Parse the CSV and create the postcards.
16
+ # Parse the input file and verify the addresses
18
17
  File.open(File.expand_path('../input.txt', __FILE__)).each_line do |line|
19
18
  parsed_address = StreetAddress::US.parse(line)
20
19
 
21
- verified_address = @lob.addresses.verify(
20
+ verified_address = lob.addresses.verify(
22
21
  address_line1: parsed_address.to_s(:line1),
23
22
  address_city: parsed_address.city,
24
23
  address_state: parsed_address.state,
data/lib/lob.rb CHANGED
@@ -1,97 +1,7 @@
1
- require "rest-client"
2
- require "json"
3
- require 'uri'
1
+ require "lob/client"
4
2
  require "lob/version"
5
3
  require "lob/errors/lob_error"
6
4
  require "lob/errors/invalid_request_error"
7
5
 
8
- # Dynamically require files
9
- Dir[File.join(File.dirname(__FILE__), 'lob', 'v*', '*.rb')].each {|file| require file }
10
-
11
6
  module Lob
12
- class << self
13
- attr_accessor :api_key, :api_version, :protocol, :api_host
14
-
15
- def configure
16
- yield self
17
- true
18
- end
19
- alias :config :configure
20
- end
21
-
22
- def self.submit(method, url, parameters={})
23
- clientVersion = Lob::VERSION
24
-
25
- begin
26
- if method == :get || method == :delete
27
- # Hack to URL encode nested objects like metadata.
28
- url = "#{url}?#{build_nested_query(parameters)}"
29
- response = RestClient.send(method, url, {
30
- user_agent: 'Lob/v1 RubyBindings/' + clientVersion,
31
- "Lob-Version" => self.api_version
32
- })
33
- else
34
- response = RestClient.send(method, url, parameters, {
35
- user_agent: 'Lob/v1 RubyBindings/' + clientVersion,
36
- "Lob-Version" => self.api_version
37
- })
38
- end
39
-
40
- body = JSON.parse(response)
41
-
42
- body.define_singleton_method(:_response) do
43
- response
44
- end
45
-
46
- return body
47
-
48
- rescue RestClient::ExceptionWithResponse => e
49
- handle_api_error(e)
50
- end
51
- end
52
-
53
- def self.load(options={})
54
- Lob(options)
55
- end
56
-
57
- def self.handle_api_error(error)
58
- begin
59
- response = JSON.parse(error.http_body.to_s)
60
- message = response.fetch("error").fetch("message")
61
- raise InvalidRequestError.new(message, error.http_code, error.http_body, error.response)
62
- rescue JSON::ParserError, KeyError
63
- # :nocov:
64
- raise LobError.new("Invalid response object:", error.http_code, error.http_body)
65
- # :nocov:
66
- end
67
- end
68
-
69
- def self.build_nested_query(value, prefix = nil)
70
- case value
71
- when Array
72
- value.map { |v|
73
- build_nested_query(v, "#{prefix}[]")
74
- }.join("&")
75
- when Hash
76
- value.map { |k, v|
77
- build_nested_query(v, prefix ? "#{prefix}[#{URI.encode_www_form_component(k)}]" : URI.encode_www_form_component(k))
78
- }.reject(&:empty?).join('&')
79
- else
80
- raise ArgumentError, "value must be an Array or Hash" if prefix.nil?
81
- "#{prefix}=#{URI.encode_www_form_component(value)}"
82
- end
83
- end
84
- end
85
-
86
- def Lob(options={})
87
- options[:api_host] ||= Lob.api_host || "api.lob.com"
88
- options[:protocol] ||= Lob.protocol || "https"
89
- options[:api_version] ||= Lob.api_version
90
- options[:api_key] ||= Lob.api_key
91
-
92
- if options[:api_key].nil?
93
- raise ArgumentError.new(":api_key is a required argument to initialize Lob")
94
- end
95
-
96
- Lob::V1::Resource.new(options)
97
7
  end
data/lib/lob/client.rb ADDED
@@ -0,0 +1,61 @@
1
+ require "lob/resources/address"
2
+ require "lob/resources/area"
3
+ require "lob/resources/bank_account"
4
+ require "lob/resources/check"
5
+ require "lob/resources/country"
6
+ require "lob/resources/letter"
7
+ require "lob/resources/postcard"
8
+ require "lob/resources/route"
9
+ require "lob/resources/state"
10
+
11
+ module Lob
12
+ class Client
13
+
14
+ attr_reader :config
15
+
16
+ def initialize(config = nil)
17
+ if config.nil? || config[:api_key].nil?
18
+ raise ArgumentError.new(":api_key is a required argument to initialize Lob")
19
+ end
20
+
21
+ @config = config
22
+ end
23
+
24
+ def areas
25
+ Lob::Resources::Area.new(config)
26
+ end
27
+
28
+ def addresses
29
+ Lob::Resources::Address.new(config)
30
+ end
31
+
32
+ def bank_accounts
33
+ Lob::Resources::BankAccount.new(config)
34
+ end
35
+
36
+ def checks
37
+ Lob::Resources::Check.new(config)
38
+ end
39
+
40
+ def countries
41
+ Lob::Resources::Country.new(config)
42
+ end
43
+
44
+ def letters
45
+ Lob::Resources::Letter.new(config)
46
+ end
47
+
48
+ def postcards
49
+ Lob::Resources::Postcard.new(config)
50
+ end
51
+
52
+ def routes
53
+ Lob::Resources::Route.new(config)
54
+ end
55
+
56
+ def states
57
+ Lob::Resources::State.new(config)
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,24 @@
1
+ require "lob/resources/resource_base"
2
+
3
+ module Lob
4
+ module Resources
5
+ class Address < Lob::Resources::ResourceBase
6
+
7
+ def initialize(config)
8
+ super(config)
9
+ @endpoint = "addresses"
10
+ end
11
+
12
+ def verify(options={})
13
+ submit :post, address_verify_url, options
14
+ end
15
+
16
+ private
17
+
18
+ def address_verify_url
19
+ "#{base_url}/verify"
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ require "lob/resources/resource_base"
2
+
3
+ module Lob
4
+ module Resources
5
+ class Area < Lob::Resources::ResourceBase
6
+
7
+ undef_method :destroy
8
+
9
+ def initialize(config)
10
+ super(config)
11
+ @endpoint = "areas"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ require "lob/resources/resource_base"
2
+
3
+ module Lob
4
+ module Resources
5
+ class BankAccount < Lob::Resources::ResourceBase
6
+
7
+ def initialize(config)
8
+ super(config)
9
+ @endpoint = "bank_accounts"
10
+ end
11
+
12
+ def verify(bank_account_id, options = {})
13
+ submit :post, verify_url(bank_account_id), options
14
+ end
15
+
16
+ private
17
+
18
+ def verify_url(bank_account_id)
19
+ "#{resource_url(bank_account_id)}/verify"
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require "lob/resources/resource_base"
2
+
3
+ module Lob
4
+ module Resources
5
+ class Check < Lob::Resources::ResourceBase
6
+
7
+ def initialize(config)
8
+ super(config)
9
+ @endpoint = "checks"
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ require "lob/resources/resource_base"
2
+
3
+ module Lob
4
+ module Resources
5
+ class Country < Lob::Resources::ResourceBase
6
+
7
+ undef_method :find, :create, :destroy
8
+
9
+ def initialize(config)
10
+ super(config)
11
+ @endpoint = "countries"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ require "lob/resources/resource_base"
2
+
3
+ module Lob
4
+ module Resources
5
+ class Letter < Lob::Resources::ResourceBase
6
+
7
+ def initialize(config)
8
+ super(config)
9
+ @endpoint = "letters"
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require "lob/resources/resource_base"
2
+
3
+ module Lob
4
+ module Resources
5
+ class Postcard < Lob::Resources::ResourceBase
6
+
7
+ def initialize(config)
8
+ super(config)
9
+ @endpoint = "postcards"
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,108 @@
1
+ require "rest-client"
2
+ require "json"
3
+ require "uri"
4
+
5
+ module Lob
6
+ module Resources
7
+ class ResourceBase
8
+
9
+ attr_reader :config, :endpoint
10
+
11
+ def initialize(config)
12
+ @config = config
13
+ end
14
+
15
+ def list(options={})
16
+ submit :get, endpoint_url, options
17
+ end
18
+
19
+ def find(resource_id)
20
+ submit :get, resource_url(resource_id)
21
+ end
22
+
23
+ def create(options = {})
24
+ submit :post, endpoint_url, options
25
+ end
26
+
27
+ def destroy(resource_id)
28
+ submit :delete, resource_url(resource_id)
29
+ end
30
+
31
+ private
32
+
33
+ def submit(method, url, parameters={})
34
+ clientVersion = Lob::VERSION
35
+
36
+ begin
37
+ if method == :get || method == :delete
38
+ # Hack to URL encode nested objects like metadata.
39
+ url = "#{url}?#{build_nested_query(parameters)}"
40
+ response = RestClient.send(method, url, {
41
+ user_agent: 'Lob/v1 RubyBindings/' + clientVersion,
42
+ "Lob-Version" => config[:api_version]
43
+ })
44
+ else
45
+ response = RestClient.send(method, url, parameters, {
46
+ user_agent: 'Lob/v1 RubyBindings/' + clientVersion,
47
+ "Lob-Version" => config[:api_version]
48
+ })
49
+ end
50
+
51
+ body = JSON.parse(response)
52
+
53
+ body.define_singleton_method(:_response) do
54
+ response
55
+ end
56
+
57
+ return body
58
+
59
+ rescue RestClient::ExceptionWithResponse => e
60
+ handle_api_error(e)
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def handle_api_error(error)
67
+ begin
68
+ response = JSON.parse(error.http_body.to_s)
69
+ message = response.fetch("error").fetch("message")
70
+ raise InvalidRequestError.new(message, error.http_code, error.http_body, error.response)
71
+ rescue JSON::ParserError, KeyError
72
+ # :nocov:
73
+ raise LobError.new("Invalid response object:", error.http_code, error.http_body)
74
+ # :nocov:
75
+ end
76
+ end
77
+
78
+ def build_nested_query(value, prefix = nil)
79
+ case value
80
+ when Array
81
+ value.map { |v|
82
+ build_nested_query(v, "#{prefix}[]")
83
+ }.join("&")
84
+ when Hash
85
+ value.map { |k, v|
86
+ build_nested_query(v, prefix ? "#{prefix}[#{URI.encode_www_form_component(k)}]" : URI.encode_www_form_component(k))
87
+ }.reject(&:empty?).join('&')
88
+ else
89
+ raise ArgumentError, "value must be an Array or Hash" if prefix.nil?
90
+ "#{prefix}=#{URI.encode_www_form_component(value)}"
91
+ end
92
+ end
93
+
94
+ def base_url
95
+ "https://#{config[:api_key]}:@api.lob.com/v1"
96
+ end
97
+
98
+ def endpoint_url
99
+ "#{base_url}/#{endpoint}"
100
+ end
101
+
102
+ def resource_url(resource_id)
103
+ "#{endpoint_url}/#{resource_id}"
104
+ end
105
+
106
+ end
107
+ end
108
+ end