createsend 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.
Files changed (55) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +3 -0
  3. data/README.md +3 -0
  4. data/Rakefile +23 -0
  5. data/config.example.yaml +2 -0
  6. data/createsend.gemspec +26 -0
  7. data/lib/campaign.rb +90 -0
  8. data/lib/client.rb +117 -0
  9. data/lib/createsend.rb +103 -0
  10. data/lib/list.rb +99 -0
  11. data/lib/subscriber.rb +49 -0
  12. data/lib/template.rb +38 -0
  13. data/test/campaign_test.rb +98 -0
  14. data/test/client_test.rb +107 -0
  15. data/test/createsend_test.rb +96 -0
  16. data/test/fixtures/active_subscribers.json +67 -0
  17. data/test/fixtures/add_subscriber.json +1 -0
  18. data/test/fixtures/apikey.json +3 -0
  19. data/test/fixtures/bounced_subscribers.json +9 -0
  20. data/test/fixtures/campaign_bounces.json +16 -0
  21. data/test/fixtures/campaign_clicks.json +23 -0
  22. data/test/fixtures/campaign_lists.json +10 -0
  23. data/test/fixtures/campaign_opens.json +32 -0
  24. data/test/fixtures/campaign_summary.json +9 -0
  25. data/test/fixtures/campaign_unsubscribes.json +9 -0
  26. data/test/fixtures/campaigns.json +18 -0
  27. data/test/fixtures/client_details.json +25 -0
  28. data/test/fixtures/clients.json +10 -0
  29. data/test/fixtures/countries.json +247 -0
  30. data/test/fixtures/create_campaign.json +1 -0
  31. data/test/fixtures/create_client.json +1 -0
  32. data/test/fixtures/create_custom_field.json +1 -0
  33. data/test/fixtures/create_list.json +1 -0
  34. data/test/fixtures/create_template.json +1 -0
  35. data/test/fixtures/custom_api_error.json +4 -0
  36. data/test/fixtures/custom_fields.json +20 -0
  37. data/test/fixtures/drafts.json +14 -0
  38. data/test/fixtures/import_subscribers.json +7 -0
  39. data/test/fixtures/list_details.json +7 -0
  40. data/test/fixtures/list_stats.json +26 -0
  41. data/test/fixtures/lists.json +10 -0
  42. data/test/fixtures/segments.json +10 -0
  43. data/test/fixtures/subscriber_details.json +20 -0
  44. data/test/fixtures/subscriber_history.json +45 -0
  45. data/test/fixtures/suppressionlist.json +12 -0
  46. data/test/fixtures/systemdate.json +3 -0
  47. data/test/fixtures/template_details.json +6 -0
  48. data/test/fixtures/templates.json +14 -0
  49. data/test/fixtures/timezones.json +99 -0
  50. data/test/fixtures/unsubscribed_subscribers.json +21 -0
  51. data/test/helper.rb +36 -0
  52. data/test/list_test.rb +107 -0
  53. data/test/subscriber_test.rb +73 -0
  54. data/test/template_test.rb +38 -0
  55. metadata +256 -0
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .DS_Store
2
+ config.yaml
3
+ config.jdennes.yaml
4
+ rdoc
5
+ pkg
6
+ *.gem
7
+ example.rb
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # createsend
2
+
3
+ A wrapper for the createsend API v3.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ require "bundler/version"
3
+ require "shoulda/tasks"
4
+ require 'lib/createsend'
5
+
6
+ require "rake/testtask"
7
+ Rake::TestTask.new(:test) do |test|
8
+ test.ruby_opts = ["-rubygems"] if defined? Gem
9
+ test.libs << "lib" << "test"
10
+ test.pattern = "test/**/*_test.rb"
11
+ end
12
+
13
+ desc "Build the gem"
14
+ task :build do
15
+ system "gem build createsend.gemspec"
16
+ end
17
+
18
+ desc "Build and release the gem"
19
+ task :release => :build do
20
+ system "gem push createsend-#{CreateSend::VER}.gem"
21
+ end
22
+
23
+ task :default => :test
@@ -0,0 +1,2 @@
1
+ base_uri: 'http://api.createsend.com/api/v3'
2
+ api_key: 'your_api_key'
@@ -0,0 +1,26 @@
1
+ require 'bundler'
2
+ require 'bundler/version'
3
+
4
+ require File.expand_path('lib/createsend')
5
+
6
+ Gem::Specification.new do |s|
7
+ s.add_development_dependency('fakeweb', '~> 1.3')
8
+ s.add_development_dependency('jnunemaker-matchy', '~> 0.4.0')
9
+ s.add_development_dependency('mocha', '~> 0.9')
10
+ s.add_development_dependency('shoulda', '~> 2.11')
11
+ s.add_runtime_dependency('hashie', '~> 0.4.0')
12
+ s.add_runtime_dependency('httparty', '~> 0.6.1')
13
+ s.name = "createsend"
14
+ s.author = "James Dennes"
15
+ s.description = %q{A wrapper for the CreateSend API v3}
16
+ s.email = ["jdennes@gmail.com"]
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
18
+ s.files = `git ls-files`.split("\n")
19
+ s.homepage = "http://github.com/campaignmonitor/createsend-ruby/"
20
+ s.require_paths = ["lib"]
21
+ s.summary = %q{Wrapper for the CreateSend API v3}
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.version = CreateSend::VER
24
+ s.platform = Gem::Platform::RUBY
25
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
26
+ end
data/lib/campaign.rb ADDED
@@ -0,0 +1,90 @@
1
+ require 'createsend'
2
+ require 'json'
3
+
4
+ class Campaign
5
+ attr_reader :campaign_id
6
+
7
+ def initialize(campaign_id)
8
+ @campaign_id = campaign_id
9
+ end
10
+
11
+ def self.create(client_id, subject, name, from_name, from_email, reply_to, html_url,
12
+ text_url, list_ids, segments)
13
+ options = { :body => {
14
+ :Subject => subject,
15
+ :Name => name,
16
+ :FromName => from_name,
17
+ :FromEmail => from_email,
18
+ :ReplyTo => reply_to,
19
+ :HtmlUrl => html_url,
20
+ :TextUrl => text_url,
21
+ :ListIDs => list_ids ,
22
+ :Segments => segments }.to_json }
23
+ response = CreateSend.post "/campaigns/#{client_id}.json", options
24
+ response.parsed_response
25
+ end
26
+
27
+ def send(confirmation_email, send_date="immediately")
28
+ options = { :body => {
29
+ :ConfirmationEmail => confirmation_email,
30
+ :SendDate => send_date }.to_json }
31
+ response = post "send", options
32
+ end
33
+
34
+ def delete
35
+ response = CreateSend.delete "/campaigns/#{campaign_id}.json", {}
36
+ end
37
+
38
+ def summary
39
+ response = get "summary", {}
40
+ Hashie::Mash.new(response)
41
+ end
42
+
43
+ def lists
44
+ response = get "lists", {}
45
+ response.map{|item| Hashie::Mash.new(item)}
46
+ end
47
+
48
+ def segments
49
+ # TODO: This needs to be implemented
50
+ []
51
+ end
52
+
53
+ def opens(date)
54
+ options = { :query => { :date => date } }
55
+ response = get "opens", options
56
+ response.map{|item| Hashie::Mash.new(item)}
57
+ end
58
+
59
+ def clicks(date)
60
+ options = { :query => { :date => date } }
61
+ response = get "clicks", options
62
+ response.map{|item| Hashie::Mash.new(item)}
63
+ end
64
+
65
+ def unsubscribes(date)
66
+ options = { :query => { :date => date } }
67
+ response = get "unsubscribes", options
68
+ response.map{|item| Hashie::Mash.new(item)}
69
+ end
70
+
71
+ def bounces
72
+ response = get "bounces", {}
73
+ response.map{|item| Hashie::Mash.new(item)}
74
+ end
75
+
76
+ private
77
+
78
+ def get(action, options = {})
79
+ CreateSend.get uri_for(action), options
80
+ end
81
+
82
+ def post(action, options = {})
83
+ CreateSend.post uri_for(action), options
84
+ end
85
+
86
+ def uri_for(action)
87
+ "/campaigns/#{campaign_id}/#{action}.json"
88
+ end
89
+
90
+ end
data/lib/client.rb ADDED
@@ -0,0 +1,117 @@
1
+ require 'createsend'
2
+ require 'json'
3
+
4
+ class Client
5
+ attr_reader :client_id
6
+
7
+ def initialize(client_id)
8
+ @client_id = client_id
9
+ end
10
+
11
+ def self.create(company, contact_name, email, timezone, country)
12
+ options = { :body => {
13
+ :CompanyName => company,
14
+ :ContactName => contact_name,
15
+ :EmailAddress => email,
16
+ :TimeZone => timezone,
17
+ :Country => country }.to_json }
18
+ CreateSend.post "/clients.json", options
19
+ end
20
+
21
+ def details
22
+ response = CreateSend.get "/clients/#{client_id}.json", {}
23
+ Hashie::Mash.new(response)
24
+ end
25
+
26
+ def campaigns
27
+ response = get 'campaigns'
28
+ response.map{|item| Hashie::Mash.new(item)}
29
+ end
30
+
31
+ def drafts
32
+ response = get 'drafts'
33
+ response.map{|item| Hashie::Mash.new(item)}
34
+ end
35
+
36
+ def lists
37
+ response = get 'lists'
38
+ response.map{|item| Hashie::Mash.new(item)}
39
+ end
40
+
41
+ def segments
42
+ response = get 'segments'
43
+ response.map{|item| Hashie::Mash.new(item)}
44
+ end
45
+
46
+ def suppressionlist
47
+ response = get 'suppressionlist'
48
+ response.map{|item| Hashie::Mash.new(item)}
49
+ end
50
+
51
+ def templates
52
+ response = get 'templates'
53
+ response.map{|item| Hashie::Mash.new(item)}
54
+ end
55
+
56
+ def set_basics(company, contact_name, email, timezone, country)
57
+ options = { :body => {
58
+ :CompanyName => company,
59
+ :ContactName => contact_name,
60
+ :EmailAddress => email,
61
+ :TimeZone => timezone,
62
+ :Country => country }.to_json }
63
+ put 'setbasics', options
64
+ end
65
+
66
+ def set_access(username, password, access_level)
67
+ options = { :body => {
68
+ :Username => username,
69
+ :Password => password,
70
+ :AccessLevel => access_level }.to_json }
71
+ put 'setaccess', options
72
+ end
73
+
74
+ def set_payg_billing(currency, can_purchase_credits, client_pays, markup_percentage,
75
+ markup_on_delivery=0, markup_per_recipient=0, markup_on_design_spam_test=0)
76
+ options = { :body => {
77
+ :Currency => currency,
78
+ :CanPurchaseCredits => can_purchase_credits,
79
+ :ClientPays => client_pays,
80
+ :MarkupPercentage => markup_percentage,
81
+ :MarkupOnDelivery => markup_on_delivery,
82
+ :MarkupPerRecipient => markup_per_recipient,
83
+ :MarkupOnDesignSpamTest => markup_on_design_spam_test }.to_json }
84
+ put 'setpaygbilling', options
85
+ end
86
+
87
+ def set_monthly_billing(currency, can_purchase_credits, client_pays, markup_percentage)
88
+ options = { :body => {
89
+ :Currency => currency,
90
+ :CanPurchaseCredits => can_purchase_credits,
91
+ :ClientPays => client_pays,
92
+ :MarkupPercentage => markup_percentage }.to_json }
93
+ put 'setmonthlybilling', options
94
+ end
95
+
96
+ def delete
97
+ CreateSend.delete "/clients/#{client_id}.json", {}
98
+ end
99
+
100
+ private
101
+
102
+ def get(action, options = {})
103
+ CreateSend.get uri_for(action), options
104
+ end
105
+
106
+ def post(action, options = {})
107
+ CreateSend.post uri_for(action), options
108
+ end
109
+
110
+ def put(action, options = {})
111
+ CreateSend.put uri_for(action), options
112
+ end
113
+
114
+ def uri_for(action)
115
+ "/clients/#{client_id}/#{action}.json"
116
+ end
117
+ end
data/lib/createsend.rb ADDED
@@ -0,0 +1,103 @@
1
+ require 'cgi'
2
+ require 'uri'
3
+ require 'httparty'
4
+ require 'hashie'
5
+ Hash.send :include, Hashie::HashExtensions
6
+
7
+ CreateSendOptions = { 'api_key' => nil, 'base_uri' => "http://api.createsend.com/api/v3" } if not Object.const_defined? :CreateSendOptions # :nodoc:
8
+ if File.exists?('config.yaml')
9
+ config = YAML.load_file('config.yaml')
10
+ CreateSendOptions['base_uri'] = config['base_uri']
11
+ CreateSendOptions['api_key'] = config['api_key']
12
+ end
13
+
14
+ libdir = File.dirname(__FILE__)
15
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
16
+
17
+ require 'client'
18
+ require 'campaign'
19
+ require 'list'
20
+ require 'subscriber'
21
+ require 'template'
22
+
23
+ class CreateSendError < StandardError
24
+ attr_reader :data
25
+ def initialize(data)
26
+ @data = data
27
+ super "The CreateSend API responded with the following error - #{@data.Code}: #{@data.Message}"
28
+ end
29
+ end
30
+
31
+ class ClientError < StandardError; end
32
+ class ServerError < StandardError; end
33
+ class BadRequest < CreateSendError; end
34
+ class Unauthorized < ClientError; end
35
+ class NotFound < ClientError; end
36
+ class Unavailable < StandardError; end
37
+
38
+ class CreateSend
39
+ include HTTParty
40
+ headers 'Content-Type' => 'application/json'
41
+ base_uri CreateSendOptions['base_uri']
42
+ basic_auth CreateSendOptions['api_key'], 'x'
43
+
44
+ VER = "0.0.1" unless defined?(CreateSend::VER)
45
+
46
+ def self.api_key(api_key=nil)
47
+ return @@api_key unless api_key
48
+ CreateSendOptions['api_key'] = api_key
49
+ @@api_key = api_key
50
+ basic_auth @@api_key, 'x'
51
+ end
52
+
53
+ def apikey(site_url, username, password)
54
+ site_url = CGI.escape(site_url)
55
+ self.class.basic_auth username, password
56
+ response = CreateSend.get("/apikey.json?SiteUrl=#{site_url}")
57
+ # Revert basic_auth to use @@api_key, 'x'
58
+ self.class.basic_auth @@api_key, 'x'
59
+ Hashie::Mash.new(response)
60
+ end
61
+
62
+ def clients
63
+ response = CreateSend.get('/clients.json')
64
+ response.map{|item| Hashie::Mash.new(item)}
65
+ end
66
+
67
+ def countries
68
+ response = CreateSend.get('/countries.json')
69
+ response.parsed_response
70
+ end
71
+
72
+ def systemdate
73
+ response = CreateSend.get('/systemdate.json')
74
+ Hashie::Mash.new(response)
75
+ end
76
+
77
+ def timezones
78
+ response = CreateSend.get('/timezones.json')
79
+ response.parsed_response
80
+ end
81
+
82
+ def self.get(*args); handle_response super end
83
+ def self.post(*args); handle_response super end
84
+ def self.put(*args); handle_response super end
85
+ def self.delete(*args); handle_response super end
86
+
87
+ def self.handle_response(response)
88
+ case response.code
89
+ when 400
90
+ raise BadRequest.new(Hashie::Mash.new response)
91
+ when 401
92
+ raise Unauthorized.new
93
+ when 404
94
+ raise NotFound.new
95
+ when 400...500
96
+ raise ClientError.new
97
+ when 500...600
98
+ raise ServerError.new
99
+ else
100
+ response
101
+ end
102
+ end
103
+ end
data/lib/list.rb ADDED
@@ -0,0 +1,99 @@
1
+ require 'createsend'
2
+ require 'json'
3
+
4
+ class List
5
+ attr_reader :list_id
6
+
7
+ def initialize(list_id)
8
+ @list_id = list_id
9
+ end
10
+
11
+ def self.create(client_id, title, unsubscribe_page, confirmed_opt_in, confirmation_success_page)
12
+ options = { :body => {
13
+ :Title => title,
14
+ :UnsubscribePage => unsubscribe_page,
15
+ :ConfirmedOptIn => confirmed_opt_in,
16
+ :ConfirmationSuccessPage => confirmation_success_page }.to_json }
17
+ response = CreateSend.post "/lists/#{client_id}.json", options
18
+ response.parsed_response
19
+ end
20
+
21
+ def delete
22
+ response = CreateSend.delete "/lists/#{list_id}.json", {}
23
+ end
24
+
25
+ def create_custom_field(field_name, data_type, options=[])
26
+ options = { :body => {
27
+ :FieldName => field_name,
28
+ :DataType => data_type,
29
+ :Options => options }.to_json }
30
+ response = post "customfields", options
31
+ response.parsed_response
32
+ end
33
+
34
+ def delete_custom_field(custom_field_key)
35
+ custom_field_key = CGI.escape(custom_field_key)
36
+ response = CreateSend.delete "/lists/#{list_id}/customfields/#{custom_field_key}.json", {}
37
+ end
38
+
39
+ def details
40
+ response = CreateSend.get "/lists/#{list_id}.json", {}
41
+ Hashie::Mash.new(response)
42
+ end
43
+
44
+ def custom_fields
45
+ response = get "customfields"
46
+ response.map{|item| Hashie::Mash.new(item)}
47
+ end
48
+
49
+ def stats
50
+ response = get "stats"
51
+ Hashie::Mash.new(response)
52
+ end
53
+
54
+ def active(date)
55
+ options = { :query => { :date => date } }
56
+ response = get "active", options
57
+ response.map{|item| Hashie::Mash.new(item)}
58
+ end
59
+
60
+ def bounced(date)
61
+ options = { :query => { :date => date } }
62
+ response = get "bounced", options
63
+ response.map{|item| Hashie::Mash.new(item)}
64
+ end
65
+
66
+ def unsubscribed(date)
67
+ options = { :query => { :date => date } }
68
+ response = get "unsubscribed", options
69
+ response.map{|item| Hashie::Mash.new(item)}
70
+ end
71
+
72
+ def update(title, unsubscribe_page, confirmed_opt_in, confirmation_success_page)
73
+ options = { :body => {
74
+ :Title => title,
75
+ :UnsubscribePage => unsubscribe_page,
76
+ :ConfirmedOptIn => confirmed_opt_in,
77
+ :ConfirmationSuccessPage => confirmation_success_page }.to_json }
78
+ response = CreateSend.put "/lists/#{list_id}.json", options
79
+ end
80
+
81
+ private
82
+
83
+ def get(action, options = {})
84
+ CreateSend.get uri_for(action), options
85
+ end
86
+
87
+ def post(action, options = {})
88
+ CreateSend.post uri_for(action), options
89
+ end
90
+
91
+ def put(action, options = {})
92
+ CreateSend.put uri_for(action), options
93
+ end
94
+
95
+ def uri_for(action)
96
+ "/lists/#{list_id}/#{action}.json"
97
+ end
98
+
99
+ end