hermes_api 0.2.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: decb2c7f0da4ef7dfa95e137bb613f325005f58441d8cb1f9d661ac1ad0a043f
4
- data.tar.gz: 3168e91a8a8e03076d00b299e91b52fd784bf8be90b031376e713d5cad093280
3
+ metadata.gz: cfeafd10d08ea6ffa236a36b66d94dc11f3b7883931aade9995a93488d9a17e9
4
+ data.tar.gz: 3d4fb22d7d6f794988fedbefc1d79c384b744a13085fb9b9e6073fed00bd7638
5
5
  SHA512:
6
- metadata.gz: '082600bc6adb445edd65488dac82b68a5d35f69676502e18f2cc26969156bfb4a1acc23e6b3bde7d61779a7019ebd113fce122ce9843f644201e4134480ae315'
7
- data.tar.gz: 6bfc6e4202d609471d541196bea1081876ebfd9ccdb3c94cba1f15f7b3e6ca5a2cb2ef95290ca98d8a09efa44ff9c06456ddbb3f9014f756b3314de775b67762
6
+ metadata.gz: 4fc203dac84c6484c990dcca4d2c070c083d8f0c588d465daa6c3de2eb0a02a0c2523376d9d30e9d37e2dc518c20b57b76c63c80070c5c45dc90404e6a5b46c8
7
+ data.tar.gz: 59160916b4fe767ead70309ef93f7c67c0392c577159ccde3f6d8fb8bded452194401db92781636cce250be07b614723461729d61fc9144fac4b153659051c45
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hermes_api (0.1.0)
4
+ hermes_api (0.3.1)
5
5
  activeresource (>= 4.1.0, < 6.0.0)
6
6
 
7
7
  GEM
@@ -32,6 +32,7 @@ GEM
32
32
  dotenv (2.7.6)
33
33
  ffi (1.15.3)
34
34
  formatador (0.3.0)
35
+ gem-release (2.2.2)
35
36
  guard (2.17.0)
36
37
  formatador (>= 0.2.4)
37
38
  listen (>= 2.7, < 4.0)
@@ -117,6 +118,7 @@ PLATFORMS
117
118
 
118
119
  DEPENDENCIES
119
120
  dotenv
121
+ gem-release
120
122
  guard-rspec
121
123
  hermes_api!
122
124
  pry
@@ -127,4 +129,4 @@ DEPENDENCIES
127
129
  standard
128
130
 
129
131
  BUNDLED WITH
130
- 2.2.15
132
+ 2.2.24
data/bin/console CHANGED
@@ -6,7 +6,6 @@ require "dotenv/load"
6
6
  require "dev/zeitwerk_loader"
7
7
  require "dev/config"
8
8
  require "hermes_api"
9
-
10
9
  # You can add fixtures and/or initialization code here to make experimenting
11
10
  # with your gem easier. You can also use a different console, if you like.
12
11
  set_config
data/hermes_api.gemspec CHANGED
@@ -3,15 +3,15 @@
3
3
  require_relative "lib/hermes_api/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "hermes_api"
7
- spec.version = HermesAPI::VERSION
8
- spec.authors = ["Andy Chong"]
9
- spec.email = ["andygg1996personal@gmail.com"]
10
-
11
- spec.summary = "Unofficial Ruby object based Hermes UK API wrapper."
12
- spec.description = "Unofficial Ruby object based Hermes UK API wrapper."
13
- spec.homepage = "https://github.com/PostCo/hermes_api"
14
- spec.license = "MIT"
6
+ spec.name = "hermes_api"
7
+ spec.version = HermesAPI::VERSION
8
+ spec.authors = ["Andy Chong"]
9
+ spec.email = ["andy@postco.co"]
10
+
11
+ spec.summary = "Unofficial Ruby object based Hermes UK API wrapper."
12
+ spec.description = "Unofficial Ruby object based Hermes UK API wrapper."
13
+ spec.homepage = "https://github.com/PostCo/hermes_api"
14
+ spec.license = "MIT"
15
15
  spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
16
16
 
17
17
  spec.metadata["allowed_push_host"] = "https://rubygems.org/"
@@ -25,11 +25,11 @@ Gem::Specification.new do |spec|
25
25
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
26
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
27
27
  end
28
- spec.bindir = "exe"
29
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
31
 
32
- spec.add_dependency "activeresource", ">= 4.1.0", "< 6.0.0"
32
+ spec.add_dependency "activeresource", ">= 4.1.0", "< 6.0.0"
33
33
 
34
34
  spec.add_development_dependency "rspec", "~> 3.2"
