hermes_api 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b1313c32c78bfdd9fb7a8256298157ca5a13f8a92a5074edeb1671969cb5f43
4
- data.tar.gz: 14a9dbfd88d46e2c0dce1e49baf0fd8d992332ac5051a60e24b7dc9af083c9a4
3
+ metadata.gz: b071e3f67cee6a1475d31ef398886a256a6caa74af59f57a4cd94b35982298e0
4
+ data.tar.gz: 0501c14dc98e8de9e9c1d3bdb703e19f69d41f55a048249ade0ab1cb102793ed
5
5
  SHA512:
6
- metadata.gz: 8bab7f7db1681634318f832ce9e2aacd1d059025f2745dfddc6a115581dfaad5de7baa552ceb23116e31fa3dae7cbdc16f9200ddad8ad61b7a828156a3fd925b
7
- data.tar.gz: 31f1ea2846b709e074a7a280b8ee7fa84820db2622370c2b011fe53d69d1bcd3ff536b921a8aaa20bfe2a6aad66d3098d1f81bea283866b74e9d5eb555e3cdff
6
+ metadata.gz: 7dd454207d4bcb9eea759890d4243b9486fbf704c29117614e51d1654621bbcde2c458916a0e89e6b1bd884cc65d40f41d113dcbe460c0f654b7a445e114a1bc
7
+ data.tar.gz: c6f727e2435134d77e00b856c61bd08467c374dd6cb95a58b9c517871fe325d50f2e468aad228a5f09b78958e507cff404216a32c206670763c18215138548b5
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hermes_api (0.2.1)
4
+ hermes_api (0.4.1)
5
5
  activeresource (>= 4.1.0, < 6.0.0)
6
6
 
7
7
  GEM
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
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = "hermes_api"
7
7
  spec.version = HermesAPI::VERSION
8
8
  spec.authors = ["Andy Chong"]
9
- spec.email = ["andygg1996personal@gmail.com"]
9
+ spec.email = ["andy@postco.co"]
10
10
 
11
11
  spec.summary = "Unofficial Ruby object based Hermes UK API wrapper."
12
12
  spec.description = "Unofficial Ruby object based Hermes UK API wrapper."
data/lib/dev/config.rb CHANGED
@@ -2,12 +2,7 @@ require "dotenv/load"
2
2
 
3
3
  def set_config
4
4
  HermesAPI.configure do |config|
5
- config.user = ENV["HERMES_API_USER"]
6
- config.password = ENV["HERMES_API_PASSWORD"]
7
5
  config.env = :test
8
6
  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"]
12
7
  end
13
8
  end
@@ -0,0 +1,38 @@
1
+ module HermesAPI
2
+ module BearerAuth
3
+ def with_oauth_session(api_key, client_id, client_secret)
4
+ headers["apikey"] = api_key
5
+ connection.bearer_token = fetch_token(client_id, client_secret)
6
+ response = yield
7
+ connection.bearer_token = nil
8
+ headers["apikey"] = nil
9
+ response
10
+ rescue ActiveResource::UnauthorizedAccess => e
11
+ clear_token_cache(client_id, client_secret)
12
+ raise e
13
+ end
14
+
15
+ def oauth_audience
16
+ prefix.match(/^\/?([^\/]*)/).captures.first
17
+ end
18
+
19
+ def clear_token_cache(client_id, client_secret)
20
+ cache_key = "HermesAPI/#{client_id}/#{client_secret}/#{oauth_audience}/oauth_token"
21
+ HermesAPI.cache.delete(cache_key)
22
+ end
23
+
24
+ def fetch_token(client_id, client_secret)
25
+ cache_key = "HermesAPI/#{client_id}/#{client_secret}/#{oauth_audience}/oauth_token"
26
+ cached_token = HermesAPI.cache.read(cache_key)
27
+ return cached_token if cached_token
28
+
29
+ response = OAuth.create(audience: oauth_audience, client_id: client_id, client_secret: client_secret)
30
+ HermesAPI.cache.write(
31
+ cache_key,
32
+ response.access_token,
33
+ expires_in: response.expires_in - 15 # clear cache earlier
34
+ )
35
+ response.access_token
36
+ end
37
+ end
38
+ end
@@ -1,6 +1,6 @@
1
1
  module HermesAPI
2
2
  class Configuration
