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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -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
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -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
@@ -0,0 +1,3 @@
1
+ require 'dotmailer/exceptions'
2
+ require 'dotmailer/data_field'
3
+ require 'dotmailer/client'
@@ -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,4 @@
1
+ module Dotmailer
2
+ class DuplicateDataField < Exception
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module Dotmailer
2
+ VERSION = "0.0.1"
3
+ 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
@@ -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: []