35
35
  spec.add_development_dependency "dotenv"
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency "pry"
38
38
  spec.add_development_dependency "guard-rspec"
39
39
  spec.add_development_dependency "standard"
40
+ spec.add_development_dependency "gem-release"
40
41
 
41
42
  # Uncomment to register a new dependency of your gem
42
43
  # spec.add_dependency "example-gem", "~> 1.0"
data/lib/dev/config.rb CHANGED
@@ -2,9 +2,12 @@ require "dotenv/load"
2
2
 
3
3
  def set_config
4
4
  HermesAPI.configure do |config|
5
- config.user = ENV["HERMES_API_USER"]
5
+ config.user = ENV["HERMES_API_USER"]
6
6
  config.password = ENV["HERMES_API_PASSWORD"]
7
7
  config.env = :test
8
8
  config.proxy = ENV["HERMES_API_PROXY"]
9
+ config.auth_id = ENV["HERMES_API_AUTH_ID"]
10
+ config.auth_secret = ENV["HERMES_API_AUTH_SECRET"]
11
+ config.api_key = ENV["HERMES_API_KEY"]
9
12
  end
10
- end
13
+ end
@@ -8,6 +8,7 @@ loader.inflector.inflect(
8
8
  loader.push_dir("./lib")
9
9
  loader.collapse("./lib/hermes_api/resources")
10
10
  loader.ignore("#{__dir__}/config.rb")
11
+ loader.ignore("./lib/hermes_api/cache.rb")
11
12
  loader.enable_reloading
12
13
  # loader.log!
13
14
  loader.setup
data/lib/hermes_api.rb CHANGED
@@ -4,10 +4,17 @@ require_relative "hermes_api/version"
4
4
  require "active_resource"
5
5
 
6
6
  module HermesAPI
7
+ require "hermes_api/cache"
7
8
  require "hermes_api/configuration"
8
9
  require "hermes_api/creation_error"
9
10
  require "hermes_api/connection"
10
11
 
11
12
  require "hermes_api/resources/base"
12
13
  require "hermes_api/resources/return_label"
14
+
15
+ require "hermes_api/resources/o_auth"
16
+ require "hermes_api/resources/json_base"
17
+ require "hermes_api/resources/print_in_store_qr_code"
18
+ require "hermes_api/resources/tracking_event"
19
+ require "hermes_api/resources/web_tracking"
13
20
  end
@@ -0,0 +1,23 @@
1
+ module HermesAPI
2
+ module BearerTokenSetup
3
+ def connection(refresh = false)
4
+ connection = super
5
+ connection.bearer_token = fetch_token
6
+ connection
7
+ end
8
+
9
+ def fetch_token
10
+ oauth_audience = prefix.match(/^\/?([^\/]*)/).captures.first
11
+ cached_token = HermesAPI.cache.read("#{oauth_audience}/oauth_token")
12
+ return cached_token if cached_token
13
+
14
+ response = OAuth.create(audience: oauth_audience)
15
+ HermesAPI.cache.write(
16
+ "#{oauth_audience}/oauth_token",
17
+ response.access_token,
18
+ expires_in: response.expires_in - 15 # clear cache earlier
19
+ )
20
+ response.access_token
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ module HermesAPI
2
+ mattr_accessor :cache
3
+
4
+ self.cache = if defined?(Rails) && Rails.respond_to?(:cache) &&
5
+ Rails.cache.is_a?(ActiveSupport::Cache::Store)
6
+ Rails.cache
7
+ else
8
+ ActiveSupport::Cache::MemoryStore.new
9
+ end
10
+ end
@@ -1,11 +1,19 @@
1
1
  module HermesAPI
2
2
  class Configuration
3
- attr_accessor :proxy, :env, :user, :password
3
+ attr_accessor :proxy, :env, :user, :password, :auth_id, :auth_secret, :api_key
4
4
  end
5
5
 
6
6
  PRODUCTION_SITE = "https://www.hermes-europe.co.uk"
7
7
  TESTING_SITE = "https://sit.hermes-europe.co.uk"
8
8
 
9
+ OAUTH_PRODUCTION_SITE = "https://hermes-client-integration-prod.eu.auth0.com"
10
+ OAUTH_TESTING_SITE = "https://hermes-client-integration-pre.eu.auth0.com"
11
+
12
+ JSON_PRODUCTION_SITE = "https://api.hermesworld.co.uk"
13
+ JSON_TESTING_SITE = "https://api.hermesworld.co.uk"
14
+ # temporarily disabled until it is fixed
15
+ # JSON_TESTING_SITE = "https://hermeslive-pre-prod.apigee.net"
16
+
9
17
  class << self
10
18
  def config
11
19
  @config ||= Configuration.new
@@ -16,6 +24,11 @@ module HermesAPI
16
24
  HermesAPI::Base.proxy = config.proxy
17
25
  HermesAPI::Base.user = config.user
18
26
  HermesAPI::Base.password = config.password
27
+
28
+ HermesAPI::JsonBase.site = config.env.to_s == "production" ? JSON_PRODUCTION_SITE : JSON_TESTING_SITE
29
+ HermesAPI::OAuth.site = config.env.to_s == "production" ? OAUTH_PRODUCTION_SITE : OAUTH_TESTING_SITE
30
+
31
+ HermesAPI::JsonBase.headers["apikey"] = config.api_key
19
32
  end
20
33
 
21
34
  def configure
@@ -0,0 +1,6 @@
1
+ module HermesAPI
2
+ class JsonBase < ActiveResource::Base
3
+ self.include_format_in_path = false
4
+ self.auth_type = :bearer
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ module HermesAPI
2
+ class OAuth < ActiveResource::Base
3
+ self.include_format_in_path = false
4
+ self.element_name=""
5
+ self.prefix="/oauth/token"
6
+
7
+ def initialize(attributes = {}, persisted = false)
8
+ attributes = {
9
+ grant_type: "client_credentials",
10
+ client_id: HermesAPI.config.auth_id,
11
+ client_secret: HermesAPI.config.auth_secret,
12
+ **attributes
13
+ }
14
+ super
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module HermesAPI
2
+ class PrintInStoreQrCode < JsonBase
3
+ extend BearerTokenSetup
4
+
5
+ self.element_name = ""
6
+ self.prefix = "/client-print-in-store-api/v1/references"
7
+
8
+ def load(attributes, remove_root = false, persisted = false)
9
+ # remove the outer array before parsing the response body
10
+ attributes = attributes[0] if attributes.is_a?(Array) && attributes.length == 1
11
+ super
12
+ end
13
+
14
+ def qr_code
15
+ base64_data = as_json.dig("qrCode", "base64EncodedBytes")
16
+ Base64.decode64(base64_data) if base64_data
17
+ end
18
+ end
19
+ end
@@ -23,8 +23,8 @@ module HermesAPI
23
23
  addressLine1: "",
24
24
  postCode: "",
25
25
  city: "",
26
- region: ""
27
- countryCode: "",
26
+ region: "",
27
+ countryCode: ""
28
28
  },