3
- attr_accessor :proxy, :env, :user, :password, :auth_id, :auth_secret, :api_key
3
+ attr_accessor :proxy, :env
4
4
  end
5
5
 
6
6
  PRODUCTION_SITE = "https://www.hermes-europe.co.uk"
@@ -10,9 +10,9 @@ module HermesAPI
10
10
  OAUTH_TESTING_SITE = "https://hermes-client-integration-pre.eu.auth0.com"
11
11
 
12
12
  JSON_PRODUCTION_SITE = "https://api.hermesworld.co.uk"
13
- JSON_TESTING_SITE = "https://api.hermesworld.co.uk"
14
13
  # temporarily disabled until it is fixed
15
14
  # JSON_TESTING_SITE = "https://hermeslive-pre-prod.apigee.net"
15
+ JSON_TESTING_SITE = JSON_PRODUCTION_SITE
16
16
 
17
17
  class << self
18
18
  def config
@@ -22,13 +22,9 @@ module HermesAPI
22
22
  def after_configure
23
23
  HermesAPI::Base.site = config.env.to_s == "production" ? PRODUCTION_SITE : TESTING_SITE
24
24
  HermesAPI::Base.proxy = config.proxy
25
- HermesAPI::Base.user = config.user
26
- HermesAPI::Base.password = config.password
27
25
 
28
26
  HermesAPI::JsonBase.site = config.env.to_s == "production" ? JSON_PRODUCTION_SITE : JSON_TESTING_SITE
29
27
  HermesAPI::OAuth.site = config.env.to_s == "production" ? OAUTH_PRODUCTION_SITE : OAUTH_TESTING_SITE
30
-
31
- HermesAPI::JsonBase.headers["apikey"] = config.api_key
32
28
  end
33
29
 
34
30
  def configure
@@ -3,24 +3,8 @@ module HermesAPI
3
3
  self.include_format_in_path = false
4
4
  self.auth_type = :bearer
5
5
 
6
- OAUTH_AUDIENCE = nil
7
-
8
- def save
9
- token = HermesAPI.cache.read("#{self.class.name}/oauth_token") || fetch_token
10
- connection.bearer_token = token
11
- super
12
- end
13
-
14
- private
15
-
16
- def fetch_token
17
- response = OAuth.create(audience: self.class::OAUTH_AUDIENCE)
18
- HermesAPI.cache.write(
19
- "#{self.class.name}/oauth_token",
20
- response.access_token,
21
- expires_in: response.expires_in - 15 # clear cache earlier
22
- )
23
- response.access_token
6
+ def self.inherited(subclass)
7
+ subclass.extend(BearerAuth)
24
8
  end
25
9
  end
26
10
  end
@@ -1,17 +1,15 @@
1
1
  module HermesAPI
2
2
  class OAuth < ActiveResource::Base
3
3
  self.include_format_in_path = false
4
- self.element_name=""
5
- self.prefix="/oauth/token"
4
+ self.element_name = ""
5
+ self.prefix = "/oauth/token"
6
6
 
7
7
  def initialize(attributes = {}, persisted = false)
8
8
  attributes = {
9
9
  grant_type: "client_credentials",
10
- client_id: HermesAPI.config.auth_id,
11
- client_secret: HermesAPI.config.auth_secret,
12
10
  **attributes
13
11
  }
14
12
  super
15
13
  end
16
14
  end
17
- end
15
+ end
@@ -1,14 +1,17 @@
1
1
  module HermesAPI
2
- class PrintInStoreQr < JsonBase
2
+ class PrintInStoreQrCode < JsonBase
3
3
  self.element_name = ""
4
4
  self.prefix = "/client-print-in-store-api/v1/references"
5
5
 
6
- OAUTH_AUDIENCE = "client-print-in-store-api"
7
-
8
6
  def load(attributes, remove_root = false, persisted = false)
9
7
  # remove the outer array before parsing the response body
10
8
  attributes = attributes[0] if attributes.is_a?(Array) && attributes.length == 1
11
9
  super
12
10
  end
11
+
12
+ def qr_code
13
+ base64_data = as_json.dig("qrCode", "base64EncodedBytes")
14
+ Base64.decode64(base64_data) if base64_data
15
+ end
13
16
  end
14
17
  end
