dotmailer 0.0.1
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/.gitignore +4 -0
- data/Gemfile +3 -0
- data/README.md +51 -0
- data/Rakefile +1 -0
- data/dotmailer.gemspec +24 -0
- data/lib/dotmailer.rb +3 -0
- data/lib/dotmailer/client.rb +78 -0
- data/lib/dotmailer/data_field.rb +38 -0
- data/lib/dotmailer/exceptions.rb +4 -0
- data/lib/dotmailer/version.rb +3 -0
- data/spec/dotmailer/client_spec.rb +159 -0
- data/spec/dotmailer/data_field_spec.rb +32 -0
- data/spec/spec_helper.rb +22 -0
- metadata +106 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
dotMailer
|
2
|
+
=========
|
3
|
+
|
4
|
+
[dotMailer](http://www.dotmailer.co.uk/) provide both a REST and SOAP API for interacting with their system. The REST API supports both XML and JSON payloads.
|
5
|
+
|
6
|
+
This gem provides a Ruby wrapper allowing you to access the REST API, and uses JSON payloads.
|
7
|
+
|
8
|
+
For a full description of the API, see https://api.dotmailer.com
|
9
|
+
|
10
|
+
Installation
|
11
|
+
------------
|
12
|
+
|
13
|
+
To install as a standalone gem:
|
14
|
+
|
15
|
+
gem install dotmailer
|
16
|
+
|
17
|
+
To install as part of a project managed by bundler, add to your Gemfile:
|
18
|
+
|
19
|
+
gem 'dotmailer'
|
20
|
+
|
21
|
+
Usage
|
22
|
+
-----
|
23
|
+
|
24
|
+
Use the `Dotmailer::Client` class to access the dotMailer REST API.
|
25
|
+
|
26
|
+
You must initialize the Client with an API user and password (see [here](http://www.dotmailer.co.uk/api/more_about_api/getting_started_with_the_api.aspx) for instructions on obtaining these):
|
27
|
+
|
28
|
+
client = Dotmailer::Client.new('your-api-username', 'your-api-password')
|
29
|
+
|
30
|
+
Data Fields
|
31
|
+
-----------
|
32
|
+
|
33
|
+
### List
|
34
|
+
|
35
|
+
`Dotmailer::Client#get_data_fields` will return an Array of `Dotmailer::DataField` objects representing the data fields for the global address book:
|
36
|
+
|
37
|
+
client.get_data_fields
|
38
|
+
=> [
|
39
|
+
Dotmailer::DataField name: "FIELD1", type: "String", visibility: "Public", default: "",
|
40
|
+
Dotmailer::DataField name: "FIELD2", type: "Numeric", visibility: "Private", default: 0
|
41
|
+
]
|
42
|
+
|
43
|
+
### Create
|
44
|
+
|
45
|
+
`Dotmailer::Client#create_data_field` will attempt to create a new data field. On success it returns true, on failure it raises an exception:
|
46
|
+
|
47
|
+
client.create_data_field 'FIELD3', :type => 'String'
|
48
|
+
=> true
|
49
|
+
|
50
|
+
client.create_data_field 'FIELD3', :type => 'String'
|
51
|
+
=> Dotmailer::DuplicateDataField
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/dotmailer.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dotmailer/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "dotmailer"
|
7
|
+
s.version = Dotmailer::VERSION
|
8
|
+
s.authors = ["Econsultancy"]
|
9
|
+
s.email = ["tech@econsultancy.com"]
|
10
|
+
s.homepage = "https://github.com/econsultancy/dotmailer"
|
11
|
+
s.summary = %q{A Ruby wrapper around the dotMailer REST API: https://apiconnector.com/v2/help/wadl}
|
12
|
+
|
13
|
+
s.rubyforge_project = "dotmailer"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_runtime_dependency 'rest-client'
|
21
|
+
|
22
|
+
s.add_development_dependency 'rspec'
|
23
|
+
s.add_development_dependency 'webmock'
|
24
|
+
end
|
data/lib/dotmailer.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'json'
|
3
|
+
require 'csv'
|
4
|
+
require 'restclient'
|
5
|
+
|
6
|
+
module Dotmailer
|
7
|
+
class Client
|
8
|
+
def initialize(api_user, api_pass)
|
9
|
+
self.api_user = api_user
|
10
|
+
self.api_pass = api_pass
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_data_fields
|
14
|
+
fields = get 'data-fields'
|
15
|
+
|
16
|
+
fields.map { |attributes| DataField.new(attributes) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_data_field(name, options = {})
|
20
|
+
options[:type] ||= 'String'
|
21
|
+
options[:visibility] ||= 'Public'
|
22
|
+
|
23
|
+
post_json(
|
24
|
+
'data-fields',
|
25
|
+
'name' => name,
|
26
|
+
'type' => options[:type],
|
27
|
+
'visibility' => options[:visibility],
|
28
|
+
'defaultValue' => options[:default]
|
29
|
+
)
|
30
|
+
|
31
|
+
true
|
32
|
+
rescue RestClient::BadRequest
|
33
|
+
raise DuplicateDataField
|
34
|
+
end
|
35
|
+
|
36
|
+
def import_contacts(headers, contacts)
|
37
|
+
csv = CSV.generate do |csv|
|
38
|
+
csv << headers
|
39
|
+
|
40
|
+
contacts.each do |contact|
|
41
|
+
csv << headers.map { |header| contact[header] }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
post 'contacts/import', csv, :content_type => :csv
|
46
|
+
end
|
47
|
+
|
48
|
+
def import_status(import_id)
|
49
|
+
response = get "contacts/import/#{import_id}"
|
50
|
+
|
51
|
+
response['status']
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
attr_accessor :api_user, :api_pass
|
56
|
+
|
57
|
+
def get(path)
|
58
|
+
JSON.parse RestClient.get url(path), :accept => :json
|
59
|
+
end
|
60
|
+
|
61
|
+
def post_json(path, params)
|
62
|
+
post path, params.to_json, :content_type => :json
|
63
|
+
end
|
64
|
+
|
65
|
+
def post(path, data, options = {})
|
66
|
+
JSON.parse RestClient.post url(path), data, options.merge(:accept => :json)
|
67
|
+
end
|
68
|
+
|
69
|
+
def url(path)
|
70
|
+
URI::Generic.build(
|
71
|
+
:scheme => 'https',
|
72
|
+
:userinfo => "#{CGI.escape(api_user)}:#{api_pass}",
|
73
|
+
:host => 'api.dotmailer.com',
|
74
|
+
:path => "/v2/#{path}"
|
75
|
+
).to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Dotmailer
|
2
|
+
class DataField
|
3
|
+
def initialize(attributes)
|
4
|
+
self.attributes = attributes
|
5
|
+
end
|
6
|
+
|
7
|
+
def name
|
8
|
+
attributes['name']
|
9
|
+
end
|
10
|
+
|
11
|
+
def type
|
12
|
+
attributes['type']
|
13
|
+
end
|
14
|
+
|
15
|
+
def visibility
|
16
|
+
attributes['visibility']
|
17
|
+
end
|
18
|
+
|
19
|
+
def default
|
20
|
+
attributes['defaultValue']
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_json(options = {})
|
24
|
+
attributes.to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
%{#{self.class.name} name: "#{name}", type: "#{type}", visibility: "#{visibility}", default: "#{default}"}
|
29
|
+
end
|
30
|
+
|
31
|
+
def ==(other)
|
32
|
+
attributes == other.attributes
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
attr_accessor :attributes
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotmailer::Client do
|
4
|
+
let(:api_user) { 'john_doe' }
|
5
|
+
let(:api_pass) { 's3cr3t' }
|
6
|
+
let(:api_base_url) { "https://#{api_user}:#{api_pass}@api.dotmailer.com" }
|
7
|
+
|
8
|
+
subject { Dotmailer::Client.new(api_user, api_pass) }
|
9
|
+
|
10
|
+
context 'data fields' do
|
11
|
+
let(:data_fields_endpoint) do
|
12
|
+
"#{api_base_url}/v2/data-fields"
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#get_data_fields' do
|
16
|
+
let(:data_fields) do
|
17
|
+
[
|
18
|
+
Dotmailer::DataField.new(
|
19
|
+
'name' => 'FIRSTNAME',
|
20
|
+
'type' => 'String',
|
21
|
+
'visibility' => 'Public',
|
22
|
+
'defaultValue' => 'John'
|
23
|
+
),
|
24
|
+
Dotmailer::DataField.new(
|
25
|
+
'name' => 'CODE',
|
26
|
+
'type' => 'String',
|
27
|
+
'visibility' => 'Private',
|
28
|
+
'defaultValue' => nil
|
29
|
+
)
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
33
|
+
before(:each) do
|
34
|
+
stub_request(:get, data_fields_endpoint).to_return(:body => data_fields.to_json)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should get the fields from the data fields endpoint' do
|
38
|
+
subject.get_data_fields
|
39
|
+
|
40
|
+
WebMock.should have_requested(:get, data_fields_endpoint).with(
|
41
|
+
:headers => { 'Accept' => 'application/json' }
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should return the data fields from the data fields endpoint' do
|
46
|
+
subject.get_data_fields.should == data_fields
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#create_data_field' do
|
51
|
+
let(:name) { 'FIRSTNAME' }
|
52
|
+
|
53
|
+
let(:data_field_json) do
|
54
|
+
{
|
55
|
+
'name' => name,
|
56
|
+
'type' => 'String',
|
57
|
+
'visibility' => 'Public',
|
58
|
+
'defaultValue' => nil
|
59
|
+
}.to_json
|
60
|
+
end
|
61
|
+
|
62
|
+
before(:each) do
|
63
|
+
stub_request(:post, data_fields_endpoint).to_return(:body => data_field_json)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should post the field to the data fields endpoint' do
|
67
|
+
subject.create_data_field name
|
68
|
+
|
69
|
+
WebMock.should have_requested(:post, data_fields_endpoint).with(
|
70
|
+
:body => data_field_json,
|
71
|
+
:headers => {
|
72
|
+
'Accept' => 'application/json',
|
73
|
+
'Content-Type' => 'application/json'
|
74
|
+
}
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when the field doesnt exist' do
|
79
|
+
it 'should return true' do
|
80
|
+
subject.create_data_field(name).should == true
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'when the field already exists' do
|
85
|
+
before(:each) do
|
86
|
+
stub_request(:post, data_fields_endpoint).to_return(:status => 400)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should raise an error' do
|
90
|
+
expect { subject.create_data_field(name) }.to raise_error(Dotmailer::DuplicateDataField)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'contacts' do
|
97
|
+
describe '#import_contacts' do
|
98
|
+
let(:contact_import_endpoint) do
|
99
|
+
"#{api_base_url}/v2/contacts/import"
|
100
|
+
end
|
101
|
+
|
102
|
+
let(:headers) { ['Email'] }
|
103
|
+
|
104
|
+
let(:contacts) do
|
105
|
+
[
|
106
|
+
{ 'Email' => 'john.doe@example.com' }
|
107
|
+
]
|
108
|
+
end
|
109
|
+
|
110
|
+
let(:contacts_csv) { "Email\njohn.doe@example.com\n" }
|
111
|
+
|
112
|
+
let(:response) { { 'id' => '123', 'status' => 'Finished' } }
|
113
|
+
|
114
|
+
before(:each) do
|
115
|
+
stub_request(:post, contact_import_endpoint).to_return(:body => response.to_json)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should post the contacts in CSV format to the contact import endpoint' do
|
119
|
+
subject.import_contacts ['Email'], contacts
|
120
|
+
|
121
|
+
WebMock.should have_requested(:post, contact_import_endpoint).with(
|
122
|
+
:body => contacts_csv,
|
123
|
+
:headers => {
|
124
|
+
'Accept' => 'application/json',
|
125
|
+
'Content-Type' => 'text/csv'
|
126
|
+
}
|
127
|
+
)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#import_status' do
|
132
|
+
let(:import_id) { 123 }
|
133
|
+
|
134
|
+
let(:import_status_endpoint) do
|
135
|
+
"#{api_base_url}/v2/contacts/import/#{import_id}"
|
136
|
+
end
|
137
|
+
|
138
|
+
let(:status) { 'Finished' }
|
139
|
+
|
140
|
+
let(:response) { { 'id' => import_id, 'status' => status } }
|
141
|
+
|
142
|
+
before(:each) do
|
143
|
+
stub_request(:get, import_status_endpoint).to_return(:body => response.to_json )
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should get the import status from the import status endpoint' do
|
147
|
+
subject.import_status import_id
|
148
|
+
|
149
|
+
WebMock.should have_requested(:get, import_status_endpoint).with(
|
150
|
+
:headers => { 'Accept' => 'application/json' }
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should return the status from the import status endpoint' do
|
155
|
+
subject.import_status(import_id).should == status
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotmailer::DataField do
|
4
|
+
let(:name) { 'FIRSTNAME' }
|
5
|
+
let(:type) { 'String' }
|
6
|
+
let(:visibility) { 'Public' }
|
7
|
+
let(:default) { 'John' }
|
8
|
+
|
9
|
+
let(:attributes) do
|
10
|
+
{
|
11
|
+
'name' => name,
|
12
|
+
'type' => type,
|
13
|
+
'visibility' => visibility,
|
14
|
+
'defaultValue' => default
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
subject { Dotmailer::DataField.new(attributes) }
|
19
|
+
|
20
|
+
its(:name) { should == name }
|
21
|
+
its(:type) { should == type }
|
22
|
+
its(:visibility) { should == visibility }
|
23
|
+
its(:default) { should == default }
|
24
|
+
|
25
|
+
its(:to_s) { should == 'Dotmailer::DataField name: "FIRSTNAME", type: "String", visibility: "Public", default: "John"' }
|
26
|
+
|
27
|
+
its(:to_json) { should == attributes.to_json }
|
28
|
+
|
29
|
+
describe '#==' do
|
30
|
+
specify { subject.should == Dotmailer::DataField.new(attributes) }
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
require 'webmock/rspec'
|
9
|
+
|
10
|
+
require 'dotmailer'
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
14
|
+
config.run_all_when_everything_filtered = true
|
15
|
+
config.filter_run :focus
|
16
|
+
|
17
|
+
# Run specs in random order to surface order dependencies. If you find an
|
18
|
+
# order dependency and want to debug it, you can fix the order by providing
|
19
|
+
# the seed, which is printed after each run.
|
20
|
+
# --seed 1234
|
21
|
+
config.order = 'random'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dotmailer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Econsultancy
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: webmock
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description:
|
63
|
+
email:
|
64
|
+
- tech@econsultancy.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- Gemfile
|
71
|
+
- README.md
|
72
|
+
- Rakefile
|
73
|
+
- dotmailer.gemspec
|
74
|
+
- lib/dotmailer.rb
|
75
|
+
- lib/dotmailer/client.rb
|
76
|
+
- lib/dotmailer/data_field.rb
|
77
|
+
- lib/dotmailer/exceptions.rb
|
78
|
+
- lib/dotmailer/version.rb
|
79
|
+
- spec/dotmailer/client_spec.rb
|
80
|
+
- spec/dotmailer/data_field_spec.rb
|
81
|
+
- spec/spec_helper.rb
|
82
|
+
homepage: https://github.com/econsultancy/dotmailer
|
83
|
+
licenses: []
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project: dotmailer
|
102
|
+
rubygems_version: 1.8.23
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: ! 'A Ruby wrapper around the dotMailer REST API: https://apiconnector.com/v2/help/wadl'
|
106
|
+
test_files: []
|