Class: AfterShip

Inherits:
Object
  • Object
show all
Defined in:
lib/after_ship.rb,
lib/after_ship/version.rb,
lib/after_ship/tracking.rb,
lib/after_ship/checkpoint.rb

Overview

Init the client:

client = AfterShip.new(api_key: 'your-aftership-api-key')

Get a list of trackings www.aftership.com/docs/api/3.0/tracking/get-trackings

client.trackings

# Will return list of Tracking objects:

[
  #<AfterShip::Tracking ...>,
  #<AfterShip::Tracking ...>,
  ...
]

Get a tracking www.aftership.com/docs/api/3.0/tracking/get-trackings-slug-tracking_number

client.tracking('tracking-number', 'ups')

# Will return Tracking object or raise AfterShip::ResourceNotFoundError
# if not exists:

#<AfterShip::Tracking:0x007fe555bd9560
  @active=false,
  @courier="UPS",
  @created_at=#<DateTime: 2014-05-08T15:25:01+00:00 ...>,
  @updated_at=#<DateTime: 2014-07-18T09:00:47+00:00 ...>>
  @custom_fields={},
  @customer_name=nil,
  @destination_country_iso3="USA",
  @emails=[],
  @expected_delivery=nil,
  @order_id="PL-12480166",
  @order_id_path=nil,
  @origin_country_iso3="IND",
  @shipment_package_count=0,
  @shipment_type="EXPEDITED",
  @signed_by="FRONT DOOR",
  @slug="ups",
  @smses=[],
  @source="api",
  @status="Delivered",
  @tag="Delivered",
  @title="1ZA2207X6790326683",
  @tracked_count=47,
  @tracking_number="1ZA2207X6790326683",
  @unique_token="ly9ueXUJC",
  @checkpoints=[
    #<AfterShip::Checkpoint:0x007fe555bb0340
      @checkpoint_time=#<DateTime: 2014-05-12T14:07:00+00:00 ...>,
      @city="NEW YORK",
      @country_iso3=nil,
      @country_name="US",
      @courier="UPS",
      @created_at=#<DateTime: 2014-05-12T18:34:32+00:00 ...>,
      @message="DELIVERED",
      @slug="ups",
      @state="NY",
      @status="Delivered",
      @tag="Delivered",
      @zip="10075">
    #<AfterShip::Checkpoint ...>,
    ...
  ]>

Create a new tracking www.aftership.com/docs/api/3.0/tracking/post-trackings

client.create_tracking('tracking-number', 'ups', order_id: 'external-id')

# Will return Tracking object or raise AfterShip::InvalidArgumentError
# if it exists:

#<AfterShip::Tracking ...>

Update a tracking www.aftership.com/docs/api/3.0/tracking/put-trackings-slug-tracking_number

client.update_tracking('tracking-number', 'ups', order_id: 'external-id')

To debug:

AfterShip.debug = true

client.tracking(‘9405903699300211343566’, ‘usps’) # In transit client.tracking(‘1ZA2207X6794165804’, ‘ups’) # Delivered, wild client.tracking(‘1ZA2207X6791425225’, ‘ups’) # Delivered, ok client.tracking(‘1ZA2207X6790326683’, ‘ups’) # Delivered, ok

Defined Under Namespace

Classes: Checkpoint, Error, InvalidArgumentError, InvalidCredentialsError, InvalidJSONDataError, RequestFailedError, ResourceNotFoundError, ServerError, TooManyRequestsError, Tracking, UnknownError

Constant Summary collapse

DEFAULT_API_ADDRESS =
'https://api.aftership.com/v3'
TRACKINGS_ENDPOINT =
"#{ DEFAULT_API_ADDRESS }/trackings"
JSON_OPTIONS =
{
  symbolize_keys: true # Symbol keys to string keys
}
TAG_STATUS =

Tag to human-friendly status conversion

{
  'Pending'        => 'Pending',
  'InfoReceived'   => 'Info Received',
  'InTransit'      => 'In Transit',
  'OutForDelivery' => 'Out for Delivery',
  'AttemptFail'    => 'Attempt Failed',
  'Delivered'      => 'Delivered',
  'Exception'      => 'Exception',
  'Expired'        => 'Expired'
}
VERSION =
'0.0.2'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ AfterShip

Returns a new instance of AfterShip.

Parameters:

  • options (Hash)

    api_key [String]



143
144
145
146
147
148
149
# File 'lib/after_ship.rb', line 143

def initialize(options)
  require_arguments(
    api_key: options[:api_key]
  )

  @api_key = options.delete(:api_key)
end

Class Attribute Details

.debugBool

If debugging is turned on, it is passed to Typhoeus as “verbose” options, which is passed down to Ethon and displays request/response in STDERR.

Returns:

  • (Bool)


136
137
138
# File 'lib/after_ship.rb', line 136

def debug
  @debug
end

Instance Attribute Details

#api_keyObject (readonly)

Returns the value of attribute api_key.



139
140
141
# File 'lib/after_ship.rb', line 139

def api_key
  @api_key
end

Instance Method Details

#create_tracking(tracking_number, courier, options = {}) ⇒ Hash

Parameters:

  • tracking_number (String)
  • courier (String)
  • options (Hash) (defaults to: {})