@@ -1,9 +1,56 @@
1
- "
2
- Create return label(s).
3
- You can choose to create a batch of return labels by passing in multiple collectionRoutingRequestEntry.
4
- "
5
1
  module HermesAPI
6
2
  class ReturnLabel < Base
3
+ # Create return label(s).
4
+ # You can choose to create a batch of return labels by passing in multiple collectionRoutingRequestEntry.
5
+ # Example:
6
+ # HermesAPI::Base.with_session("username", "password") do
7
+ # request_body = {clientId: "1234",
8
+ # clientName: "Life",
9
+ # childClientId: "",
10
+ # childClientName: "",
11
+ # sourceOfRequest: "CLIENTWS",
12
+ # collectionRoutingRequestEntries: [{ #collectionRoutingRequestEntry
13
+ # customer: {
14
+ # address: {
15
+ # firstName: "Leonie", lastName: "E", houseName: "2", streetName: "Street",
16
+ # addressLine1: "2 Street", addressLine2: "Fulham", postCode: "SW6 6EL",
17
+ # city: "London", region: "", countryCode: "GB"
18
+ # },
19
+ # mobilePhoneNo: "+447884571522",
20
+ # email: "leonie@london.com",
21
+ # customerReference1: "8284"
22
+ # },
23
+ # countryOfOrigin: "GB"
24
+ # }]}
25
+ # @order = HermesAPI::ReturnLabel.new(request_body)
26
+ # @order.save
27
+ #
28
+ # # Request for a single print in store QR code by wrapping in an oauth session block, only work with 1 label.
29
+ # # To request a batch of QR codes, use the HermesAPI::PrintInStoreQrCode#create directly.
30
+ #
31
+ # HermesAPI::PrintInStoreQrCode.with_oauth_session("api_key", "client_id/auth_id", "client_secret/auth_secret") do
32
+ # @order.request_print_in_store_qr_code(
33
+ # deliveryAddress: {
34
+ # name: "Andy",
35
+ # addressLine1: "7 Street",
36
+ # addressLine2: "Fulham",
37
+ # countryCode: "GB",
38
+ # postcode: "SW6 6EL"
39
+ # },
40
+ # dimensions: {
41
+ # depth: 15,
42
+ # length: 20,
43
+ # width: 15,
44
+ # weight: 1
45
+ # },
46
+ # value: {
47
+ # currency: "GBP",
48
+ # amount: 10
49
+ # }
50
+ # )
51
+ # end
52
+ # end
53
+ #
7
54
  self.prefix = "/routing/service/rest/v4/createReturnBarcodeAndLabel"
8
55
  self.element_name = ""
9
56
 
@@ -66,18 +113,11 @@ module HermesAPI
66
113
 
67
114
  alias_method :tracking_number, :tracking_numbers
68
115
 
69
- def request_print_in_store_qr_code(attrs = {
70
- dimensions: {
71
- depth: 15,
72
- length: 20,
73
- width: 15,
74
- weight: 1
75
- },
76
- value: {
77
- currency: "GBP",
78
- amount: 10
79
- }
80
- })
116
+ def request_print_in_store_qr_code(**attrs)
117
+ if ([:dimensions, :value, :deliveryAddress] - attrs.keys).length > 0
118
+ raise ArgumentError, request_print_in_store_qr_code_error_message
119
+ end
120
+
81
121
  return nil if attributes["routingResponseEntries"].blank?
82
122
 
83
123
  entries = routingResponseEntries.routingResponseEntry
@@ -86,17 +126,10 @@ module HermesAPI
86
126
  barcode = carrier.barcode1
87
127
  customer = collectionRoutingRequestEntries[0].customer
88
128
  address = customer.address