29
29
  mobilePhoneNo: "",
30
30
  email: "",
@@ -50,6 +50,8 @@ module HermesAPI
50
50
  rescue NameError
51
51
  end
52
52
 
53
+ alias_method :label, :labels
54
+
53
55
  def tracking_numbers
54
56
  entries = routingResponseEntries.routingResponseEntry
55
57
  if entries.is_a?(Array)
@@ -62,7 +64,76 @@ module HermesAPI
62
64
  rescue NameError
63
65
  end
64
66
 
65
- alias_method :label, :labels
66
67
  alias_method :tracking_number, :tracking_numbers
68
+
69
+ def request_print_in_store_qr_code(**attrs)
70
+ if ([:dimensions, :value, :deliveryAddress] - attrs.keys).length > 0
71
+ raise ArgumentError, request_print_in_store_qr_code_error_message
72
+ end
73
+
74
+ return nil if attributes["routingResponseEntries"].blank?
75
+
76
+ entries = routingResponseEntries.routingResponseEntry
77
+ entry = entries.is_a?(Array) ? entries[0] : entries
78
+ carrier = entry.inboundCarriers.carrier1
79
+ barcode = carrier.barcode1
80
+ customer = collectionRoutingRequestEntries[0].customer
81
+ address = customer.address
82
+
83
+ self.print_in_store_qr_code = PrintInStoreQrCode.create(
84
+ customer: {
85
+ customerReference1: customer.customerReference1
86
+ },
87
+ labelType: "RETURN",
88
+ barcode: {
89
+ barcode: barcode.barcodeNumber,
90
+ barcodeDisplay: barcode.barcodeDisplay
91
+ },
92
+ client: {
93
+ clientId: clientId,
94
+ clientName: clientName
95
+ },
96
+ routing: {
97
+ deliveryMethod: {
98
+ deliveryMethodId: carrier.deliveryMethodCode,
99
+ deliveryMethodDescription: carrier.deliveryMethodDesc
100
+ },
101
+ sortLevels: {
102
+ sortLevel1: carrier.sortLevel1.strip,
103
+ sortLevel2: carrier.sortLevel2
104
+ }
105
+ },
106
+ serviceOffers: [],
107
+ **attrs
108
+ )
109
+ end
110
+
111
+ private
112
+
113
+ def request_print_in_store_qr_code_error_message
114
+ <<~HEREDOC
115
+ Missing attributes
116
+ Example:
117
+ HermesAPI::ReturnLabel#request_print_in_store_qr_code(
118
+ dimensions: {
119
+ depth: 15,
120
+ length: 20,
121
+ width: 15,
122
+ weight: 1
123
+ },
124
+ value: {
125
+ currency: 'GBP',
126
+ amount: 10
127
+ },
128
+ deliveryAddress: {
129
+ name: 'Don Joe',
130
+ addressLine1: 'Real Logic',
131
+ addressLine2: '4-4 Ridings Park, Eastern Way',
132
+ countryCode: 'GB',
133
+ postcode: 'WS117FJ'
134
+ }
135
+ )
136
+ HEREDOC
137
+ end
67
138
  end
