emaildirect 1.0.0
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.
- 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
|
+
|