apsis-on-steroids 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +36 -6
- data/README.md +123 -0
- data/VERSION +1 -1
- data/apsis-on-steroids.gemspec +16 -10
- data/include/bounce.rb +3 -0
- data/include/click.rb +5 -0
- data/include/errors.rb +1 -1
- data/include/open.rb +3 -0
- data/include/opt_out.rb +3 -0
- data/include/sending.rb +59 -0
- data/include/sub_base.rb +10 -4
- data/lib/apsis-on-steroids.rb +96 -44
- data/spec/apsis-on-steroids_spec.rb +41 -15
- metadata +49 -61
- data/README.rdoc +0 -87
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ca260874d9300648caddfb9ca87705a72b17de34
|
4
|
+
data.tar.gz: 246852b83262cce4dd77dba066b5d838eb4e6354
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 87aeb2df293b7edb9ecdf3fc1f91127c7693385a2c59f414fc54d24970035ac37153d567654bb2053dda039d03a22073f7c2df8b5f5372309c60680c9660de25
|
7
|
+
data.tar.gz: f481ad7b1a86fc87be112e642e5fe7c2dc84e0189c497ae6e1c8ddbaeb14bebee9a42447dff66a5becbbbb44575a24de00f0480ded150197c561518ac200bc79
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,16 +1,46 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
addressable (2.3.6)
|
5
|
+
builder (3.2.2)
|
4
6
|
diff-lcs (1.1.3)
|
5
|
-
|
6
|
-
|
7
|
-
|
7
|
+
faraday (0.8.9)
|
8
|
+
multipart-post (~> 1.2.0)
|
9
|
+
git (1.2.8)
|
10
|
+
github_api (0.10.1)
|
11
|
+
addressable
|
12
|
+
faraday (~> 0.8.1)
|
13
|
+
hashie (>= 1.2)
|
14
|
+
multi_json (~> 1.4)
|
15
|
+
nokogiri (~> 1.5.2)
|
16
|
+
oauth2
|
17
|
+
hashie (3.2.0)
|
18
|
+
highline (1.6.21)
|
19
|
+
http2 (0.0.25)
|
20
|
+
string-cases
|
21
|
+
jeweler (1.8.8)
|
22
|
+
builder
|
8
23
|
bundler (~> 1.0)
|
9
24
|
git (>= 1.2.5)
|
25
|
+
github_api (= 0.10.1)
|
26
|
+
highline (>= 1.6.15)
|
27
|
+
nokogiri (= 1.5.10)
|
10
28
|
rake
|
11
29
|
rdoc
|
12
|
-
json (1.8.
|
13
|
-
|
30
|
+
json (1.8.1)
|
31
|
+
jwt (1.0.0)
|
32
|
+
multi_json (1.10.1)
|
33
|
+
multi_xml (0.5.5)
|
34
|
+
multipart-post (1.2.0)
|
35
|
+
nokogiri (1.5.10)
|
36
|
+
oauth2 (1.0.0)
|
37
|
+
faraday (>= 0.8, < 0.10)
|
38
|
+
jwt (~> 1.0)
|
39
|
+
multi_json (~> 1.3)
|
40
|
+
multi_xml (~> 0.5)
|
41
|
+
rack (~> 1.2)
|
42
|
+
rack (1.5.2)
|
43
|
+
rake (10.3.2)
|
14
44
|
rdoc (3.12.2)
|
15
45
|
json (~> 1.4)
|
16
46
|
rspec (2.8.0)
|
@@ -28,7 +58,7 @@ PLATFORMS
|
|
28
58
|
|
29
59
|
DEPENDENCIES
|
30
60
|
bundler (>= 1.0.0)
|
31
|
-
http2 (~> 0.0.
|
61
|
+
http2 (~> 0.0.25)
|
32
62
|
jeweler (~> 1.8.4)
|
33
63
|
rdoc (~> 3.12)
|
34
64
|
rspec (~> 2.8.0)
|
data/README.md
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
[![Code Climate](https://codeclimate.com/github/kaspernj/apsis-on-steroids/badges/gpa.svg)](https://codeclimate.com/github/kaspernj/apsis-on-steroids)
|
2
|
+
|
3
|
+
# apsis-on-steroids
|
4
|
+
|
5
|
+
Library that implements the Apsis API in Ruby in regards to administrating subscribers and such for newsletters.
|
6
|
+
|
7
|
+
## Examples
|
8
|
+
|
9
|
+
### Connecting
|
10
|
+
```ruby
|
11
|
+
aos = ApsisOnSteroids.new(
|
12
|
+
:api_key => "[your api key]"
|
13
|
+
)
|
14
|
+
```
|
15
|
+
|
16
|
+
### List all mailing lists.
|
17
|
+
```ruby
|
18
|
+
aos.mailing_lists
|
19
|
+
```
|
20
|
+
|
21
|
+
### Create a mailing list
|
22
|
+
```ruby
|
23
|
+
aos.create_mailing_list(
|
24
|
+
:Name => "my_awesome_list",
|
25
|
+
:FromName => "Kasper Johansen",
|
26
|
+
:FromEmail => "kj@naoshi-dev.com",
|
27
|
+
:CharacterSet => "utf-8"
|
28
|
+
)
|
29
|
+
```
|
30
|
+
|
31
|
+
### Get a mailing list.
|
32
|
+
```ruby
|
33
|
+
mlist = aos.mailing_list_by_name("test_list")
|
34
|
+
```
|
35
|
+
|
36
|
+
### Delete a mailing list.
|
37
|
+
```ruby
|
38
|
+
mlist.delete
|
39
|
+
```
|
40
|
+
|
41
|
+
### Get a subscriber from a mailing list.
|
42
|
+
```ruby
|
43
|
+
sub = mlist.subscriber_by_email("some@email.com")
|
44
|
+
```
|
45
|
+
|
46
|
+
### Create one or more subscribers in a mailing list.
|
47
|
+
```ruby
|
48
|
+
mlist.create_subscribers(
|
49
|
+
[
|
50
|
+
{
|
51
|
+
:Email => "some@email.com",
|
52
|
+
:Name => "Some Name"
|
53
|
+
},{
|
54
|
+
:Email => "some_other@email.com",
|
55
|
+
:Name => "Some Name"
|
56
|
+
}
|
57
|
+
]
|
58
|
+
)
|
59
|
+
```
|
60
|
+
|
61
|
+
### Get details about subscribers.
|
62
|
+
```ruby
|
63
|
+
puts "Details: #{sub.details}"
|
64
|
+
```
|
65
|
+
|
66
|
+
### Update subscribers.
|
67
|
+
```ruby
|
68
|
+
sub.update(:Email => "some_third@email.com")
|
69
|
+
```
|
70
|
+
|
71
|
+
### Remove subscriber from a mailing list.
|
72
|
+
```ruby
|
73
|
+
mlist.remove_subscriber(sub)
|
74
|
+
```
|
75
|
+
|
76
|
+
### Get a list of subscribers from a mailing list.
|
77
|
+
```ruby
|
78
|
+
list = mlist.subscribers
|
79
|
+
list.each do |sub|
|
80
|
+
# do something
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
### Get a total list of subscribers.
|
85
|
+
```ruby
|
86
|
+
aos.subscribers do |sub|
|
87
|
+
# do something
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
### Get sendings
|
92
|
+
```ruby
|
93
|
+
date_from = Date.new(2014, 6, 17)
|
94
|
+
date_to = Date.new(2014, 6, 24)
|
95
|
+
|
96
|
+
sendings = apsis.sendings_by_date_interval(@date_from, @date_to).to_a
|
97
|
+
```
|
98
|
+
|
99
|
+
### Get data from sendings
|
100
|
+
sendings.opens(count: true) #=> 5
|
101
|
+
sendings.bounces(count: true) #=> 1
|
102
|
+
sendings.clicks(count: true) #=> 3
|
103
|
+
sendings.opt_outs(count: true) #=> 1
|
104
|
+
|
105
|
+
sendings.clicks.each do |click|
|
106
|
+
puts "ClickData: #{click.data_hash}"
|
107
|
+
end
|
108
|
+
|
109
|
+
## Contributing to apsis-on-steroids
|
110
|
+
|
111
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
112
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
113
|
+
* Fork the project.
|
114
|
+
* Start a feature/bugfix branch.
|
115
|
+
* Commit and push until you are happy with your contribution.
|
116
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
117
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
118
|
+
|
119
|
+
## Copyright
|
120
|
+
|
121
|
+
Copyright (c) 2013 kaspernj. See LICENSE.txt for
|
122
|
+
further details.
|
123
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.9
|
data/apsis-on-steroids.gemspec
CHANGED
@@ -2,19 +2,21 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: apsis-on-steroids 0.0.9 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "apsis-on-steroids"
|
8
|
-
s.version = "0.0.
|
9
|
+
s.version = "0.0.9"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["kaspernj"]
|
12
|
-
s.date = "
|
14
|
+
s.date = "2014-08-04"
|
13
15
|
s.description = "A Ruby API for the Apsis mail service. "
|
14
16
|
s.email = "k@spernj.org"
|
15
17
|
s.extra_rdoc_files = [
|
16
18
|
"LICENSE.txt",
|
17
|
-
"README.
|
19
|
+
"README.md"
|
18
20
|
]
|
19
21
|
s.files = [
|
20
22
|
".document",
|
@@ -22,12 +24,17 @@ Gem::Specification.new do |s|
|
|
22
24
|
"Gemfile",
|
23
25
|
"Gemfile.lock",
|
24
26
|
"LICENSE.txt",
|
25
|
-
"README.
|
27
|
+
"README.md",
|
26
28
|
"Rakefile",
|
27
29
|
"VERSION",
|
28
30
|
"apsis-on-steroids.gemspec",
|
31
|
+
"include/bounce.rb",
|
32
|
+
"include/click.rb",
|
29
33
|
"include/errors.rb",
|
30
34
|
"include/mailing_list.rb",
|
35
|
+
"include/open.rb",
|
36
|
+
"include/opt_out.rb",
|
37
|
+
"include/sending.rb",
|
31
38
|
"include/sub_base.rb",
|
32
39
|
"include/subscriber.rb",
|
33
40
|
"lib/apsis-on-steroids.rb",
|
@@ -36,22 +43,21 @@ Gem::Specification.new do |s|
|
|
36
43
|
]
|
37
44
|
s.homepage = "http://github.com/kaspernj/apsis-on-steroids"
|
38
45
|
s.licenses = ["MIT"]
|
39
|
-
s.
|
40
|
-
s.rubygems_version = "1.8.23"
|
46
|
+
s.rubygems_version = "2.4.0"
|
41
47
|
s.summary = "A Ruby API for the Apsis mail service."
|
42
48
|
|
43
49
|
if s.respond_to? :specification_version then
|
44
|
-
s.specification_version =
|
50
|
+
s.specification_version = 4
|
45
51
|
|
46
52
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
|
-
s.add_runtime_dependency(%q<http2>, ["~> 0.0.
|
53
|
+
s.add_runtime_dependency(%q<http2>, ["~> 0.0.25"])
|
48
54
|
s.add_runtime_dependency(%q<string-cases>, [">= 0"])
|
49
55
|
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
50
56
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
51
57
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
52
58
|
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
53
59
|
else
|
54
|
-
s.add_dependency(%q<http2>, ["~> 0.0.
|
60
|
+
s.add_dependency(%q<http2>, ["~> 0.0.25"])
|
55
61
|
s.add_dependency(%q<string-cases>, [">= 0"])
|
56
62
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
57
63
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
@@ -59,7 +65,7 @@ Gem::Specification.new do |s|
|
|
59
65
|
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
60
66
|
end
|
61
67
|
else
|
62
|
-
s.add_dependency(%q<http2>, ["~> 0.0.
|
68
|
+
s.add_dependency(%q<http2>, ["~> 0.0.25"])
|
63
69
|
s.add_dependency(%q<string-cases>, [">= 0"])
|
64
70
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
65
71
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
data/include/bounce.rb
ADDED
data/include/click.rb
ADDED
data/include/errors.rb
CHANGED
data/include/open.rb
ADDED
data/include/opt_out.rb
ADDED
data/include/sending.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
class ApsisOnSteroids::Sending < ApsisOnSteroids::SubBase
|
2
|
+
def clicks args = {}
|
3
|
+
list_for("v1/clicks/sendqueues/%{send_queue_id}/page/%{page}/size/%{size}", "Click", args)
|
4
|
+
end
|
5
|
+
|
6
|
+
def opens args = {}
|
7
|
+
list_for("v1/opens/sendqueues/%{send_queue_id}/page/%{page}/size/%{size}", "Open", args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def bounces args = {}
|
11
|
+
list_for("v1/bounces/sendqueues/%{send_queue_id}/page/%{page}/size/%{size}", "Bounce", args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def opt_outs args = {}
|
15
|
+
list_for("v1/optouts/sendqueues/%{send_queue_id}/%{page}/%{size}", "OptOut", args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def mailing_lists
|
19
|
+
Enumerator.new do |yielder|
|
20
|
+
data(:mailinglist_id).each do |mailing_list_id|
|
21
|
+
next if mailing_list_id == 0
|
22
|
+
yielder << aos.mailing_list_by_id(mailing_list_id)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def list_for resource_url, resource_name, args = {}
|
30
|
+
page = 1
|
31
|
+
resource_url = resource_url.gsub("%{send_queue_id}", data(:send_queue_id).to_s)
|
32
|
+
|
33
|
+
if args[:count]
|
34
|
+
resource_url = resource_url.gsub("%{page}", page.to_s).gsub("%{size}", "2")
|
35
|
+
res = aos.req_json("/#{resource_url}")
|
36
|
+
return res["Result"]["TotalCount"]
|
37
|
+
end
|
38
|
+
|
39
|
+
response_url = response_url.gsub("%{size}", "200")
|
40
|
+
|
41
|
+
Enumerator.new do |yielder|
|
42
|
+
loop do
|
43
|
+
resource_url = resource_url.gsub("%{page}", page.to_s)
|
44
|
+
res = aos.req_json("/#{resource_url}")
|
45
|
+
|
46
|
+
aos.read_resources_from_array(resource_name, res["Result"]["Items"]).each do |resource|
|
47
|
+
yielder << resource
|
48
|
+
end
|
49
|
+
|
50
|
+
size_no = res["Result"]["TotalPages"]
|
51
|
+
if page >= size_no
|
52
|
+
break
|
53
|
+
else
|
54
|
+
page += 1
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/include/sub_base.rb
CHANGED
@@ -1,23 +1,29 @@
|
|
1
1
|
class ApsisOnSteroids::SubBase
|
2
2
|
def initialize(args)
|
3
3
|
@args = args
|
4
|
-
|
4
|
+
|
5
5
|
@data = {}
|
6
6
|
@args[:data].each do |key, val|
|
7
7
|
@data[StringCases.camel_to_snake(key).to_sym] = val
|
8
8
|
end
|
9
|
+
|
10
|
+
@data = aos.parse_obj(@data)
|
9
11
|
end
|
10
|
-
|
12
|
+
|
11
13
|
def aos
|
12
14
|
return @args[:aos]
|
13
15
|
end
|
14
|
-
|
16
|
+
|
15
17
|
def data(name)
|
16
18
|
name = name.to_sym
|
17
19
|
return @data[name] if @data.key?(name)
|
18
20
|
raise "No such data: '#{name}' in fields: #{@data.keys}"
|
19
21
|
end
|
20
|
-
|
22
|
+
|
23
|
+
def data_hash
|
24
|
+
return @data
|
25
|
+
end
|
26
|
+
|
21
27
|
def debugs(str)
|
22
28
|
self.aos.debugs(str)
|
23
29
|
end
|
data/lib/apsis-on-steroids.rb
CHANGED
@@ -5,33 +5,36 @@ require "timeout"
|
|
5
5
|
require "cgi"
|
6
6
|
|
7
7
|
class ApsisOnSteroids
|
8
|
+
STRFTIME_FORMAT = "%Y%m%dT%H%M%S"
|
9
|
+
|
8
10
|
attr_reader :http
|
9
|
-
|
11
|
+
|
10
12
|
def self.const_missing(name)
|
11
13
|
require "#{File.dirname(__FILE__)}/../include/#{::StringCases.camel_to_snake(name)}"
|
12
14
|
raise "Still not loaded: '#{name}'." unless ApsisOnSteroids.const_defined?(name)
|
13
15
|
return ApsisOnSteroids.const_get(name)
|
14
16
|
end
|
15
|
-
|
17
|
+
|
16
18
|
def initialize(args)
|
17
19
|
raise "Invalid API key: '#{args[:api_key]}' from: '#{args}'." if args[:api_key].to_s.strip.empty?
|
18
|
-
|
20
|
+
|
19
21
|
@args = args
|
20
22
|
@http = Http2.new(
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
23
|
+
host: "se.api.anpdm.com",
|
24
|
+
port: 8443,
|
25
|
+
ssl: true,
|
26
|
+
follow_redirects: false,
|
27
|
+
debug: args[:debug],
|
28
|
+
extra_headers: {
|
27
29
|
"Accept" => "text/json, application/json"
|
28
30
|
},
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
32
|
-
}
|
31
|
+
basic_auth: {
|
32
|
+
user: @args[:api_key],
|
33
|
+
passwd: ""
|
34
|
+
},
|
35
|
+
skip_port_in_host_header: true
|
33
36
|
)
|
34
|
-
|
37
|
+
|
35
38
|
if block_given?
|
36
39
|
begin
|
37
40
|
yield self
|
@@ -41,93 +44,130 @@ class ApsisOnSteroids
|
|
41
44
|
end
|
42
45
|
end
|
43
46
|
end
|
44
|
-
|
47
|
+
|
48
|
+
def new_url_builder
|
49
|
+
ub = ::Http2::UrlBuilder.new
|
50
|
+
ub.protocol = "https"
|
51
|
+
ub.port = "8443"
|
52
|
+
ub.host = "se.api.anpdm.com"
|
53
|
+
|
54
|
+
return ub
|
55
|
+
end
|
56
|
+
|
45
57
|
# Closes connection and removes all references to resource-objects.
|
46
58
|
def destroy
|
47
59
|
@http.destroy if @http
|
48
60
|
@http = nil
|
49
61
|
end
|
50
|
-
|
62
|
+
|
51
63
|
def debugs(str)
|
52
64
|
puts str if @args[:debug]
|
53
65
|
end
|
54
|
-
|
66
|
+
|
55
67
|
def mailing_lists
|
56
68
|
res = req_json("v1/mailinglists/1/999")
|
57
|
-
|
69
|
+
|
58
70
|
ret = []
|
59
71
|
res["Result"]["Items"].each do |mlist|
|
60
72
|
ret << ApsisOnSteroids::MailingList.new(
|
61
|
-
:
|
62
|
-
:
|
73
|
+
aos: self,
|
74
|
+
data: mlist
|
63
75
|
)
|
64
76
|
end
|
65
|
-
|
77
|
+
|
66
78
|
return ret
|
67
79
|
end
|
68
|
-
|
80
|
+
|
69
81
|
def create_mailing_list(data)
|
70
|
-
res = req_json("v1/mailinglists/", :post, :
|
82
|
+
res = req_json("v1/mailinglists/", :post, json: data)
|
71
83
|
if res["Code"] == 1
|
72
84
|
# Success!
|
73
85
|
else
|
74
86
|
raise "Unexpected result: '#{res}'."
|
75
87
|
end
|
76
88
|
end
|
77
|
-
|
89
|
+
|
90
|
+
def sendings_by_date_interval(date_from, date_to)
|
91
|
+
date_from_str = date_from.strftime(STRFTIME_FORMAT)
|
92
|
+
date_to_str = date_to.strftime(STRFTIME_FORMAT)
|
93
|
+
|
94
|
+
Enumerator.new do |yielder|
|
95
|
+
res = req_json("v1/sendqueues/date/from/#{date_from_str}/to/#{date_to_str}")
|
96
|
+
|
97
|
+
res["Result"].each do |sending_data|
|
98
|
+
sending = ApsisOnSteroids::Sending.new(
|
99
|
+
aos: self,
|
100
|
+
data: sending_data
|
101
|
+
)
|
102
|
+
|
103
|
+
yielder << sending
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
78
108
|
def mailing_list_by_name(name)
|
79
|
-
|
109
|
+
mailing_lists.each do |mlist|
|
80
110
|
return mlist if name.to_s == mlist.data(:name).to_s
|
81
111
|
end
|
82
|
-
|
112
|
+
|
83
113
|
raise "Could not find mailing list by that name: '#{name}'."
|
84
114
|
end
|
85
|
-
|
115
|
+
|
116
|
+
def mailing_list_by_id(id)
|
117
|
+
tried_ids = []
|
118
|
+
mailing_lists.each do |mailing_list|
|
119
|
+
return mailing_list if mailing_list.data(:id) == id.to_i
|
120
|
+
tried_ids << mailing_list.data(:id)
|
121
|
+
end
|
122
|
+
|
123
|
+
raise "Mailing list by that ID could not be found: #{id} in list #{tried_ids}"
|
124
|
+
end
|
125
|
+
|
86
126
|
def subscriber_by_email(email)
|
87
127
|
begin
|
88
|
-
res = req_json("subscribers/v2/email", :post, :
|
128
|
+
res = req_json("subscribers/v2/email", :post, json: email)
|
89
129
|
rescue
|
90
130
|
raise ApsisOnSteroids::Errors::SubscriberNotFound, "Could not find subscriber by that email in the system: '#{email}'."
|
91
131
|
end
|
92
|
-
|
132
|
+
|
93
133
|
sub = ApsisOnSteroids::Subscriber.new(
|
94
|
-
:
|
95
|
-
:
|
134
|
+
aos: self,
|
135
|
+
data: {
|
96
136
|
"Id" => res["Result"],
|
97
137
|
"Email" => email
|
98
138
|
}
|
99
139
|
)
|
100
|
-
|
140
|
+
|
101
141
|
return sub
|
102
142
|
end
|
103
|
-
|
143
|
+
|
104
144
|
def req_json(url, type = :get, method_args = {})
|
105
145
|
# Parse arguments, send and parse the result.
|
106
146
|
args = { :url => url.start_with?('/') ? url[1..-1] : url }.merge(method_args)
|
107
147
|
http_res = @http.__send__(type, args)
|
108
|
-
|
148
|
+
|
109
149
|
begin
|
110
150
|
res = JSON.parse(http_res.body)
|
111
151
|
rescue JSON::ParserError
|
112
152
|
raise "Invalid JSON given: '#{http_res.body}'."
|
113
153
|
end
|
114
|
-
|
154
|
+
|
115
155
|
# Check for various kind of server errors and raise them as Ruby errors if present.
|
116
156
|
raise "Failed on server with code #{res["Code"]}: #{res["Message"]}" if res.is_a?(Hash) && res.key?("Code") && res["Code"] < 0
|
117
157
|
raise "Failed on server with state #{res["State"]} and name '#{res["StateName"]}': #{res["Message"]}" if res.is_a?(Hash) && res.key?("State") && res["State"].to_i < 0
|
118
|
-
|
158
|
+
|
119
159
|
# Return the result.
|
120
160
|
return res
|
121
161
|
end
|
122
|
-
|
162
|
+
|
123
163
|
def read_queued_response(url)
|
124
164
|
uri = URI.parse(url)
|
125
|
-
|
165
|
+
|
126
166
|
Timeout.timeout(300) do
|
127
167
|
loop do
|
128
168
|
sleep 1
|
129
169
|
res = req_json(uri.path)
|
130
|
-
|
170
|
+
|
131
171
|
if res["State"] == "2"
|
132
172
|
uri_data = URI.parse(res["DataUrl"])
|
133
173
|
return req_json(uri_data.path)
|
@@ -139,29 +179,41 @@ class ApsisOnSteroids
|
|
139
179
|
end
|
140
180
|
end
|
141
181
|
end
|
142
|
-
|
182
|
+
|
183
|
+
def read_resources_from_array resource_class_name, resource_array
|
184
|
+
Enumerator.new do |yielder|
|
185
|
+
resource_array.each do |resource_data|
|
186
|
+
resource = ApsisOnSteroids.const_get(resource_class_name).new(aos: self, data: resource_data)
|
187
|
+
yielder << resource
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
143
192
|
def parse_obj(obj)
|
144
193
|
if obj.is_a?(Array)
|
145
194
|
ret = []
|
146
195
|
obj.each do |obj_i|
|
147
196
|
ret << parse_obj(obj_i)
|
148
197
|
end
|
149
|
-
|
198
|
+
|
150
199
|
return ret
|
151
200
|
elsif obj.is_a?(Hash)
|
152
201
|
ret = {}
|
153
202
|
obj.each do |key, val|
|
154
203
|
ret[key] = parse_obj(val)
|
155
204
|
end
|
156
|
-
|
205
|
+
|
157
206
|
return ret
|
158
207
|
elsif obj.is_a?(String)
|
159
208
|
# Automatically convert dates.
|
160
|
-
if match = obj.match(/^\/Date\((\d+)\+(\d+)\)
|
209
|
+
if match = obj.match(/^\/Date\((\d+)\+(\d+)\)\/$/)
|
210
|
+
unix_t = match[1].to_i / 1000
|
211
|
+
return Time.at(unix_t)
|
212
|
+
elsif match = obj.match(/^\/Date\((\d+)\)\/$/)
|
161
213
|
unix_t = match[1].to_i / 1000
|
162
214
|
return Time.at(unix_t)
|
163
215
|
end
|
164
|
-
|
216
|
+
|
165
217
|
return obj
|
166
218
|
else
|
167
219
|
return obj
|
@@ -11,19 +11,19 @@ describe "ApsisOnSteroids" do
|
|
11
11
|
it "can connect" do
|
12
12
|
aos
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
it "should create and delete a mailing list" do
|
16
16
|
name = "create-mlist-#{Time.now.to_f.to_s}"
|
17
|
-
|
17
|
+
|
18
18
|
aos.create_mailing_list(
|
19
19
|
:Name => name,
|
20
20
|
:FromName => "Kasper Johansen",
|
21
21
|
:FromEmail => "kj@naoshi-dev.com",
|
22
22
|
:CharacterSet => "utf-8"
|
23
23
|
)
|
24
|
-
|
24
|
+
|
25
25
|
mlist = aos.mailing_list_by_name(name)
|
26
|
-
|
26
|
+
|
27
27
|
sleep 1
|
28
28
|
mlist.delete
|
29
29
|
end
|
@@ -32,13 +32,39 @@ describe "ApsisOnSteroids" do
|
|
32
32
|
mlist = aos.mailing_list_by_name("kj")
|
33
33
|
end
|
34
34
|
|
35
|
+
it "#sendings_by_date_interval" do
|
36
|
+
date_from = Date.new(2014, 6, 1)
|
37
|
+
date_to = Date.new(2014, 6, 4)
|
38
|
+
|
39
|
+
list = aos.sendings_by_date_interval(date_from, date_to).to_a
|
40
|
+
list.empty?.should_not eq true
|
41
|
+
|
42
|
+
sending = list.first
|
43
|
+
puts "Sending data: #{sending.data_hash}"
|
44
|
+
|
45
|
+
mlists = sending.mailing_lists.first
|
46
|
+
puts "MList: #{mlists.data_hash}"
|
47
|
+
|
48
|
+
click = sending.clicks.first
|
49
|
+
puts "Click data: #{click.data_hash}"
|
50
|
+
|
51
|
+
open = sending.opens.first
|
52
|
+
puts "Open data: #{open.data_hash}"
|
53
|
+
|
54
|
+
bounce = sending.bounces.first
|
55
|
+
puts "Bounce data: #{bounce.data_hash}"
|
56
|
+
|
57
|
+
opt_outs_count = sending.opt_outs(count: true)
|
58
|
+
puts "Opt outs count: #{opt_outs_count}"
|
59
|
+
end
|
60
|
+
|
35
61
|
context do
|
36
62
|
let(:mlist) do
|
37
63
|
mlist = aos.mailing_list_by_name("kj")
|
38
64
|
mlist.remove_all_subscribers
|
39
65
|
mlist
|
40
66
|
end
|
41
|
-
|
67
|
+
|
42
68
|
let(:sub) do
|
43
69
|
email = "kaspernj#{Time.now.to_f}@naoshi-dev.com"
|
44
70
|
mlist.create_subscribers([{
|
@@ -47,11 +73,11 @@ describe "ApsisOnSteroids" do
|
|
47
73
|
}])
|
48
74
|
aos.subscriber_by_email(email)
|
49
75
|
end
|
50
|
-
|
76
|
+
|
51
77
|
it "can create subscribers" do
|
52
78
|
sub
|
53
79
|
end
|
54
|
-
|
80
|
+
|
55
81
|
it "can get subscribers and their details" do
|
56
82
|
details = sub.details
|
57
83
|
details.is_a?(Hash).should eql(true)
|
@@ -81,16 +107,16 @@ describe "ApsisOnSteroids" do
|
|
81
107
|
it "can lookup the subscriber on the list" do
|
82
108
|
mlist.subscriber_by_email(sub.data(:email)).should_not eq nil
|
83
109
|
end
|
84
|
-
|
110
|
+
|
85
111
|
it "can get lists of subscribers from lists" do
|
86
112
|
original_sub = sub
|
87
|
-
|
113
|
+
|
88
114
|
count = 0
|
89
115
|
mlist.subscribers do |sub_i|
|
90
116
|
count += 1
|
91
117
|
#puts "Subscriber: #{sub_i}"
|
92
118
|
end
|
93
|
-
|
119
|
+
|
94
120
|
raise "Expected more than one." if count < 1
|
95
121
|
end
|
96
122
|
|
@@ -101,24 +127,24 @@ describe "ApsisOnSteroids" do
|
|
101
127
|
it "can validate if a subscriber is active or not" do
|
102
128
|
sub.active?.should eql(true)
|
103
129
|
end
|
104
|
-
|
130
|
+
|
105
131
|
it "can subscribe, remove and then re-subscribe" do
|
106
132
|
sub.active?.should eql(true)
|
107
|
-
|
133
|
+
|
108
134
|
mlist.remove_subscriber(sub)
|
109
135
|
mlist.add_subscriber(sub)
|
110
|
-
|
136
|
+
|
111
137
|
sub.active?.should eql(true)
|
112
138
|
mlist.member?(sub).should eql(true)
|
113
139
|
end
|
114
|
-
|
140
|
+
|
115
141
|
it "should be able to opt out a subscriber" do
|
116
142
|
mlist.opt_out_subscriber(sub)
|
117
143
|
mlist.opt_out?(sub).should eql(true)
|
118
144
|
mlist.opt_out_remove_subscriber(sub)
|
119
145
|
mlist.opt_out?(sub).should eql(false)
|
120
146
|
end
|
121
|
-
|
147
|
+
|
122
148
|
it "trying to an email that does not exist should raise the correct error" do
|
123
149
|
expect{
|
124
150
|
aos.subscriber_by_email("asd@asd.com")
|
metadata
CHANGED
@@ -1,131 +1,123 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apsis-on-steroids
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.0.8
|
4
|
+
version: 0.0.9
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- kaspernj
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-08-04 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
|
16
|
-
|
14
|
+
name: http2
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
17
16
|
requirements:
|
18
|
-
- - ~>
|
17
|
+
- - "~>"
|
19
18
|
- !ruby/object:Gem::Version
|
20
|
-
version: 0.0.
|
21
|
-
name: http2
|
19
|
+
version: 0.0.25
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
|
-
|
25
|
-
none: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.0.
|
26
|
+
version: 0.0.25
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
|
-
|
32
|
-
|
28
|
+
name: string-cases
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
33
30
|
requirements:
|
34
|
-
- -
|
31
|
+
- - ">="
|
35
32
|
- !ruby/object:Gem::Version
|
36
33
|
version: '0'
|
37
|
-
name: string-cases
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
|
-
|
41
|
-
none: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
|
-
|
48
|
-
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
49
44
|
requirements:
|
50
|
-
- - ~>
|
45
|
+
- - "~>"
|
51
46
|
- !ruby/object:Gem::Version
|
52
47
|
version: 2.8.0
|
53
|
-
name: rspec
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
|
-
|
57
|
-
none: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
51
|
requirements:
|
59
|
-
- - ~>
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 2.8.0
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
|
-
|
64
|
-
|
56
|
+
name: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
65
58
|
requirements:
|
66
|
-
- - ~>
|
59
|
+
- - "~>"
|
67
60
|
- !ruby/object:Gem::Version
|
68
61
|
version: '3.12'
|
69
|
-
name: rdoc
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
|
-
|
73
|
-
none: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
65
|
requirements:
|
75
|
-
- - ~>
|
66
|
+
- - "~>"
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '3.12'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
|
-
|
80
|
-
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
81
72
|
requirements:
|
82
|
-
- -
|
73
|
+
- - ">="
|
83
74
|
- !ruby/object:Gem::Version
|
84
75
|
version: 1.0.0
|
85
|
-
name: bundler
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
|
-
|
89
|
-
none: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - ">="
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: 1.0.0
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
|
-
|
96
|
-
|
84
|
+
name: jeweler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
97
86
|
requirements:
|
98
|
-
- - ~>
|
87
|
+
- - "~>"
|
99
88
|
- !ruby/object:Gem::Version
|
100
89
|
version: 1.8.4
|
101
|
-
name: jeweler
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
|
-
|
105
|
-
none: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
93
|
requirements:
|
107
|
-
- - ~>
|
94
|
+
- - "~>"
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: 1.8.4
|
110
|
-
description:
|
97
|
+
description: 'A Ruby API for the Apsis mail service. '
|
111
98
|
email: k@spernj.org
|
112
99
|
executables: []
|
113
100
|
extensions: []
|
114
101
|
extra_rdoc_files:
|
115
102
|
- LICENSE.txt
|
116
|
-
- README.
|
103
|
+
- README.md
|
117
104
|
files:
|
118
|
-
- .document
|
119
|
-
- .rspec
|
105
|
+
- ".document"
|
106
|
+
- ".rspec"
|
120
107
|
- Gemfile
|
121
108
|
- Gemfile.lock
|
122
109
|
- LICENSE.txt
|
123
|
-
- README.
|
110
|
+
- README.md
|
124
111
|
- Rakefile
|
125
112
|
- VERSION
|
126
113
|
- apsis-on-steroids.gemspec
|
114
|
+
- include/bounce.rb
|
115
|
+
- include/click.rb
|
127
116
|
- include/errors.rb
|
128
117
|
- include/mailing_list.rb
|
118
|
+
- include/open.rb
|
119
|
+
- include/opt_out.rb
|
120
|
+
- include/sending.rb
|
129
121
|
- include/sub_base.rb
|
130
122
|
- include/subscriber.rb
|
131
123
|
- lib/apsis-on-steroids.rb
|
@@ -134,29 +126,25 @@ files:
|
|
134
126
|
homepage: http://github.com/kaspernj/apsis-on-steroids
|
135
127
|
licenses:
|
136
128
|
- MIT
|
129
|
+
metadata: {}
|
137
130
|
post_install_message:
|
138
131
|
rdoc_options: []
|
139
132
|
require_paths:
|
140
133
|
- lib
|
141
134
|
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
-
none: false
|
143
135
|
requirements:
|
144
|
-
- -
|
136
|
+
- - ">="
|
145
137
|
- !ruby/object:Gem::Version
|
146
|
-
segments:
|
147
|
-
- 0
|
148
|
-
hash: -1381735060528271675
|
149
138
|
version: '0'
|
150
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
-
none: false
|
152
140
|
requirements:
|
153
|
-
- -
|
141
|
+
- - ">="
|
154
142
|
- !ruby/object:Gem::Version
|
155
143
|
version: '0'
|
156
144
|
requirements: []
|
157
145
|
rubyforge_project:
|
158
|
-
rubygems_version:
|
146
|
+
rubygems_version: 2.4.0
|
159
147
|
signing_key:
|
160
|
-
specification_version:
|
148
|
+
specification_version: 4
|
161
149
|
summary: A Ruby API for the Apsis mail service.
|
162
150
|
test_files: []
|
data/README.rdoc
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
= apsis-on-steroids
|
2
|
-
|
3
|
-
Library that implements the Apsis API in Ruby in regards to administrating subscribers and such for newsletters.
|
4
|
-
|
5
|
-
== Examples
|
6
|
-
|
7
|
-
=== Connecting
|
8
|
-
|
9
|
-
aos = ApsisOnSteroids.new(
|
10
|
-
:api_key => "[your api key]"
|
11
|
-
)
|
12
|
-
|
13
|
-
=== Create a mailing list
|
14
|
-
|
15
|
-
aos.create_mailing_list(
|
16
|
-
:Name => "my_awesome_list",
|
17
|
-
:FromName => "Kasper Johansen",
|
18
|
-
:FromEmail => "kj@naoshi-dev.com",
|
19
|
-
:CharacterSet => "utf-8"
|
20
|
-
)
|
21
|
-
|
22
|
-
=== Get a mailing list.
|
23
|
-
|
24
|
-
mlist = aos.mailing_list_by_name("test_list")
|
25
|
-
|
26
|
-
=== Delete a mailing list.
|
27
|
-
|
28
|
-
mlist.delete
|
29
|
-
|
30
|
-
=== Get a subscriber from a mailing list.
|
31
|
-
|
32
|
-
sub = mlist.subscriber_by_email("some@email.com")
|
33
|
-
|
34
|
-
=== Create one or more subscribers in a mailing list.
|
35
|
-
|
36
|
-
mlist.create_subscribers(
|
37
|
-
[
|
38
|
-
{
|
39
|
-
:Email => "some@email.com",
|
40
|
-
:Name => "Some Name"
|
41
|
-
},{
|
42
|
-
:Email => "some_other@email.com",
|
43
|
-
:Name => "Some Name"
|
44
|
-
}
|
45
|
-
]
|
46
|
-
)
|
47
|
-
|
48
|
-
=== Get details about subscribers.
|
49
|
-
|
50
|
-
puts "Details: #{sub.details}"
|
51
|
-
|
52
|
-
=== Update subscribers.
|
53
|
-
|
54
|
-
sub.update(:Email => "some_third@email.com")
|
55
|
-
|
56
|
-
=== Remove subscriber from a mailing list.
|
57
|
-
|
58
|
-
mlist.remove_subscriber(sub)
|
59
|
-
|
60
|
-
=== Get a list of subscribers from a mailing list.
|
61
|
-
|
62
|
-
list = mlist.subscribers
|
63
|
-
list.each do |sub|
|
64
|
-
# do something
|
65
|
-
end
|
66
|
-
|
67
|
-
=== Get a total list of subscribers.
|
68
|
-
|
69
|
-
aos.subscribers do |sub|
|
70
|
-
# do something
|
71
|
-
end
|
72
|
-
|
73
|
-
== Contributing to apsis-on-steroids
|
74
|
-
|
75
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
76
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
77
|
-
* Fork the project.
|
78
|
-
* Start a feature/bugfix branch.
|
79
|
-
* Commit and push until you are happy with your contribution.
|
80
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
81
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
82
|
-
|
83
|
-
== Copyright
|
84
|
-
|
85
|
-
Copyright (c) 2013 kaspernj. See LICENSE.txt for
|
86
|
-
further details.
|
87
|
-
|