Returns:

  • (Hash)


188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/after_ship.rb', line 188

def create_tracking(tracking_number, courier, options = {})
  require_arguments(tracking_number: tracking_number, courier: courier)

  params = {
    tracking: {
      tracking_number: tracking_number,
      slug:            courier
    }.merge(options)
  }

  response = request_response(TRACKINGS_ENDPOINT, params, :post)
  data     = response.fetch(:data).fetch(:tracking)

  Tracking.new(data)
end

#invalid_argument!(name) ⇒ Object (protected)

Parameters:

  • name (Symbol)


241
242
243
# File 'lib/after_ship.rb', line 241

def invalid_argument!(name)
  fail ArgumentError, "Argument #{ name } cannot be empty"
end

#parse_response(response) ⇒ Hash (protected)

Parse response body into a Hash.

Parameters:

  • response (Typhoeus::Response)

Returns:

  • (Hash)


320
321
322
# File 'lib/after_ship.rb', line 320

def parse_response(response)
  MultiJson.load(response.body, JSON_OPTIONS)
end

#request_response(url, body_hash, method = :get) ⇒ Hash (protected)

Prepare a ‘Typhoeus::Request`, send it over the net and deal with te response by either returning a Hash or raising an error.

Parameters:

  • url (String)
  • body_hash (Hash)
  • method (Symbol) (defaults to: :get)

Returns:

  • (Hash)


253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/after_ship.rb', line 253

def request_response(url, body_hash, method = :get)
  body_json = MultiJson.dump(body_hash)

  request = Typhoeus::Request.new(
    url,
    method:  method,
    verbose: self.class.debug,
    body:    body_json,
    headers: {
      'aftership-api-key' => @api_key,
      'Content-Type'      => 'application/json'
    }
  )

  if self.class.debug
    request.on_complete do |response|
      puts
      puts 'Request body:'
      puts request.options[:body]
      puts
      puts 'Response body:'
      puts response.body
      puts
    end
  end

  response = request.run
  response_to_json(response)
end

#require_arguments(hash) ⇒ Object

Raises an ArgumentError if any of the args is empty or nil.

Parameters:

  • hash (Hash)

    arguments needed in options



228
229
230
231
232
233
234
235
236
# File 'lib/after_ship.rb', line 228

def require_arguments(hash)
  hash.each do |name, value|
    if value.respond_to?(:empty?)
      invalid_argument!(name) if value.empty?
    else
      invalid_argument!(name)
    end
  end
end

#response_to_json(response) ⇒ Hash (protected)

Deal with API response, either return a Hash or raise an error.

rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength

Parameters:

  • response (Typhoeus::Response)

Returns:

  • (Hash)


290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/after_ship.rb', line 290

def response_to_json(response)
  json_response = parse_response(response)

  case json_response[:meta][:code]
  when 200, 201
    return json_response
  when 400
    fail InvalidJSONDataError, json_response[:meta][:error_message]
  when 401
    fail InvalidCredentialsError, json_response[:meta][:error_message]
  when 402
    fail RequestFailedError, json_response[:meta][:error_message]
  when 404
    fail ResourceNotFoundError, json_response[:meta][:error_message]
  when 409
    fail InvalidArgumentError, json_response[:meta][:error_message]
  when 429
    fail TooManyRequestsError, json_response[:meta][:error_message]
  when 500, 502, 503, 504
    fail ServerError, json_response[:meta][:error_message]
  else
    fail UnknownError, json_response[:meta][:error_message]
  end
end

#tracking(tracking_number, courier) ⇒ Hash

Get a single tracking. Raises an error if not found. www.aftership.com/docs/api/3.0/tracking/get-trackings-slug-tracking_number

Parameters:

  • tracking_number (String)
  • courier (String)

Returns:

  • (Hash)


169
170
171
172
173
174
175
176
177
178
# File 'lib/after_ship.rb', line 169

def tracking(tracking_number, courier)
  require_arguments(tracking_number: tracking_number, courier: courier)

  url = "#{ TRACKINGS_ENDPOINT }/#{ courier }/#{ tracking_number }"

  response = request_response(url, {}, :get)
  data     = response.fetch(:data).fetch(:tracking)

  Tracking.new(data)
end

#trackingsHash

Returns:

  • (Hash)


155
156
157
158
159
160
# File 'lib/after_ship.rb', line 155

def trackings
  response = request_response(TRACKINGS_ENDPOINT, {}, :get)
  data     = response.fetch(:data).fetch(:trackings)

  data.map { |datum| Tracking.new(datum) }
end

#update_tracking(tracking_number, courier, options = {}) ⇒ Hash

Parameters:

  • tracking_number (String)
  • courier (String)
  • options (Hash) (defaults to: {})

Returns:

  • (Hash)


211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/after_ship.rb', line 211

def update_tracking(tracking_number, courier, options = {})
  require_arguments(tracking_number: tracking_number, courier: courier)

  url = "#{ TRACKINGS_ENDPOINT }/#{ courier }/#{ tracking_number }"
  params = {
    tracking: options
  }

  response = request_response(url, params, :put)
  data     = response.fetch(:data).fetch(:tracking)

  Tracking.new(data)
end