sendle-api 0.0.2 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +5 -0
- data/README.md +99 -5
- data/lib/sendle/api.rb +46 -3
- data/lib/sendle/api/actions/base.rb +51 -0
- data/lib/sendle/api/actions/create.rb +31 -0
- data/lib/sendle/api/actions/destroy.rb +23 -0
- data/lib/sendle/api/actions/index.rb +16 -14
- data/lib/sendle/api/actions/show.rb +23 -0
- data/lib/sendle/api/constants.rb +4 -0
- data/lib/sendle/api/errors/invalid_plan.rb +16 -0
- data/lib/sendle/api/errors/missing_params.rb +16 -0
- data/lib/sendle/api/errors/payment_required.rb +9 -0
- data/lib/sendle/api/errors/precondition_failed.rb +9 -0
- data/lib/sendle/api/errors/unprocessable_entity.rb +19 -0
- data/lib/sendle/api/factories/errors.rb +26 -0
- data/lib/sendle/api/order.rb +41 -0
- data/lib/sendle/api/ping.rb +8 -3
- data/lib/sendle/api/quote.rb +28 -0
- data/lib/sendle/api/resource.rb +64 -0
- data/lib/sendle/api/responses/json.rb +15 -0
- data/lib/sendle/api/sugars/create.rb +13 -0
- data/lib/sendle/api/sugars/destroy.rb +13 -0
- data/lib/sendle/api/sugars/index.rb +13 -0
- data/lib/sendle/api/sugars/show.rb +13 -0
- data/lib/sendle/api/utils.rb +24 -0
- data/lib/sendle/api/version.rb +1 -1
- data/spec/sendle/api/order_spec.rb +249 -0
- data/spec/sendle/api/ping_spec.rb +9 -1
- data/spec/sendle/api/quote_spec.rb +103 -0
- data/spec/sendle/api_spec.rb +22 -0
- data/spec/sendle/errors/missing_params_spec.rb +13 -0
- data/spec/support/helpers.rb +15 -1
- data/spec/support/shared_examples/with_credentials_spec.rb +1 -1
- metadata +29 -3
- data/lib/sendle/utils/actions.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68b93ccc7a2f1762a621462360bfd3efaa0b9a1e
|
4
|
+
data.tar.gz: eac48906b5c093d3fe83547bebaa9ddd1c3585c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d63dfb209cb35f600b6d3f30a4e2ead269245a9a0681a16ab69fbfeb6e062491313e536b5b48be5b9e296881aa496638801fadf6fe40994cdefa22a2227c861
|
7
|
+
data.tar.gz: 5ec6cfacd67a5494cda6335786500ca45aa7ba13f0a6a9118e3093283f0e9abf01b39a6685af28904ecd8edd74b191489e11b6da9ab06febc75ad61ac546519a
|
data/Changelog.md
ADDED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Sendle::Api
|
2
2
|
|
3
|
-
|
3
|
+
The Sendle API Ruby bindings provide a small SDK for convenient access to the Sendle API from applications written with the Ruby language.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -20,7 +20,101 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
23
|
+
Before you can use the Sendle API, you need to sign up for a Sendle account. Once you have signed up, you need to send an email to Sendle support requesting access to their API. When access has been granted, you will have access to your sendle_id and api_key, both which are required to access the api.
|
24
|
+
|
25
|
+
If you are accessing the Sendle API in sandbox mode, you need to repeat the above process on Sendle's sandbox servers.
|
26
|
+
|
27
|
+
### Configuration
|
28
|
+
|
29
|
+
Before you can start using the library, you need to configure your api credentials. The instructions below assume you are using this library from a Rails application.
|
30
|
+
|
31
|
+
Create a file called 'sendle.rb' inside your config/initializers directory with the following content:
|
32
|
+
```
|
33
|
+
Sendle::Api.api_key = Rails.application.secrets.sendle_api_key
|
34
|
+
Sendle::Api.sendle_id = Rails.application.secrets.sendle_id
|
35
|
+
Sendle::Api.sandbox = true #Only if you are accessing the Sendle sandbox servers, otherwise take out this line.
|
36
|
+
```
|
37
|
+
|
38
|
+
### Making a Request
|
39
|
+
|
40
|
+
Sendle's API documentation can be found here: http://sendle.github.io/sendle-api-doc.
|
41
|
+
|
42
|
+
#### Pinging the API
|
43
|
+
```
|
44
|
+
Sendle::Api::Ping.execute
|
45
|
+
```
|
46
|
+
|
47
|
+
Returns an instance of Sendle::Api::Responses::Pong upon a successful response from the API.
|
48
|
+
|
49
|
+
#### Getting a Delivery Quote
|
50
|
+
```
|
51
|
+
params = { pickup_suburb: 'woolloomooloo',
|
52
|
+
pickup_postcode: '2011',
|
53
|
+
delivery_suburb: 'eastgardens',
|
54
|
+
delivery_postcode: '2036',
|
55
|
+
kilogram_weight: '1'
|
56
|
+
}
|
57
|
+
response = Sendle::Api::Quote.execute(params)
|
58
|
+
|
59
|
+
puts response.json #a hash
|
60
|
+
```
|
61
|
+
|
62
|
+
Returns an instance of Sendle::Api::Responses::Json upon a successful response.
|
63
|
+
|
64
|
+
#### Creating an Order
|
65
|
+
```
|
66
|
+
params = { pickup_date: "2016-05-05",
|
67
|
+
description: "Kryptonite",
|
68
|
+
kilogram_weight: 1,
|
69
|
+
cubic_metre_volume: 0.01,
|
70
|
+
customer_reference: "SupBdayPressie",
|
71
|
+
sender: {
|
72
|
+
contact: {
|
73
|
+
name: "Lex Luthor",
|
74
|
+
phone: "0412 345 678"
|
75
|
+
},
|
76
|
+
address: {
|
77
|
+
address_line1: "123 Gotham Ln",
|
78
|
+
suburb: "Sydney",
|
79
|
+
state_name: "NSW",
|
80
|
+
postcode: "2000",
|
81
|
+
country: "Australia"
|
82
|
+
},
|
83
|
+
instructions: "Knock loudly"
|
84
|
+
},
|
85
|
+
receiver: {
|
86
|
+
contact: {
|
87
|
+
name: "Clark Kent",
|
88
|
+
email: "clarkissuper@dailyplanet.xyz"
|
89
|
+
},
|
90
|
+
address: {
|
91
|
+
address_line1: "80 Wentworth Park Road",
|
92
|
+
suburb: "Glebe",
|
93
|
+
state_name: "NSW",
|
94
|
+
postcode: "2037",
|
95
|
+
country: "Australia"
|
96
|
+
},
|
97
|
+
instructions: "Give directly to Clark"
|
98
|
+
}
|
99
|
+
}
|
100
|
+
response = Sendle::Api::Order.create(params) #response is an instance of Sendle::Api::Responses::Json
|
101
|
+
```
|
102
|
+
|
103
|
+
#### Viewing an Order
|
104
|
+
```
|
105
|
+
#response is an instance of Sendle::Api::Responses::Json
|
106
|
+
response = Sendle::Api::Order.show("d9a5f8be-a245-4629-bfb5-e019bd9a2a06")
|
107
|
+
```
|
108
|
+
|
109
|
+
#### Cancelling an Order (only orders with is_cancellable attribute set to true can be cancelled)
|
110
|
+
```
|
111
|
+
#response is an instance of Sendle::Api::Responses::Json
|
112
|
+
response = Sendle::Api::Order.destroy("d9a5f8be-a245-4629-bfb5-e019bd9a2a06")
|
113
|
+
```
|
114
|
+
|
115
|
+
#### Errors
|
116
|
+
Any of the methods described above can throw errors. Check the Sendle API docs for a list of errors and how to resolve them.
|
117
|
+
|
24
118
|
|
25
119
|
## Contributing
|
26
120
|
|
@@ -35,10 +129,10 @@ TODO: Write usage instructions here
|
|
35
129
|
1. Navigate to root of this project
|
36
130
|
2. Run bundle install to install the gems specified in sendle-api.gemspec
|
37
131
|
3. Run bundle exec rake spec to run the tests
|
132
|
+
4. After changes and ready to release, up the version in lib/sendle/api/version.rb
|
133
|
+
5. Then run 'bundle install' on your testing project. Testing project is installing the sendle-api gem using a local path, so we don't need to release the gem to RubyGems.
|
134
|
+
6. Once the gem is ready to be release, follow the instructions below.
|
38
135
|
|
39
136
|
### Release
|
40
137
|
1. Make sure you have a RubyGems.org account
|
41
138
|
2. bundle exec rake release
|
42
|
-
|
43
|
-
### Guide
|
44
|
-
Based on this guide: https://quickleft.com/blog/engineering-lunch-series-step-by-step-guide-to-building-your-first-ruby-gem
|
data/lib/sendle/api.rb
CHANGED
@@ -1,17 +1,60 @@
|
|
1
|
+
# 3rd party libs
|
1
2
|
require 'rest-client'
|
2
3
|
|
4
|
+
# Version
|
3
5
|
require "sendle/api/version"
|
4
6
|
|
5
|
-
|
7
|
+
# Constants
|
8
|
+
require "sendle/api/constants"
|
9
|
+
|
10
|
+
# Utils
|
11
|
+
require 'sendle/api/utils'
|
12
|
+
|
13
|
+
# Syntax Sugar
|
14
|
+
require 'sendle/api/sugars/index'
|
15
|
+
require 'sendle/api/sugars/create'
|
16
|
+
require 'sendle/api/sugars/show'
|
17
|
+
require 'sendle/api/sugars/destroy'
|
18
|
+
|
19
|
+
# Api resource actions
|
20
|
+
require 'sendle/api/actions/base'
|
21
|
+
require 'sendle/api/actions/index'
|
22
|
+
require 'sendle/api/actions/create'
|
23
|
+
require 'sendle/api/actions/show'
|
24
|
+
require 'sendle/api/actions/destroy'
|
25
|
+
|
26
|
+
# Factories
|
27
|
+
require 'sendle/api/factories/errors'
|
28
|
+
|
29
|
+
# Api errors
|
30
|
+
require 'sendle/api/errors/missing_api_key'
|
31
|
+
require 'sendle/api/errors/missing_sendle_id'
|
32
|
+
require 'sendle/api/errors/unauthorized'
|
33
|
+
require 'sendle/api/errors/payment_required'
|
34
|
+
require 'sendle/api/errors/missing_params'
|
35
|
+
require 'sendle/api/errors/invalid_plan'
|
36
|
+
require 'sendle/api/errors/unprocessable_entity'
|
37
|
+
require 'sendle/api/errors/precondition_failed'
|
38
|
+
|
39
|
+
# Api responses
|
40
|
+
require 'sendle/api/responses/pong'
|
41
|
+
require 'sendle/api/responses/json'
|
42
|
+
|
43
|
+
# Api resources
|
44
|
+
require 'sendle/api/resource'
|
45
|
+
require 'sendle/api/ping'
|
46
|
+
require 'sendle/api/quote'
|
47
|
+
require 'sendle/api/order'
|
6
48
|
|
7
49
|
module Sendle
|
8
50
|
module Api
|
51
|
+
@sandbox = false
|
9
52
|
|
10
53
|
class << self
|
11
|
-
attr_accessor :api_key, :sendle_id
|
54
|
+
attr_accessor :api_key, :sendle_id, :sandbox
|
12
55
|
|
13
56
|
def base_url
|
14
|
-
"https://sandbox.sendle.com/api/"
|
57
|
+
sandbox ? "https://sandbox.sendle.com/api/" : "https://www.sendle.com/api/"
|
15
58
|
end
|
16
59
|
end
|
17
60
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Sendle
|
2
|
+
module Api
|
3
|
+
module Actions
|
4
|
+
module Base
|
5
|
+
|
6
|
+
def request(params)
|
7
|
+
RestClient::Request.execute(params)
|
8
|
+
rescue RestClient::PreconditionFailed,
|
9
|
+
RestClient::Unauthorized,
|
10
|
+
RestClient::PaymentRequired,
|
11
|
+
RestClient::UnprocessableEntity => e
|
12
|
+
raise Sendle::Api::Factories::Errors.new_error(e)
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def rest_client_params
|
18
|
+
include_credentials? ? common_params_with_credentials : common_params
|
19
|
+
end
|
20
|
+
|
21
|
+
def common_params
|
22
|
+
{
|
23
|
+
headers: json_headers
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def common_params_with_credentials
|
28
|
+
common_params.merge(credential_params)
|
29
|
+
end
|
30
|
+
|
31
|
+
def check_for_missing_credentials
|
32
|
+
return unless self.include_credentials?
|
33
|
+
raise Sendle::Api::Errors::MissingSendleId if Sendle::Api.sendle_id.nil?
|
34
|
+
raise Sendle::Api::Errors::MissingApiKey if Sendle::Api.api_key.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def json_headers
|
38
|
+
{ accept: :json, content_type: :json }
|
39
|
+
end
|
40
|
+
|
41
|
+
def credential_params
|
42
|
+
{
|
43
|
+
user: Sendle::Api.sendle_id,
|
44
|
+
password: Sendle::Api.api_key
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Sendle
|
2
|
+
module Api
|
3
|
+
module Actions
|
4
|
+
module Create
|
5
|
+
|
6
|
+
def create(params = {})
|
7
|
+
check_for_missing_credentials
|
8
|
+
validate_create_request!(params)
|
9
|
+
|
10
|
+
request_params = rest_client_params
|
11
|
+
request_params[:method] = :post
|
12
|
+
request_params[:url] = url
|
13
|
+
request_params[:payload] = params
|
14
|
+
|
15
|
+
process_create_response(request(request_params))
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.included(base)
|
19
|
+
base.extend(Sendle::Api::Sugars::Create)
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def http_method
|
25
|
+
:post
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Sendle
|
2
|
+
module Api
|
3
|
+
module Actions
|
4
|
+
module Destroy
|
5
|
+
|
6
|
+
def destroy(id)
|
7
|
+
raise Sendle::Api::Errors::MissingParams.new(['id']) if nullish?(id)
|
8
|
+
|
9
|
+
request_params = rest_client_params
|
10
|
+
request_params[:method] = :delete
|
11
|
+
request_params[:url] = url + '/' + id
|
12
|
+
|
13
|
+
process_destroy_response(request(request_params))
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(base)
|
17
|
+
base.extend(Sendle::Api::Sugars::Destroy)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -2,21 +2,23 @@ module Sendle
|
|
2
2
|
module Api
|
3
3
|
module Actions
|
4
4
|
module Index
|
5
|
-
|
6
|
-
def index
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
rescue RestClient::Unauthorized => e
|
17
|
-
response = JSON.parse(e.response)
|
18
|
-
raise Sendle::Api::Errors::Unauthorized.new(response['error_description'])
|
5
|
+
|
6
|
+
def index(params = {})
|
7
|
+
check_for_missing_credentials if include_credentials?
|
8
|
+
validate_index_request!(params)
|
9
|
+
|
10
|
+
request_params = rest_client_params
|
11
|
+
request_params[:method] = :get
|
12
|
+
request_params[:url] = url
|
13
|
+
request_params[:headers][:params] = params unless params.empty?
|
14
|
+
|
15
|
+
process_index_response(request(request_params))
|
19
16
|
end
|
17
|
+
|
18
|
+
def self.included(base)
|
19
|
+
base.extend(Sendle::Api::Sugars::Index)
|
20
|
+
end
|
21
|
+
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Sendle
|
2
|
+
module Api
|
3
|
+
module Actions
|
4
|
+
module Show
|
5
|
+
|
6
|
+
def show(id)
|
7
|
+
raise Sendle::Api::Errors::MissingParams.new(['id']) if nullish?(id)
|
8
|
+
|
9
|
+
request_params = rest_client_params
|
10
|
+
request_params[:method] = :get
|
11
|
+
request_params[:url] = url + '/' + id
|
12
|
+
|
13
|
+
process_show_response(request(request_params))
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(base)
|
17
|
+
base.extend(Sendle::Api::Sugars::Show)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sendle
|
2
|
+
module Api
|
3
|
+
module Errors
|
4
|
+
class MissingParams < StandardError
|
5
|
+
def initialize(*params)
|
6
|
+
@missing_params = params
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
"The following params are required: #{@missing_params.join(', ')}. Please check your request and try again."
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Sendle
|
2
|
+
module Api
|
3
|
+
module Errors
|
4
|
+
class UnprocessableEntity < StandardError
|
5
|
+
|
6
|
+
def initialize(messages)
|
7
|
+
@messages = messages
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
msg = "Please fix the following errors and try again - "
|
12
|
+
@messages.each { |k, v| msg += "#{k}: #{v.join(', ')}" }
|
13
|
+
msg
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|