emaildirect 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ rdoc
3
+ pkg
4
+ *.gem
5
+ example.rb
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ emaildirect (1.0.0)
5
+ hashie
6
+ httparty
7
+ json
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ hashie (1.2.0)
13
+ httparty (0.8.1)
14
+ multi_json
15
+ multi_xml
16
+ json (1.5.3)
17
+ multi_json (1.0.4)
18
+ multi_xml (0.4.1)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ emaildirect!
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Jason Rust
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,83 @@
1
+ # emaildirect
2
+
3
+ A ruby library which implements the complete functionality of the REST (v5) [Email Direct API](https://docs.emaildirect.com).
4
+
5
+ ## Installation
6
+
7
+ ### Plain ruby
8
+ gem install emaildirect
9
+ require 'emaildirect'
10
+ EmailDirect.api_key 'your_api_key'
11
+
12
+ ### Rails integration
13
+ In your gemfile:
14
+
15
+ gem 'emaildirect'
16
+
17
+ In an initializer:
18
+
19
+ EmailDirect.api_key 'your_api_key'
20
+
21
+ ## Examples
22
+
23
+ ### Retrieve a list of all your publications.
24
+
25
+ EmailDirect::Publication.all.Publications.each do |pub|
26
+ puts "#{pub.PublicationID}: #{pub.Name}"
27
+ end
28
+
29
+ Results in:
30
+
31
+ 1: Publication One
32
+ 2: Publication Two
33
+
34
+ ### Create, then remove a Publication
35
+
36
+ response = EmailDirect::Publication.create('Test', :Description => 'Test Publication')
37
+ sub = EmailDirect::Publication.new(response.publicationID)
38
+ sub.delete
39
+
40
+ ### ActionMailer integration
41
+ You can use send your ActionMailer email through Email Direct using their Relay Send functionality by setting up a new delivery method in an initalizer:
42
+
43
+ ActionMailer::Base.add_delivery_method :emaildirect, EmailDirect::Mailer,
44
+ :category_id => 1,
45
+ :options => { :Force => true }
46
+
47
+ And in your ActionMailer class:
48
+
49
+ defaults :delivery_method => :emaildirect
50
+
51
+ or for just a particular message:
52
+
53
+ def welcome(user) do
54
+ mail :to => user.email,
55
+ :delivery_method => :emaildirect
56
+ end
57
+
58
+ ### Handling errors
59
+ If the emaildirect API returns an error, an exception will be thrown. For example, if you attempt to create a subscriber with an invalid email address:
60
+
61
+ begin
62
+ response = EmailDirect::Subscriber.create('bademail')
63
+ rescue EmailDirect::BadRequest => br
64
+ puts "Bad request error: #{br}"
65
+ puts "Error Code: #{br.data.ErrorCode}"
66
+ puts "Error Message: #{br.data.Message}"
67
+ rescue Exception => e
68
+ puts "Error: #{e}"
69
+ end
70
+
71
+ Results in:
72
+
73
+ Bad request error: The EmailDirect API responded with the following error - 101: Invalid Email Address
74
+ Error Code: 101
75
+ Error Message: Invalid Email Address
76
+
77
+ ### Expected input and output
78
+ The best way of finding out the expected input and output of a particular method in a particular class is to read the [API docs](https://docs.emaildirect.com)
79
+ and take a look at the code for that function.
80
+
81
+ ## Credits
82
+ - Jason Rust
83
+ - [createsend-ruby](https://github.com/campaignmonitor/createsend-ruby) library for inspiration on how to write a decent REST API wrapper.
@@ -0,0 +1,23 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ require "bundler/version"
3
+ require "shoulda/tasks"
4
+ require "rake/testtask"
5
+ require "./lib/emaildirect"
6
+
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 emaildirect.gemspec"
16
+ end
17
+
18
+ desc "Build and release the gem"
19
+ task :release => :build do
20
+ system "gem push emaildirect-#{CreateSend::VERSION}.gem"
21
+ end
22
+
23
+ task :default => :test
@@ -0,0 +1,23 @@
1
+ require 'bundler'
2
+ require 'bundler/version'
3
+
4
+ require File.expand_path('lib/emaildirect/version')
5
+
6
+ Gem::Specification.new do |s|
7
+ s.add_runtime_dependency('json')
8
+ s.add_runtime_dependency('hashie')
9
+ s.add_runtime_dependency('httparty')
10
+ s.name = "emaildirect"
11
+ s.author = "Jason Rust"
12
+ s.description = %q{Implements the complete functionality of the email direct REST API.}
13
+ s.email = ["rustyparts@gmail.com"]
14
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
15
+ s.files = `git ls-files`.split("\n")
16
+ s.homepage = "http://github.com/jrust/emaildirect/"
17
+ s.require_paths = ["lib"]
18
+ s.summary = %q{A library which implements the complete functionality of of the emaildirect REST API (v5).}
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.version = EmailDirect::VERSION
21
+ s.platform = Gem::Platform::RUBY
22
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
23
+ end
@@ -0,0 +1,104 @@
1
+ require 'cgi'
2
+ require 'uri'
3
+ require 'httparty'
4
+ require 'hashie'
5
+ Hash.send :include, Hashie::HashExtensions
6
+
7
+ libdir = File.dirname(__FILE__)
8
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
9
+
10
+ require 'emaildirect/version'
11
+ require 'emaildirect/mailer'
12
+ require 'emaildirect/campaign'
13
+ require 'emaildirect/creative'
14
+ require 'emaildirect/creative_folder'
15
+ require 'emaildirect/database'
16
+ require 'emaildirect/filter'
17
+ require 'emaildirect/image_folder'
18
+ require 'emaildirect/image_file'
19
+ require 'emaildirect/import'
20
+ require 'emaildirect/list'
21
+ require 'emaildirect/relay_send'
22
+ require 'emaildirect/short_url'
23
+ require 'emaildirect/publication'
24
+ require 'emaildirect/source'
25
+ require 'emaildirect/subscriber'
26
+ require 'emaildirect/suppression_list'
27
+ require 'emaildirect/workflow'
28
+
29
+ module EmailDirect
30
+ # Just allows callers to do EmailDirect.api_key "..." rather than EmailDirect::EmailDirect.api_key "..." etc
31
+ class << self
32
+ def api_key(api_key=nil)
33
+ r = EmailDirect.api_key api_key
34
+ end
35
+
36
+ def base_uri(uri)
37
+ r = EmailDirect.base_uri uri
38
+ end
39
+ end
40
+
41
+ # Represents a EmailDirect API error and contains specific data about the error.
42
+ class EmailDirectError < StandardError
43
+ attr_reader :data, :code
44
+ def initialize(data)
45
+ @data = data
46
+ super "The EmailDirect API responded with the following error - #{@data.ErrorCode}: #{@data.Message}"
47
+ end
48
+ end
49
+
50
+ class ClientError < StandardError; end
51
+ class ServerError < StandardError; end
52
+ class BadRequest < EmailDirectError; end
53
+ class Unauthorized < StandardError; end
54
+ class NotFound < ClientError; end
55
+ class Unavailable < StandardError; end
56
+
57
+ class EmailDirect
58
+ include HTTParty
59
+
60
+ @@base_uri = "https://rest.emaildirect.com/v1/"
61
+ @@api_key = ""
62
+ headers({
63
+ 'User-Agent' => "emaildirect-rest-#{VERSION}",
64
+ 'Content-Type' => 'application/json; charset=utf-8',
65
+ 'Accept-Encoding' => 'gzip, deflate' })
66
+ base_uri @@base_uri
67
+ basic_auth 'x', @@api_key
68
+
69
+ # Sets the API key which will be used to make calls to the EmailDirect API.
70
+ def self.api_key(api_key=nil)
71
+ return @@api_key unless api_key
72
+ @@api_key = api_key
73
+ basic_auth 'x', @@api_key
74
+ end
75
+
76
+ # This call returns an object reflecting the current permissions allowed for the provided API Key
77
+ def ping
78
+ response = EmailDirect.get('/Ping')
79
+ Hashie::Mash.new(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) # :nodoc:
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 response.parsed_response
97
+ when 500...600
98
+ raise ServerError.new
99
+ else
100
+ response
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,135 @@
1
+ require 'emaildirect'
2
+ require 'json'
3
+
4
+ module EmailDirect
5
+ # Represents a campaign and associated functionality
6
+ class Campaign
7
+ class << self
8
+ def active(options = {})
9
+ response = EmailDirect.get '/Campaigns', :query => options
10
+ Hashie::Mash.new(response)
11
+ end
12
+
13
+ def drafts(options = {})
14
+ response = EmailDirect.get '/Campaigns/Drafts', :query => options
15
+ Hashie::Mash.new(response)
16
+ end
17
+
18
+ def sent(options = {})
19
+ response = EmailDirect.get '/Campaigns/Sent', :query => options
20
+ Hashie::Mash.new(response)
21
+ end
22
+
23
+ def sending(options = {})
24
+ response = EmailDirect.get '/Campaigns/Sending', :query => options
25
+ Hashie::Mash.new(response)
26
+ end
27
+
28
+ def scheduled(options = {})
29
+ response = EmailDirect.get '/Campaigns/Scheduled', :query => options
30
+ Hashie::Mash.new(response)
31
+ end
32
+
33
+ def all(options = {})
34
+ response = EmailDirect.get '/Campaigns/All', :query => options
35
+ Hashie::Mash.new(response)
36
+ end
37
+
38
+ def create(name, creative_id, subject, from_name, publication_id, options = {})
39
+ options.merge! :Name => name, :CreativeID => creative_id, :Subject => subject, :FromName => from_name, :PublicationID => publication_id
40
+ response = EmailDirect.post '/Campaigns', :body => options.to_json
41
+ Hashie::Mash.new(response)
42
+ end
43
+ end
44
+
45
+ attr_reader :campaign_id
46
+
47
+ def initialize(campaign_id)
48
+ @campaign_id = campaign_id
49
+ end
50
+
51
+ def details
52
+ response = get
53
+ Hashie::Mash.new(response)
54
+ end
55
+
56
+ def message
57
+ response = get 'Email'
58
+ Hashie::Mash.new(response)
59
+ end
60
+
61
+ def links
62
+ response = get 'Links'
63
+ Hashie::Mash.new(response)
64
+ end
65
+
66
+ def recipients(options = {})
67
+ response = get 'Recipients', options
68
+ Hashie::Mash.new(response)
69
+ end
70
+
71
+ def opens(options = {})
72
+ response = get 'Opens', options
73
+ Hashie::Mash.new(response)
74
+ end
75
+
76
+ def clicks(options = {})
77
+ response = get 'Clicks', options
78
+ Hashie::Mash.new(response)
79
+ end
80
+
81
+ def removes(options = {})
82
+ response = get 'Removes', options
83
+ Hashie::Mash.new(response)
84
+ end
85
+
86
+ def complaints(options = {})
87
+ response = get 'Complaints', options
88
+ Hashie::Mash.new(response)
89
+ end
90
+
91
+ def soft_bounces(options = {})
92
+ response = get 'SoftBounces', options
93
+ Hashie::Mash.new(response)
94
+ end
95
+
96
+ def hard_bounces(options = {})
97
+ response = get 'HardBounces', options
98
+ Hashie::Mash.new(response)
99
+ end
100
+
101
+ def update(name, creative_id, subject, from_name, publication_id, options = {})
102
+ options.merge! :Name => name, :CreativeID => creative_id, :Subject => subject, :FromName => from_name, :PublicationID => publication_id
103
+ response = EmailDirect.put uri_for, :body => options.to_json
104
+ Hashie::Mash.new(response)
105
+ end
106
+
107
+ def schedule(schedule_date)
108
+ options = { :CampaignID => campaign_id, :ScheduleDate => schedule_date.strftime('%FT%TZ') }
109
+ response = EmailDirect.post '/Campaigns/Schedule', :body => options.to_json
110
+ Hashie::Mash.new(response)
111
+ end
112
+
113
+ def cancel
114
+ response = EmailDirect.post '/Campaigns/Cancel', :body => campaign_id.to_json
115
+ Hashie::Mash.new(response)
116
+ end
117
+
118
+ def delete
119
+ response = EmailDirect.delete uri_for, {}
120
+ Hashie::Mash.new(response)
121
+ end
122
+
123
+ private
124
+
125
+ def get(action = nil, options = {})
126
+ EmailDirect.get uri_for(action), :query => options
127
+ end
128
+
129
+ def uri_for(action = nil)
130
+ action = "/#{action}" if action
131
+ "/Campaigns/#{campaign_id}#{action}"
132
+ end
133
+ end
134
+ end
135
+
@@ -0,0 +1,54 @@
1
+ require 'emaildirect'
2
+ require 'json'
3
+
4
+ module EmailDirect
5
+ # Represents a creative and associated functionality
6
+ class Creative
7
+ class << self
8
+ def all(options = {})
9
+ response = EmailDirect.get '/Creatives', :query => options
10
+ Hashie::Mash.new(response)
11
+ end
12
+
13
+ def create(name, options = {})
14
+ options.merge! :Name => name
15
+ response = EmailDirect.post '/Creatives', :body => options.to_json
16
+ Hashie::Mash.new(response)
17
+ end
18
+ end
19
+
20
+ attr_reader :creative_id
21
+
22
+ def initialize(creative_id)
23
+ @creative_id = creative_id
24
+ end
25
+
26
+ def details
27
+ response = get
28
+ Hashie::Mash.new(response)
29
+ end
30
+
31
+ def update(name, options)
32
+ options.merge! :Name => name
33
+ response = EmailDirect.put uri_for, :body => options.to_json
34
+ Hashie::Mash.new(response)
35
+ end
36
+
37
+ def delete
38
+ response = EmailDirect.delete uri_for, {}
39
+ Hashie::Mash.new(response)
40
+ end
41
+
42
+ private
43
+
44
+ def get(action = nil)
45
+ EmailDirect.get uri_for(action)
46
+ end
47
+
48
+ def uri_for(action = nil)
49
+ action = "/#{action}" if action
50
+ "/Creatives/#{creative_id}#{action}"
51
+ end
52
+ end
53
+ end
54
+