sailthru-client 4.0.7 → 4.1.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 +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +22 -0
- data/lib/sailthru/client.rb +42 -2
- data/lib/sailthru/version.rb +1 -1
- data/test/fixtures/templates_get.json +1 -0
- data/test/sailthru/file_upload_test.rb +5 -3
- data/test/sailthru/rate_info_test.rb +94 -0
- data/test/sailthru/template_test.rb +8 -0
- data/test/test_helper.rb +17 -4
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 861a575aa56944d027c0cc7e3fbd52a9c266abc0
|
4
|
+
data.tar.gz: 55d80097eb3dc65651a27c90e27d2a481f113019
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4d39c922e39970f6bcf10063efdf015b513da719fef606092e69e594603d3a3e83f2631a2b491b7bcd463bd50867b23200c9f87b7ded646b1dc8b969f832f90
|
7
|
+
data.tar.gz: 7b30e7fc8563837c3176de48bc6edc2674d21b240085a6314510a3138811dab377e6e8a0fa6b7b135239a78a3f53a6281f652604c81b9ecda7f8f04cebdf627c
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -24,6 +24,28 @@ sailthru = Sailthru::Client.new("api-key", "api-secret", "https://api.sailthru.c
|
|
24
24
|
{:http_read_timeout => 30, :http_ssl_timeout => 30, :http_open_timeout => 30})
|
25
25
|
```
|
26
26
|
|
27
|
+
## Rate Limit Information
|
28
|
+
|
29
|
+
The library allows inspection of the 'X-Rate-Limit-*' headers returned by the Sailthru API. The `get_last_rate_limit_info(endpoint, method)` function allows you to retrieve the last known rate limit information for the given endpoint / method combination. It must follow an API call. For example, if you do a `/send POST`, you can follow up with a call to `get_last_rate_limit_info(:send, :post)` as shown below:
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
# make API call as normal
|
33
|
+
response = sailthru.send_email template_name, email, {foo: "bar"}
|
34
|
+
|
35
|
+
# check rate limit information
|
36
|
+
rate_limit_info = sailthru.get_last_rate_limit_info :send, :post
|
37
|
+
```
|
38
|
+
|
39
|
+
The return type will be `nil` if there is no rate limit information for the given endpoint / method combination (e.g. if you have not yet made a request to that endpoint). Otherwise, it will be a hash in the following format:
|
40
|
+
|
41
|
+
``` ruby
|
42
|
+
{
|
43
|
+
limit: 1234, # <Number representing the limit of requests/minute for this action / method combination>
|
44
|
+
remaining: 1230, # <Number representing how many requests remain in the current minute>
|
45
|
+
reset: 1459381680 # <Number representing the UNIX epoch timestamp of when the next minute starts, and when the rate limit resets>
|
46
|
+
}
|
47
|
+
```
|
48
|
+
|
27
49
|
## License
|
28
50
|
|
29
51
|
Please see MIT-LICENSE for license.
|
data/lib/sailthru/client.rb
CHANGED
@@ -29,6 +29,7 @@ module Sailthru
|
|
29
29
|
@proxy_port = proxy_port
|
30
30
|
@verify_ssl = true
|
31
31
|
@opts = opts
|
32
|
+
@last_rate_limit_info = {}
|
32
33
|
end
|
33
34
|
|
34
35
|
# params:
|
@@ -746,6 +747,21 @@ module Sailthru
|
|
746
747
|
api_request(action, data, 'DELETE')
|
747
748
|
end
|
748
749
|
|
750
|
+
# params
|
751
|
+
# endpoint, String a e.g. "user" or "send"
|
752
|
+
# method, String "GET" or "POST"
|
753
|
+
# returns
|
754
|
+
# Hash rate info
|
755
|
+
# Get rate info for a particular endpoint/method, as of the last time a request was sent to the given endpoint/method
|
756
|
+
# Includes the following keys:
|
757
|
+
# limit: the per-minute limit for the given endpoint/method
|
758
|
+
# remaining: the number of allotted requests remaining in the current minute for the given endpoint/method
|
759
|
+
# reset: unix timestamp of the top of the next minute, when the rate limit will reset
|
760
|
+
def get_last_rate_limit_info(endpoint, method)
|
761
|
+
rate_info_key = get_rate_limit_info_key(endpoint, method)
|
762
|
+
@last_rate_limit_info[rate_info_key]
|
763
|
+
end
|
764
|
+
|
749
765
|
protected
|
750
766
|
|
751
767
|
# params:
|
@@ -774,7 +790,7 @@ module Sailthru
|
|
774
790
|
if !binary_key.nil?
|
775
791
|
data[binary_key] = binary_key_data
|
776
792
|
end
|
777
|
-
_result = http_request(
|
793
|
+
_result = http_request(action, data, request_type, binary_key)
|
778
794
|
|
779
795
|
# NOTE: don't do the unserialize here
|
780
796
|
if data[:format] == 'json'
|
@@ -817,9 +833,10 @@ module Sailthru
|
|
817
833
|
# method, String "GET" or "POST"
|
818
834
|
# returns:
|
819
835
|
# String, body of response
|
820
|
-
def http_request(
|
836
|
+
def http_request(action, data, method = 'POST', binary_key = nil)
|
821
837
|
data = flatten_nested_hash(data, false)
|
822
838
|
|
839
|
+
uri = "#{@api_uri}/#{action}"
|
823
840
|
if method != 'POST'
|
824
841
|
uri += "?" + data.map{ |key, value| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}" }.join("&")
|
825
842
|
end
|
@@ -866,6 +883,8 @@ module Sailthru
|
|
866
883
|
raise ClientError, "Unable to open stream to #{_uri}: #{e.message}"
|
867
884
|
end
|
868
885
|
|
886
|
+
save_rate_limit_info(action, method, response)
|
887
|
+
|
869
888
|
response.body || raise(ClientError, "No response received from stream: #{_uri}")
|
870
889
|
end
|
871
890
|
|
@@ -883,5 +902,26 @@ module Sailthru
|
|
883
902
|
payload[:sig] = get_signature_hash(payload, @secret)
|
884
903
|
payload
|
885
904
|
end
|
905
|
+
|
906
|
+
def save_rate_limit_info(action, method, response)
|
907
|
+
limit = response['x-rate-limit-limit'].to_i
|
908
|
+
remaining = response['x-rate-limit-remaining'].to_i
|
909
|
+
reset = response['x-rate-limit-reset'].to_i
|
910
|
+
|
911
|
+
if limit.nil? or remaining.nil? or reset.nil?
|
912
|
+
return
|
913
|
+
end
|
914
|
+
|
915
|
+
rate_info_key = get_rate_limit_info_key(action, method)
|
916
|
+
@last_rate_limit_info[rate_info_key] = {
|
917
|
+
limit: limit,
|
918
|
+
remaining: remaining,
|
919
|
+
reset: reset
|
920
|
+
}
|
921
|
+
end
|
922
|
+
|
923
|
+
def get_rate_limit_info_key(endpoint, method)
|
924
|
+
:"#{endpoint}_#{method.downcase}"
|
925
|
+
end
|
886
926
|
end
|
887
927
|
end
|
data/lib/sailthru/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
{"templates":[{"template_id": 23},{"template_id": 24}]}
|
@@ -3,7 +3,7 @@ require 'mocha/setup'
|
|
3
3
|
|
4
4
|
class FileUploadTest < Minitest::Test
|
5
5
|
|
6
|
-
describe "
|
6
|
+
describe "File Upload Functionality" do
|
7
7
|
|
8
8
|
before do
|
9
9
|
@secret = 'my_secret'
|
@@ -26,7 +26,8 @@ class FileUploadTest < Minitest::Test
|
|
26
26
|
Net::HTTP.stubs(:Proxy).returns(Net::HTTP)
|
27
27
|
Net::HTTP.any_instance.stubs(
|
28
28
|
:request => stub(
|
29
|
-
"body" => JSON.unparse({"job_id" => "123"})
|
29
|
+
"body" => JSON.unparse({"job_id" => "123"}),
|
30
|
+
"[]" => nil
|
30
31
|
)
|
31
32
|
)
|
32
33
|
|
@@ -50,7 +51,8 @@ class FileUploadTest < Minitest::Test
|
|
50
51
|
Net::HTTP.stubs(:Proxy).returns(Net::HTTP)
|
51
52
|
Net::HTTP.any_instance.stubs(
|
52
53
|
:request => stub(
|
53
|
-
"body" => JSON.unparse({"job_id" => "123"})
|
54
|
+
"body" => JSON.unparse({"job_id" => "123"}),
|
55
|
+
"[]" => nil
|
54
56
|
)
|
55
57
|
)
|
56
58
|
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RateInfoTest < Minitest::Test
|
4
|
+
describe "get_last_rate_limit_info() (All API Calls)" do
|
5
|
+
before do
|
6
|
+
@api_url = 'http://api.sailthru.com'
|
7
|
+
@secret = 'my_secret'
|
8
|
+
@api_key = 'my_api_key'
|
9
|
+
@sailthru_client = Sailthru::Client.new(@api_key, @secret, @api_url)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns rate limit info for a given endpoint and method" do
|
13
|
+
# perform a /send GET request
|
14
|
+
api_call_url = sailthru_api_call_url(@api_url, 'send')
|
15
|
+
valid_send_id = "TT1ClGdj2bRHAAP6"
|
16
|
+
params = {
|
17
|
+
'send_id' => valid_send_id
|
18
|
+
}
|
19
|
+
query_string = create_json_payload(@api_key, @secret, params)
|
20
|
+
rate_headers = get_rate_info_headers(3, 2, Time.now.to_i)
|
21
|
+
stub_get(api_call_url + '?' + query_string , 'send_get_valid.json', rate_headers)
|
22
|
+
response = @sailthru_client.get_send(valid_send_id)
|
23
|
+
assert_equal valid_send_id, response['send_id']
|
24
|
+
|
25
|
+
# verify the subsequent rate info for /send GET
|
26
|
+
rate_info = @sailthru_client.get_last_rate_limit_info(:send, :get)
|
27
|
+
assert_equal rate_headers[:x_rate_limit_limit], rate_info[:limit]
|
28
|
+
assert_equal rate_headers[:x_rate_limit_remaining], rate_info[:remaining]
|
29
|
+
assert_equal rate_headers[:x_rate_limit_reset], rate_info[:reset]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can return distinct rate limit info for different endpoints" do
|
33
|
+
# perform a /send GET request
|
34
|
+
send_api_call_url = sailthru_api_call_url(@api_url, 'send')
|
35
|
+
valid_send_id = "TT1ClGdj2bRHAAP6"
|
36
|
+
send_query_string = create_json_payload(@api_key, @secret, { 'send_id' => valid_send_id })
|
37
|
+
send_rate_headers = get_rate_info_headers(3, 2, Time.now.to_i + 10)
|
38
|
+
stub_get(send_api_call_url + '?' + send_query_string , 'send_get_valid.json', send_rate_headers)
|
39
|
+
response = @sailthru_client.get_send(valid_send_id)
|
40
|
+
assert_equal valid_send_id, response['send_id']
|
41
|
+
|
42
|
+
# perform a /list GET request -- and have this endpoint return different rate info
|
43
|
+
list_api_call_url = sailthru_api_call_url(@api_url, 'list')
|
44
|
+
list = 'list1'
|
45
|
+
list_query_string = create_json_payload(@api_key, @secret, {'list' => list})
|
46
|
+
list_rate_headers = get_rate_info_headers(5, 4, Time.now.to_i + 8)
|
47
|
+
stub_get(list_api_call_url + '?' + list_query_string, 'list_get_valid.json', list_rate_headers)
|
48
|
+
response = @sailthru_client.get_list(list)
|
49
|
+
assert_equal(response['list'], list)
|
50
|
+
|
51
|
+
# verify the rate info for each call
|
52
|
+
send_rate_info = @sailthru_client.get_last_rate_limit_info(:send, :get)
|
53
|
+
assert_equal send_rate_headers[:x_rate_limit_limit], send_rate_info[:limit]
|
54
|
+
assert_equal send_rate_headers[:x_rate_limit_remaining], send_rate_info[:remaining]
|
55
|
+
assert_equal send_rate_headers[:x_rate_limit_reset], send_rate_info[:reset]
|
56
|
+
|
57
|
+
list_rate_info = @sailthru_client.get_last_rate_limit_info(:list, :get)
|
58
|
+
assert_equal list_rate_headers[:x_rate_limit_limit], list_rate_info[:limit]
|
59
|
+
assert_equal list_rate_headers[:x_rate_limit_remaining], list_rate_info[:remaining]
|
60
|
+
assert_equal list_rate_headers[:x_rate_limit_reset], list_rate_info[:reset]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "can return distinct rate limit info for different methods" do
|
64
|
+
api_call_url = sailthru_api_call_url(@api_url, 'send')
|
65
|
+
|
66
|
+
# perform a /send GET request
|
67
|
+
valid_send_id = "TT1ClGdj2bRHAAP6"
|
68
|
+
get_query_string = create_json_payload(@api_key, @secret, { 'send_id' => valid_send_id })
|
69
|
+
get_rate_headers = get_rate_info_headers(3, 2, Time.now.to_i + 10)
|
70
|
+
stub_get(api_call_url + '?' + get_query_string , 'send_get_valid.json', get_rate_headers)
|
71
|
+
response = @sailthru_client.get_send(valid_send_id)
|
72
|
+
assert_equal valid_send_id, response['send_id']
|
73
|
+
|
74
|
+
# perform a /send POST request -- and have this method return different rate info
|
75
|
+
template_name = 'default'
|
76
|
+
email = 'example@example.com'
|
77
|
+
post_rate_headers = get_rate_info_headers(5, 4, Time.now.to_i + 8)
|
78
|
+
stub_post(api_call_url, 'send_get_valid.json', post_rate_headers)
|
79
|
+
response = @sailthru_client.send_email template_name, email, {"name" => "Unix", "myvar" => [1111,2,3], "mycomplexvar" => {"tags" => ["obama", "aaa", "c"]}}
|
80
|
+
assert_equal template_name, response['template']
|
81
|
+
|
82
|
+
# verify the rate info for each call
|
83
|
+
get_rate_info = @sailthru_client.get_last_rate_limit_info(:send, :get)
|
84
|
+
assert_equal get_rate_headers[:x_rate_limit_limit], get_rate_info[:limit]
|
85
|
+
assert_equal get_rate_headers[:x_rate_limit_remaining], get_rate_info[:remaining]
|
86
|
+
assert_equal get_rate_headers[:x_rate_limit_reset], get_rate_info[:reset]
|
87
|
+
|
88
|
+
post_rate_info = @sailthru_client.get_last_rate_limit_info(:send, :post)
|
89
|
+
assert_equal post_rate_headers[:x_rate_limit_limit], post_rate_info[:limit]
|
90
|
+
assert_equal post_rate_headers[:x_rate_limit_remaining], post_rate_info[:remaining]
|
91
|
+
assert_equal post_rate_headers[:x_rate_limit_reset], post_rate_info[:reset]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -28,6 +28,14 @@ class TemplateTest < Minitest::Test
|
|
28
28
|
assert_equal 14, response['error']
|
29
29
|
end
|
30
30
|
|
31
|
+
it "can get a list of all existing templates" do
|
32
|
+
query_string = create_json_payload(@api_key, @secret, {})
|
33
|
+
stub_get(@api_call_url + '?' + query_string, 'templates_get.json')
|
34
|
+
response = @sailthru_client.get_templates
|
35
|
+
assert response['templates'][0].has_key?('template_id')
|
36
|
+
refute_nil response['templates'][0]['template_id']
|
37
|
+
end
|
38
|
+
|
31
39
|
it "can save template with given template name" do
|
32
40
|
valid_template_name = 'my-template-new'
|
33
41
|
from_email = 'praj@sailthru.com'
|
data/test/test_helper.rb
CHANGED
@@ -34,18 +34,22 @@ class Minitest::Test
|
|
34
34
|
sailthru_api_base_url(url + action)
|
35
35
|
end
|
36
36
|
|
37
|
-
def stub_get(url, filename)
|
37
|
+
def stub_get(url, filename, headers={})
|
38
38
|
options = { :body => fixture_file(filename), :content_type => 'application/json' }
|
39
|
+
options.merge!(headers)
|
39
40
|
FakeWeb.register_uri(:get, URI.parse(url), options)
|
40
41
|
end
|
41
42
|
|
42
|
-
def stub_delete(url, filename)
|
43
|
+
def stub_delete(url, filename, headers={})
|
43
44
|
options = { :body => fixture_file(filename), :content_type => 'application/json' }
|
45
|
+
options.merge!(headers)
|
44
46
|
FakeWeb.register_uri(:delete, URI.parse(url), options)
|
45
47
|
end
|
46
48
|
|
47
|
-
def stub_post(url, filename)
|
48
|
-
|
49
|
+
def stub_post(url, filename, headers={})
|
50
|
+
options = { :body => fixture_file(filename), :content_type => 'application/json' }
|
51
|
+
options.merge!(headers)
|
52
|
+
FakeWeb.register_uri(:post, URI.parse(url), options)
|
49
53
|
end
|
50
54
|
|
51
55
|
def stub_exception(url, filename)
|
@@ -65,4 +69,13 @@ class Minitest::Test
|
|
65
69
|
data['sig'] = get_signature_hash(data, secret)
|
66
70
|
data.map{ |key, value| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}" }.join("&")
|
67
71
|
end
|
72
|
+
|
73
|
+
def get_rate_info_headers(limit, remaining, reset)
|
74
|
+
{
|
75
|
+
:x_rate_limit_limit => limit,
|
76
|
+
:x_rate_limit_remaining => remaining,
|
77
|
+
:x_rate_limit_reset => reset
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
68
81
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sailthru-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Prajwal Tuladhar
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-05-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -153,6 +153,7 @@ files:
|
|
153
153
|
- test/fixtures/template_save.json
|
154
154
|
- test/fixtures/template_save_test_vars.json
|
155
155
|
- test/fixtures/template_valid_get.json
|
156
|
+
- test/fixtures/templates_get.json
|
156
157
|
- test/fixtures/user_update_post_valid.json
|
157
158
|
- test/fixtures/user_update_valid.json
|
158
159
|
- test/sailthru/blast_test.rb
|
@@ -163,6 +164,7 @@ files:
|
|
163
164
|
- test/sailthru/helpers_test.rb
|
164
165
|
- test/sailthru/list_test.rb
|
165
166
|
- test/sailthru/purchase_test.rb
|
167
|
+
- test/sailthru/rate_info_test.rb
|
166
168
|
- test/sailthru/receive_post_callback_test.rb
|
167
169
|
- test/sailthru/send_test.rb
|
168
170
|
- test/sailthru/stats_test.rb
|
@@ -233,6 +235,7 @@ test_files:
|
|
233
235
|
- test/fixtures/template_save.json
|
234
236
|
- test/fixtures/template_save_test_vars.json
|
235
237
|
- test/fixtures/template_valid_get.json
|
238
|
+
- test/fixtures/templates_get.json
|
236
239
|
- test/fixtures/user_update_post_valid.json
|
237
240
|
- test/fixtures/user_update_valid.json
|
238
241
|
- test/sailthru/blast_test.rb
|
@@ -243,6 +246,7 @@ test_files:
|
|
243
246
|
- test/sailthru/helpers_test.rb
|
244
247
|
- test/sailthru/list_test.rb
|
245
248
|
- test/sailthru/purchase_test.rb
|
249
|
+
- test/sailthru/rate_info_test.rb
|
246
250
|
- test/sailthru/receive_post_callback_test.rb
|
247
251
|
- test/sailthru/send_test.rb
|
248
252
|
- test/sailthru/stats_test.rb
|