sendicate 0.1.0 → 0.2.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.
- data/README.md +20 -3
- data/VERSION +1 -1
- data/lib/sendicate.rb +2 -0
- data/lib/sendicate/import.rb +1 -4
- data/lib/sendicate/list.rb +2 -83
- data/lib/sendicate/request.rb +3 -3
- data/lib/sendicate/resource.rb +120 -0
- data/lib/sendicate/subscriber.rb +24 -0
- data/sendicate.gemspec +5 -2
- data/spec/sendicate/list_spec.rb +5 -5
- data/spec/sendicate/subscriber_spec.rb +64 -0
- metadata +6 -3
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
This gem is a wrapper for the [Sendicate API](https://github.com/Sendicate/sendicate-docs/tree/master/api).
|
4
4
|
|
5
|
+
Find out more about Sendicate at [https://www.sendicate.net/](https://www.sendicate.net/).
|
6
|
+
|
5
7
|
|
6
8
|
## Installation
|
7
9
|
|
@@ -10,7 +12,7 @@ This gem is a wrapper for the [Sendicate API](https://github.com/Sendicate/sendi
|
|
10
12
|
|
11
13
|
## Requirements
|
12
14
|
|
13
|
-
You will need a Sendicate account and [API token](https://www.sendicate.net/account/edit).
|
15
|
+
You will need a Sendicate account and [API token](https://www.sendicate.net/account/edit). The token can be found by logging into your Sendicate account and going to Manage, then Account, then scrolling down to API Access.
|
14
16
|
|
15
17
|
|
16
18
|
## Usage
|
@@ -21,9 +23,12 @@ Configure your API token. You can either set the environment variable SENDICATE_
|
|
21
23
|
# or
|
22
24
|
Sendicate.api_token = 'YOUR_API_TOKEN'
|
23
25
|
|
26
|
+
|
27
|
+
### Lists
|
28
|
+
|
24
29
|
Create a new list:
|
25
30
|
|
26
|
-
list = Sendicate::List.new(title: 'Life-changing newsletter')
|
31
|
+
list = Sendicate::List.new(title: 'Life-changing newsletter list')
|
27
32
|
list.save
|
28
33
|
|
29
34
|
View all lists:
|
@@ -32,7 +37,7 @@ View all lists:
|
|
32
37
|
|
33
38
|
Update a list:
|
34
39
|
|
35
|
-
list.title = '
|
40
|
+
list.title = 'new list'
|
36
41
|
list.save
|
37
42
|
|
38
43
|
Destroy a list:
|
@@ -56,6 +61,18 @@ Add a subcriber to a list:
|
|
56
61
|
end
|
57
62
|
|
58
63
|
|
64
|
+
### Subscribers
|
65
|
+
|
66
|
+
Change a subscriber's email address:
|
67
|
+
|
68
|
+
subscriber = Subscriber.find('user@example.com')
|
69
|
+
subscriber.email = 'differentuser@example.com'
|
70
|
+
subscriber.save
|
71
|
+
|
72
|
+
Unsubscribe a subscriber:
|
73
|
+
|
74
|
+
Subscriber.unsubscribe('user@example.com')
|
75
|
+
|
59
76
|
## Contributing to sendicate-ruby
|
60
77
|
|
61
78
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/sendicate.rb
CHANGED
@@ -7,6 +7,8 @@ module Sendicate
|
|
7
7
|
autoload :Import, 'sendicate/import'
|
8
8
|
autoload :List, 'sendicate/list'
|
9
9
|
autoload :Request, 'sendicate/request'
|
10
|
+
autoload :Resource, 'sendicate/resource'
|
11
|
+
autoload :Subscriber, 'sendicate/subscriber'
|
10
12
|
|
11
13
|
class << self
|
12
14
|
attr_accessor :api_token
|
data/lib/sendicate/import.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
module Sendicate
|
2
2
|
|
3
3
|
class Import
|
4
|
-
include HTTParty
|
5
|
-
base_uri 'https://api.sendicate.net/v1'
|
6
|
-
headers 'Accept' => 'application/json', 'Content-Type' => 'application/json', "Authorization" => "token #{Sendicate.api_token}"
|
7
4
|
|
8
5
|
attr_reader :list_id, :data, :response, :errors
|
9
6
|
|
@@ -13,7 +10,7 @@ module Sendicate
|
|
13
10
|
end
|
14
11
|
|
15
12
|
def save
|
16
|
-
@response =
|
13
|
+
@response = Request.post("/lists/#{list_id}/subscribers", body: MultiJson.dump(data))
|
17
14
|
success?
|
18
15
|
end
|
19
16
|
|
data/lib/sendicate/list.rb
CHANGED
@@ -1,87 +1,6 @@
|
|
1
1
|
module Sendicate
|
2
2
|
|
3
|
-
class List
|
4
|
-
|
5
|
-
attr_reader :attributes, :errors
|
6
|
-
|
7
|
-
def initialize(attributes={})
|
8
|
-
@attributes = attributes
|
9
|
-
@errors = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def method_missing(method, *args)
|
13
|
-
method_string = method.to_s
|
14
|
-
is_setter_method = method_string[-1, 1] == '='
|
15
|
-
key = method_string.gsub(/\=/, '')
|
16
|
-
|
17
|
-
if attributes.include?(key)
|
18
|
-
if is_setter_method
|
19
|
-
attributes[key] = args.first
|
20
|
-
else
|
21
|
-
attributes[key]
|
22
|
-
end
|
23
|
-
else
|
24
|
-
super
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class << self
|
29
|
-
|
30
|
-
def all
|
31
|
-
response = Sendicate::Request.get("/lists")
|
32
|
-
response.parsed_response.map do |attributes|
|
33
|
-
new(attributes)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def find(id)
|
38
|
-
if id.nil?
|
39
|
-
raise Sendicate::ResourceNotFound
|
40
|
-
else
|
41
|
-
response = Sendicate::Request.get("/lists/#{id}")
|
42
|
-
new(response.parsed_response)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def default_response_options
|
47
|
-
{
|
48
|
-
query: {
|
49
|
-
token: Sendicate.api_token
|
50
|
-
}
|
51
|
-
}
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def save
|
56
|
-
response = if persisted?
|
57
|
-
Sendicate::Request.post("/lists", body: to_json)
|
58
|
-
else
|
59
|
-
Sendicate::Request.post("/lists/#{id}", body: to_json)
|
60
|
-
end
|
61
|
-
|
62
|
-
if response.success?
|
63
|
-
@attributes = response.parsed_response
|
64
|
-
true
|
65
|
-
else
|
66
|
-
@errors = response.parsed_response
|
67
|
-
false
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def destroy
|
72
|
-
response = Sendicate::Request.delete("/lists/#{id}")
|
73
|
-
end
|
74
|
-
|
75
|
-
def persisted?
|
76
|
-
id
|
77
|
-
end
|
78
|
-
|
79
|
-
def id
|
80
|
-
attributes['id'] || attributes[:id]
|
81
|
-
end
|
82
|
-
|
83
|
-
def to_json
|
84
|
-
MultiJson.dump(attributes)
|
85
|
-
end
|
3
|
+
class List < Resource
|
4
|
+
base_path '/lists'
|
86
5
|
end
|
87
6
|
end
|
data/lib/sendicate/request.rb
CHANGED
@@ -32,11 +32,11 @@ module Sendicate
|
|
32
32
|
unless success?
|
33
33
|
case response.code
|
34
34
|
when 400
|
35
|
-
raise
|
35
|
+
raise BadRequest
|
36
36
|
when 401
|
37
|
-
raise
|
37
|
+
raise Unauthorized
|
38
38
|
when 404
|
39
|
-
raise
|
39
|
+
raise ResourceNotFound
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Sendicate
|
2
|
+
|
3
|
+
class Resource
|
4
|
+
include HTTParty
|
5
|
+
base_uri 'https://api.sendicate.net/v1'
|
6
|
+
headers 'Accept' => 'application/json', 'Content-Type' => 'application/json', "Authorization" => "token #{Sendicate.api_token}"
|
7
|
+
|
8
|
+
attr_reader :attributes, :errors, :response
|
9
|
+
|
10
|
+
def initialize(attributes={})
|
11
|
+
@attributes = attributes
|
12
|
+
@errors = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(method, *args)
|
16
|
+
method_string = method.to_s
|
17
|
+
is_setter_method = method_string[-1, 1] == '='
|
18
|
+
key = method_string.gsub(/\=/, '')
|
19
|
+
|
20
|
+
if is_setter_method
|
21
|
+
attributes[key] = args.first
|
22
|
+
elsif attributes.include?(key)
|
23
|
+
attributes[key]
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
|
31
|
+
def base_path(path)
|
32
|
+
@base_path = path
|
33
|
+
end
|
34
|
+
|
35
|
+
def all
|
36
|
+
response = get(collection_path)
|
37
|
+
response.parsed_response.map do |attributes|
|
38
|
+
new(attributes)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def find(param)
|
43
|
+
if param.nil?
|
44
|
+
raise ResourceNotFound
|
45
|
+
else
|
46
|
+
response = get(member_path(param))
|
47
|
+
new(response.parsed_response)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def collection_path
|
52
|
+
@base_path
|
53
|
+
end
|
54
|
+
|
55
|
+
def member_path(param)
|
56
|
+
[@base_path, param].join("/")
|
57
|
+
end
|
58
|
+
|
59
|
+
def get(*args)
|
60
|
+
Request.get(*args)
|
61
|
+
end
|
62
|
+
|
63
|
+
def post(*args)
|
64
|
+
Request.post(*args)
|
65
|
+
end
|
66
|
+
|
67
|
+
def patch(*args)
|
68
|
+
Request.patch(*args)
|
69
|
+
end
|
70
|
+
|
71
|
+
def put(*args)
|
72
|
+
Request.put(*args)
|
73
|
+
end
|
74
|
+
|
75
|
+
def delete(*args)
|
76
|
+
Request.delete(*args)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def save
|
81
|
+
response = if persisted?
|
82
|
+
self.class.put(member_path, body: to_json)
|
83
|
+
else
|
84
|
+
self.class.post(member_path, body: to_json)
|
85
|
+
end
|
86
|
+
|
87
|
+
if response.success?
|
88
|
+
@attributes = response.parsed_response
|
89
|
+
true
|
90
|
+
else
|
91
|
+
@errors = response.parsed_response
|
92
|
+
false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def destroy
|
97
|
+
response = self.class.delete(member_path)
|
98
|
+
end
|
99
|
+
|
100
|
+
def persisted?
|
101
|
+
!to_param.nil?
|
102
|
+
end
|
103
|
+
|
104
|
+
def id
|
105
|
+
attributes['id'] || attributes[:id]
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_param
|
109
|
+
id
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_json
|
113
|
+
MultiJson.dump(attributes)
|
114
|
+
end
|
115
|
+
|
116
|
+
def member_path
|
117
|
+
self.class.member_path(to_param)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sendicate
|
2
|
+
|
3
|
+
class Subscriber < Resource
|
4
|
+
base_path '/subscribers'
|
5
|
+
|
6
|
+
def email
|
7
|
+
attributes['email'] || attributes[:email]
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_param
|
11
|
+
id || email
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.unsubscribe(email)
|
15
|
+
subscriber = find(email)
|
16
|
+
subscriber.unsubscribe
|
17
|
+
end
|
18
|
+
|
19
|
+
def unsubscribe
|
20
|
+
self.subscribed = false
|
21
|
+
save
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/sendicate.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "sendicate"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Evan Whalen"]
|
12
|
-
s.date = "2013-04-
|
12
|
+
s.date = "2013-04-03"
|
13
13
|
s.description = "Use this Sendicate API wrapper to subscribe your users to your Sendicate mailing lists."
|
14
14
|
s.email = "evanwhalendev@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -28,9 +28,12 @@ Gem::Specification.new do |s|
|
|
28
28
|
"lib/sendicate/import.rb",
|
29
29
|
"lib/sendicate/list.rb",
|
30
30
|
"lib/sendicate/request.rb",
|
31
|
+
"lib/sendicate/resource.rb",
|
32
|
+
"lib/sendicate/subscriber.rb",
|
31
33
|
"sendicate.gemspec",
|
32
34
|
"spec/sendicate/import_spec.rb",
|
33
35
|
"spec/sendicate/list_spec.rb",
|
36
|
+
"spec/sendicate/subscriber_spec.rb",
|
34
37
|
"spec/sendicate_spec.rb",
|
35
38
|
"spec/spec_helper.rb"
|
36
39
|
]
|
data/spec/sendicate/list_spec.rb
CHANGED
@@ -8,7 +8,6 @@ describe Sendicate::List do
|
|
8
8
|
list = Sendicate::List.new(title: "Test list")
|
9
9
|
list.save.should be_true
|
10
10
|
list.id.should_not be_nil
|
11
|
-
@list_id = list.id
|
12
11
|
end
|
13
12
|
|
14
13
|
it "should not create list if invalid" do
|
@@ -41,21 +40,22 @@ describe Sendicate::List do
|
|
41
40
|
end
|
42
41
|
|
43
42
|
it "should not find invalid list" do
|
44
|
-
lambda { Sendicate::List.find(
|
43
|
+
lambda { Sendicate::List.find('bogus') }.should raise_error(Sendicate::ResourceNotFound)
|
45
44
|
end
|
46
45
|
end
|
47
46
|
|
48
47
|
describe "save" do
|
49
|
-
let(:list_id) { Sendicate::List.all.select{|l| l.title == 'Test list'}.first.id }
|
50
48
|
|
51
49
|
it "should update list" do
|
52
|
-
list = Sendicate::List.
|
50
|
+
list = Sendicate::List.new(title: "Test list")
|
51
|
+
list.save
|
53
52
|
list.title = "Test list updated"
|
54
53
|
list.save.should be_true
|
55
54
|
end
|
56
55
|
|
57
56
|
it "should not update list if invalid" do
|
58
|
-
list = Sendicate::List.
|
57
|
+
list = Sendicate::List.new(title: "Test list")
|
58
|
+
list.save
|
59
59
|
list.title = ""
|
60
60
|
list.save.should be_false
|
61
61
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sendicate::Subscriber do
|
4
|
+
let(:email) { 'user@example.com' }
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
list = Sendicate::List.new(title: 'Test')
|
8
|
+
list.save
|
9
|
+
import = Sendicate::Import.new(
|
10
|
+
list_id: list.id,
|
11
|
+
data: {
|
12
|
+
email: 'user@example.com'
|
13
|
+
}
|
14
|
+
)
|
15
|
+
import.save
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:all) do
|
19
|
+
Sendicate::List.all.each do |list|
|
20
|
+
if list.title == 'Test'
|
21
|
+
list.destroy
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "find" do
|
27
|
+
|
28
|
+
it "should find subscriber" do
|
29
|
+
subscriber = Sendicate::Subscriber.find(email)
|
30
|
+
subscriber.email.should == email
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should not find invalid list" do
|
34
|
+
lambda { Sendicate::Subscriber.find('bogus@example.com') }.should raise_error(Sendicate::ResourceNotFound)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "save" do
|
39
|
+
|
40
|
+
it "should update subscriber" do
|
41
|
+
subscriber = Sendicate::Subscriber.find(email)
|
42
|
+
subscriber.email = 'anotheruser@example.com'
|
43
|
+
subscriber.save.should be_true
|
44
|
+
subscriber.email = email
|
45
|
+
subscriber.save
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should not update subscriber if invalid" do
|
49
|
+
subscriber = Sendicate::Subscriber.find(email)
|
50
|
+
subscriber.email = ""
|
51
|
+
subscriber.save.should be_false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'unsubscribe' do
|
56
|
+
|
57
|
+
it "should unsubscribe subscriber" do
|
58
|
+
Sendicate::Subscriber.unsubscribe(email).should be_true
|
59
|
+
subscriber = Sendicate::Subscriber.find(email)
|
60
|
+
subscriber.subscribed.should == false
|
61
|
+
subscriber.unsubscribed_at.should_not be_nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sendicate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
@@ -127,9 +127,12 @@ files:
|
|
127
127
|
- lib/sendicate/import.rb
|
128
128
|
- lib/sendicate/list.rb
|
129
129
|
- lib/sendicate/request.rb
|
130
|
+
- lib/sendicate/resource.rb
|
131
|
+
- lib/sendicate/subscriber.rb
|
130
132
|
- sendicate.gemspec
|
131
133
|
- spec/sendicate/import_spec.rb
|
132
134
|
- spec/sendicate/list_spec.rb
|
135
|
+
- spec/sendicate/subscriber_spec.rb
|
133
136
|
- spec/sendicate_spec.rb
|
134
137
|
- spec/spec_helper.rb
|
135
138
|
homepage: http://github.com/evanwhalen/sendicate-ruby
|
@@ -147,7 +150,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
150
|
version: '0'
|
148
151
|
segments:
|
149
152
|
- 0
|
150
|
-
hash: -
|
153
|
+
hash: -702026301068380783
|
151
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
155
|
none: false
|
153
156
|
requirements:
|