This library interfaces with the web services of various shipping carriers. The goal is to abstract the features that are most frequently used into a pleasant and consistent Ruby API.
FreightKit supports:
- Downloading scanned documents
- Finding shipping rates
- Tracking shipments
On a technical level it supports:
- Abstracted accessorials
- Abstracted tracking events
- Cubic feet and density calculations
- Freight class calculations (and manual overriding)
Carrier: Has unique web services pertaining to whatever real-world services they provide.
Platform: Provides web-accessible services for many carriers at once.
Note: Carrier
s may extend Platform
s and override them when their behavior differs from the Platform
.
FreightKit relies on plug-ins (gems) to define how it connects to individual Carrier
s and Platform
s.
Using bundler, add to the Gemfile
:
gem 'freight_kit'
Or standalone:
$ gem install freight_kit
Note: Plug-ins are required to connect to Carrier
s and Platforms
(see above).
Start off by initializing the Carrier
provided by a Carrier
plug-in:
require 'freight_kit'
# Typically just one `Credential` is required
credentials = [
FreightKit::Credential.new(
type: :api,
account: 'account_number',
username: 'username',
password: 'password',
tariff: FreightKit::Tariff.new # optional
),
FreightKit::Credential.new(
type: :oauth2,
access_token: 'token',
expires_at: DateTime.current + 1.day, # DateTime
scope: 'scope'
),
FreightKit::Credential.new(
type: :website,
username: 'username',
password: 'password'
),
FreightKit::Credential.new(
type: :selenoid,
base_url: URI.parse('http://domain:4444'),
browser: :chrome
)
]
carrier = FreightKit::SCAC.new(credentials)
carrier.bol(tracking_number) # BOL generated by carrier
carrier.scanned_bol(tracking_number) # BOL scanned by carrier
carrier.pod(tracking_number)
tracking = carrier.find_tracking_info(tracking_number)
tracking.delivered?
tracking.status
tracking.shipment_events.each do |event|
puts "#{event.name} at #{event.location.city}, #{event.location.state} on #{event.time}. #{event.message}"
end
packages = [
FreightKit::Package.new(
371 * 16, # 371 lbs
{
length: 40, # inches
width: 48,
height: 47
},
units: :imperial
),
FreightKit::Package.new(
371 * 16, # 371 lbs
{
length: 40, # inches
width: 48,
height: 47
},
freight_class: 125, # override calculated freight class
units: :imperial
)
]
origin = FreightKit::Location.new(
country: 'US',
state: 'CA',
city: 'Los Angeles',
zip: '90001'
)
destination = FreightKit::Location.new(
country: 'US',
state: 'IL',
city: 'Chicago',
zip: '60007'
)
accessorials = %i[
appointment_delivery
liftgate_delivery
residential_delivery
]
response = carrier.find_rates(origin, destination, packages, accessorials: accessorials)
rates = response.rates
rates = response.rates.sort_by(&:price).collect { |rate| [rate.service_name, rate.price] }