68
139
  end
@@ -0,0 +1,12 @@
1
+ module HermesAPI
2
+ class TrackingEvent < JsonBase
3
+ extend BearerTokenSetup
4
+
5
+ self.element_name = ""
6
+ self.prefix = "/client-tracking-api/v1/events"
7
+
8
+ def self.where(barcode:)
9
+ super(barcode: barcode, descriptionType: "CLIENT")
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ module HermesAPI
2
+ class WebTracking < ActiveResource::Base
3
+ self.element_name = ""
4
+ self.site = "https://api.hermesworld.co.uk"
5
+ self.prefix = "/enterprise-tracking-api/v1/parcels"
6
+ self.include_format_in_path = false
7
+ headers["apiKey"] = ENV["HERMES_WEB_TRACKING_API_KEY"]
8
+
9
+ MAPPING = {
10
+ "715" => "pending_drop_off",
11
+ "708" => "dropped_off",
12
+ "690" => "dropped_off",
13
+ "710" => "collected_by_courier",
14
+ "688" => "collected_by_courier",
15
+ "689" => "collected_by_courier",
16
+ "711" => "collected_by_courier"
17
+ }
18
+
19
+ def load(attributes, remove_root = false, persisted = false)
20
+ attributes = attributes.dig("results", 0)
21
+ super(attributes)
22
+ end
23
+
24
+ def self.find(barcode)
25
+ uniqueId = format.decode(connection.get("#{prefix}/search/#{barcode}", headers).body).first
26
+ find_single("", params: {uniqueIds: uniqueId})
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HermesAPI
4
- VERSION = "0.2.0"
4
+ VERSION = "0.4.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hermes_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Chong
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-06 00:00:00.000000000 Z
11
+ date: 2021-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeresource
@@ -114,9 +114,23 @@ dependencies:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: gem-release
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
117
131
  description: Unofficial Ruby object based Hermes UK API wrapper.
118
132
  email:
119
- - andygg1996personal@gmail.com
133
+ - andy@postco.co
120
134
  executables: []
121
135
  extensions: []
122
136
  extra_rdoc_files: []
@@ -137,11 +151,18 @@ files:
137
151
  - lib/dev/config.rb
138
152
  - lib/dev/zeitwerk_loader.rb
139
153
  - lib/hermes_api.rb
154
+ - lib/hermes_api/bearer_token_setup.rb
155
+ - lib/hermes_api/cache.rb
140
156
  - lib/hermes_api/configuration.rb
141
157
  - lib/hermes_api/connection.rb
142
158
  - lib/hermes_api/creation_error.rb
143
159
  - lib/hermes_api/resources/base.rb
160
+ - lib/hermes_api/resources/json_base.rb
161
+ - lib/hermes_api/resources/o_auth.rb
162
+ - lib/hermes_api/resources/print_in_store_qr_code.rb
144
163
  - lib/hermes_api/resources/return_label.rb
164
+ - lib/hermes_api/resources/tracking_event.rb
165
+ - lib/hermes_api/resources/web_tracking.rb
145
166
  - lib/hermes_api/version.rb
146
167
  homepage: https://github.com/PostCo/hermes_api
147
168
  licenses:
@@ -166,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
187
  - !ruby/object:Gem::Version
167
188
  version: '0'
168
189
  requirements: []
169
- rubygems_version: 3.1.6
190
+ rubygems_version: 3.2.22
170
191
  signing_key:
171
192
  specification_version: 4
172
193
  summary: Unofficial Ruby object based Hermes UK API wrapper.