89
-
90
- self.print_in_store_qr_code = PrintInStoreQr.create(
129
+ self.print_in_store_qr_code = PrintInStoreQrCode.create(
91
130
  customer: {
92
131
  customerReference1: customer.customerReference1
93
132
  },
94
- deliveryAddress: {
95
- name: "#{address.firstName} #{address.lastName}",
96
- addressLine1: address.addressLine1,
97
- countryCode: address.countryCode,
98
- postcode: address.postCode
99
- },
100
133
  labelType: "RETURN",
101
134
  barcode: {
102
135
  barcode: barcode.barcodeNumber,
@@ -121,8 +154,32 @@ module HermesAPI
121
154
  )
122
155
  end
123
156
 
124
- def base64_print_in_store_qr_code
125
- as_json.dig("print_in_store_qr_code", "qrCode", "base64EncodedBytes")
157
+ private
158
+
159
+ def request_print_in_store_qr_code_error_message
160
+ <<~HEREDOC
161
+ Missing attributes
162
+ Example:
163
+ HermesAPI::ReturnLabel#request_print_in_store_qr_code(
164
+ dimensions: {
165
+ depth: 15,
166
+ length: 20,
167
+ width: 15,
168
+ weight: 1
169
+ },
170
+ value: {
171
+ currency: 'GBP',
172
+ amount: 10
173
+ },
174
+ deliveryAddress: {
175
+ name: 'Don Joe',
176
+ addressLine1: 'Real Logic',
177
+ addressLine2: '4-4 Ridings Park, Eastern Way',
178
+ countryCode: 'GB',
179
+ postcode: 'WS117FJ'
180
+ }
181
+ )
182
+ HEREDOC
126
183
  end
127
184
  end
128
185
  end
@@ -0,0 +1,16 @@
1
+ module HermesAPI
2
+ class TrackingEvent < JsonBase
3
+ # # Retrieve TrackingEvents by wrapping in an oauth session block
4
+ #
5
+ # HermesAPI::TrackingEvent.with_oauth_session("api_key", "client_id/auth_id", "client_secret/auth_secret") do
6
+ # HermesAPI::TrackingEvent.where(barcode: "123456789")
7
+ # end
8
+
9
+ self.element_name = ""
10
+ self.prefix = "/client-tracking-api/v1/events"
11
+
12
+ def self.where(barcode:)
13
+ super(barcode: barcode, descriptionType: "CLIENT")
14
+ end
15
+ end
16
+ 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.3.0"
4
+ VERSION = "0.5.0"
5
5
  end
data/lib/hermes_api.rb CHANGED
@@ -5,15 +5,17 @@ require "active_resource"
5
5
 
6
6
  module HermesAPI
7
7
  require "hermes_api/cache"
8
+ require "hermes_api/bearer_auth"
8
9
  require "hermes_api/configuration"
9
10
  require "hermes_api/creation_error"
10
11
  require "hermes_api/connection"
11
12
 
12
13
  require "hermes_api/resources/base"
13
14
  require "hermes_api/resources/return_label"
14
-
15
+
15
16
  require "hermes_api/resources/o_auth"
16
17
  require "hermes_api/resources/json_base"
17
- require "hermes_api/resources/print_in_store_qr"
18
-
18
+ require "hermes_api/resources/print_in_store_qr_code"
19
+ require "hermes_api/resources/tracking_event"
20
+ require "hermes_api/resources/web_tracking"
19
21
  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.3.0
4
+ version: 0.5.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-08-03 00:00:00.000000000 Z
11
+ date: 2021-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeresource
@@ -130,7 +130,7 @@ dependencies:
130
130
  version: '0'
131
131
  description: Unofficial Ruby object based Hermes UK API wrapper.
132
132
  email:
133
- - andygg1996personal@gmail.com
133
+ - andy@postco.co
134
134
  executables: []
135
135
  extensions: []
136
136
  extra_rdoc_files: []
@@ -151,6 +151,7 @@ files:
151
151
  - lib/dev/config.rb
152
152
  - lib/dev/zeitwerk_loader.rb
153
153
  - lib/hermes_api.rb
154
+ - lib/hermes_api/bearer_auth.rb
154
155
  - lib/hermes_api/cache.rb
155
156
  - lib/hermes_api/configuration.rb
156
157
  - lib/hermes_api/connection.rb
@@ -158,8 +159,10 @@ files:
158
159
  - lib/hermes_api/resources/base.rb
159
160
  - lib/hermes_api/resources/json_base.rb
160
161
  - lib/hermes_api/resources/o_auth.rb
161
- - lib/hermes_api/resources/print_in_store_qr.rb
162
+ - lib/hermes_api/resources/print_in_store_qr_code.rb
162
163
  - lib/hermes_api/resources/return_label.rb
164
+ - lib/hermes_api/resources/tracking_event.rb
165
+ - lib/hermes_api/resources/web_tracking.rb
163
166
  - lib/hermes_api/version.rb
164
167
  homepage: https://github.com/PostCo/hermes_api
165
168
  licenses: