createsend 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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