emaildirect 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +24 -0
- data/LICENSE +19 -0
- data/README.md +83 -0
- data/Rakefile +23 -0
- data/emaildirect.gemspec +23 -0
- data/lib/emaildirect.rb +104 -0
- data/lib/emaildirect/campaign.rb +135 -0
- data/lib/emaildirect/creative.rb +54 -0
- data/lib/emaildirect/creative_folder.rb +59 -0
- data/lib/emaildirect/database.rb +32 -0
- data/lib/emaildirect/filter.rb +42 -0
- data/lib/emaildirect/image_file.rb +46 -0
- data/lib/emaildirect/image_folder.rb +53 -0
- data/lib/emaildirect/import.rb +43 -0
- data/lib/emaildirect/list.rb +75 -0
- data/lib/emaildirect/mailer.rb +57 -0
- data/lib/emaildirect/publication.rb +79 -0
- data/lib/emaildirect/relay_send.rb +7 -0
- data/lib/emaildirect/relay_send/category.rb +51 -0
- data/lib/emaildirect/relay_send/email.rb +21 -0
- data/lib/emaildirect/relay_send/receipt.rb +39 -0
- data/lib/emaildirect/short_url.rb +53 -0
- data/lib/emaildirect/source.rb +65 -0
- data/lib/emaildirect/subscriber.rb +90 -0
- data/lib/emaildirect/suppression_list.rb +89 -0
- data/lib/emaildirect/version.rb +3 -0
- data/lib/emaildirect/workflow.rb +88 -0
- data/rails/init.rb +1 -0
- metadata +140 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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.
|
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 "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
|
data/emaildirect.gemspec
ADDED
@@ -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
|
data/lib/emaildirect.rb
ADDED
@@ -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
|
+
|