email_center_api 0.0.1 → 0.0.2
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 +1 -0
- data/README.md +64 -11
- data/config/email_center_api.example.yml +3 -0
- data/email_center_api.gemspec +5 -4
- data/lib/email_center_api.rb +32 -8
- data/lib/email_center_api/actions.rb +17 -0
- data/lib/email_center_api/http_client.rb +47 -0
- data/lib/email_center_api/nodes/email_node.rb +81 -0
- data/lib/email_center_api/nodes/template_node.rb +22 -0
- data/lib/email_center_api/query.rb +44 -0
- data/lib/email_center_api/response_validator.rb +31 -0
- data/lib/email_center_api/version.rb +1 -1
- data/spec/fake_web_helpers/email.rb +36 -0
- data/spec/fake_web_helpers/template.rb +21 -0
- data/spec/features/triggering_an_email_to_send_spec.rb +22 -0
- data/spec/http_client_spec.rb +50 -0
- data/spec/nodes/email_node_spec.rb +113 -0
- data/spec/nodes/template_node_spec.rb +15 -0
- data/spec/response_validator_spec.rb +70 -0
- data/spec/spec_helper.rb +12 -41
- data/spec/support/fake_config.yml +3 -0
- metadata +120 -106
- data/lib/email_center_api/base.rb +0 -40
- data/lib/email_center_api/configuration.rb +0 -32
- data/lib/email_center_api/list.rb +0 -90
- data/lib/email_center_api/recipient.rb +0 -62
- data/spec/configuration_spec.rb +0 -28
- data/spec/list_spec.rb +0 -119
- data/spec/recipient_spec.rb +0 -56
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -20,22 +20,75 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
24
|
-
lists and recipients.
|
23
|
+
### General configuration
|
25
24
|
|
26
|
-
Try it out with something like this:
|
27
|
-
|
28
|
-
require 'rubygems'
|
29
25
|
require 'email_center_api'
|
30
|
-
require 'pry'
|
31
26
|
|
27
|
+
This will load a configuration yaml file from:
|
28
|
+
|
29
|
+
'config/email_center_api.yml'
|
30
|
+
|
31
|
+
You can set a custom configuration file with:
|
32
|
+
|
33
|
+
EmailCenterApi.config_path = 'path/to/config'
|
34
|
+
|
35
|
+
The config file should contain the keys:
|
36
|
+
|
37
|
+
base_uri
|
38
|
+
username
|
39
|
+
password
|
40
|
+
|
41
|
+
### Email Node Class
|
42
|
+
|
43
|
+
The 'email' tree can be queried in the following ways:
|
44
|
+
|
45
|
+
# All children elements of a node:
|
46
|
+
EmailCenterApi::Nodes::EmailNode.all(selector)
|
47
|
+
|
48
|
+
# Folders from a node:
|
49
|
+
EmailCenterApi::Nodes::EmailNode.folders(selector)
|
50
|
+
|
51
|
+
# Emails from a node:
|
52
|
+
EmailCenterApi::Nodes::EmailNode.emails(selector)
|
53
|
+
|
54
|
+
where the selector contains an optional parameter to select the parent folder in the form:
|
55
|
+
|
56
|
+
{ folder: <folder node id> }
|
57
|
+
|
58
|
+
This will return and array of EmailCenterApi::Nodes::EmailNode object.
|
59
|
+
|
60
|
+
### Email Node Instance
|
61
|
+
|
62
|
+
Each email node is a folder it can be queried in the following ways:
|
63
|
+
|
64
|
+
node = EmailCenterApi::Nodes::EmailNode.all(selector).first
|
65
|
+
|
66
|
+
# All children elements of a node:
|
67
|
+
node.all
|
68
|
+
|
69
|
+
# Folders from a node:
|
70
|
+
node.folders
|
71
|
+
|
72
|
+
# Emails from a node:
|
73
|
+
node.emails
|
74
|
+
|
75
|
+
Alternatively an email node can be triggered to send an email:
|
76
|
+
|
77
|
+
node = EmailCenterApi::Nodes::EmailNode.all(selector).first
|
78
|
+
|
79
|
+
# All children elements of a node:
|
80
|
+
node.trigger(<email_address>, <options>)
|
81
|
+
|
82
|
+
Where options is a hash containing the relevant profile data for the email.
|
83
|
+
See [Maxemail Documentation](http://maxemail.emailcenteruk.com/manual/doku.php?id=maxemail:v6:webservices:email_send#trigger) for more details.
|
84
|
+
|
85
|
+
### Email Template Node Instance
|
86
|
+
|
87
|
+
Can be used to query all templates within the tree:
|
32
88
|
|
33
|
-
EmailCenterApi.
|
34
|
-
config.username = 'yourusername'
|
35
|
-
config.password = 'yourpassword'
|
36
|
-
end
|
89
|
+
EmailCenterApi::Nodes::TemplateNode.all
|
37
90
|
|
38
|
-
|
91
|
+
This returns a array of template instances which exposes ```name``` and ```nodeId``` attributes.
|
39
92
|
|
40
93
|
## Contributing
|
41
94
|
|
data/email_center_api.gemspec
CHANGED
@@ -9,17 +9,18 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.version = EmailCenterApi::VERSION
|
10
10
|
gem.authors = ["Ed Robinson"]
|
11
11
|
gem.email = Base64.decode64("ZWQucm9iaW5zb25AcmVldm9vLmNvbQ==\n")
|
12
|
-
gem.description =
|
13
|
-
gem.summary =
|
12
|
+
gem.description = "A RubyGem That wraps EmailCenter's maxemail JSON Api"
|
13
|
+
gem.summary = "A RubyGem That wraps EmailCenter's maxemail JSON Api"
|
14
14
|
gem.homepage = "https://github.com/reevoo/email_center_api"
|
15
15
|
|
16
16
|
gem.files = `git ls-files`.split($/)
|
17
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
|
-
gem.add_dependency("httparty", "~> 0.
|
20
|
+
gem.add_dependency("httparty", "~> 0.11.0")
|
21
21
|
gem.add_dependency("json", "~> 1.7.5")
|
22
22
|
gem.add_development_dependency("fakeweb", "~> 1.3.0")
|
23
|
-
gem.add_development_dependency("rspec", "~> 2.
|
23
|
+
gem.add_development_dependency("rspec", "~> 2.14.0")
|
24
24
|
gem.add_development_dependency("pry")
|
25
|
+
gem.add_development_dependency("pry-debugger")
|
25
26
|
end
|
data/lib/email_center_api.rb
CHANGED
@@ -1,13 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module EmailCenterApi
|
2
|
+
class AllErrors < StandardError; end
|
3
|
+
class ApiError < AllErrors; end
|
4
|
+
class HttpError < AllErrors; end
|
5
|
+
class HttpTimeoutError < AllErrors; end
|
5
6
|
|
7
|
+
DEFAULT_PATH = 'config/email_center_api.yml'
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
def config
|
10
|
+
@config ||= YAML.load_file(config_path)
|
11
|
+
end
|
12
|
+
|
13
|
+
def config_path
|
14
|
+
@config_path || DEFAULT_PATH
|
15
|
+
end
|
16
|
+
|
17
|
+
def config_path=(path)
|
18
|
+
@config_path = path
|
19
|
+
@config = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
extend self
|
9
23
|
end
|
10
24
|
|
11
|
-
require
|
12
|
-
require
|
25
|
+
require 'httparty'
|
26
|
+
require 'yaml'
|
27
|
+
require 'delegate'
|
28
|
+
|
29
|
+
require "email_center_api/nodes/template_node"
|
30
|
+
require "email_center_api/nodes/email_node"
|
13
31
|
|
32
|
+
require "email_center_api/http_client"
|
33
|
+
require "email_center_api/response_validator"
|
34
|
+
require "email_center_api/query"
|
35
|
+
require "email_center_api/actions"
|
36
|
+
|
37
|
+
require "email_center_api/version"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module EmailCenterApi
|
2
|
+
class Actions
|
3
|
+
|
4
|
+
def trigger(email_id, email_address, options)
|
5
|
+
get(
|
6
|
+
method: 'trigger',
|
7
|
+
emailID: email_id,
|
8
|
+
emailAddress: email_address,
|
9
|
+
profileData: options
|
10
|
+
).validate_and_return_response
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(query)
|
14
|
+
ResponseValidator.new(HttpClient.get('/email_send', :query => query))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module EmailCenterApi
|
2
|
+
class HttpClient
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def get(*args)
|
6
|
+
with_retries do
|
7
|
+
connection.get(*args)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def connection
|
12
|
+
@connection ||= Connection.tap{ |con| con.configure(EmailCenterApi.config) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def reset
|
16
|
+
@connection = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def with_retries(attempts=3)
|
22
|
+
error = nil
|
23
|
+
attempts.times do
|
24
|
+
begin
|
25
|
+
return yield
|
26
|
+
rescue Timeout::Error => e
|
27
|
+
error = e
|
28
|
+
end
|
29
|
+
end
|
30
|
+
raise EmailCenterApi::HttpTimeoutError.new(error.message)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Connection
|
35
|
+
include HTTParty
|
36
|
+
default_timeout 10
|
37
|
+
|
38
|
+
class << self
|
39
|
+
|
40
|
+
def configure(config)
|
41
|
+
base_uri config['base_uri']
|
42
|
+
basic_auth config['username'], config['password']
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module EmailCenterApi::Nodes
|
2
|
+
class EmailNode
|
3
|
+
TREE_ROOT = 'email'
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def all(selectors={})
|
7
|
+
where(
|
8
|
+
selectors[:folder] || 0,
|
9
|
+
->(node) { true }
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def folders(selectors={})
|
14
|
+
where(
|
15
|
+
selectors[:folder] || 0,
|
16
|
+
->(node) { node['nodeClass'] == 'folder' }
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def emails(selectors={})
|
21
|
+
where(
|
22
|
+
selectors[:folder] || 0,
|
23
|
+
->(node) { node['nodeClass'] =~ /^email/ }
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def where(folder_id, selector)
|
30
|
+
EmailCenterApi::Query.new(TREE_ROOT)
|
31
|
+
.tree('folder', folder_id)
|
32
|
+
.select { |node| selector.call(node) }
|
33
|
+
.map { |node| build(node) }
|
34
|
+
rescue EmailCenterApi::AllErrors
|
35
|
+
[]
|
36
|
+
end
|
37
|
+
|
38
|
+
def build(node)
|
39
|
+
new(node['text'], node['nodeId'], node['nodeClass'])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :name, :node_id, :node_class
|
44
|
+
|
45
|
+
def initialize(name, node_id, node_class)
|
46
|
+
@name = name
|
47
|
+
@node_id = node_id.to_i
|
48
|
+
@node_class = node_class
|
49
|
+
end
|
50
|
+
|
51
|
+
def ==(other)
|
52
|
+
name == other.name &&
|
53
|
+
node_id == other.node_id &&
|
54
|
+
node_class == other.node_class
|
55
|
+
end
|
56
|
+
|
57
|
+
def all
|
58
|
+
super unless is_folder?
|
59
|
+
self.class.all(parent: node_id)
|
60
|
+
end
|
61
|
+
|
62
|
+
def folders
|
63
|
+
super unless is_folder?
|
64
|
+
self.class.folders(parent: node_id)
|
65
|
+
end
|
66
|
+
|
67
|
+
def emails
|
68
|
+
super unless is_folder?
|
69
|
+
self.class.emails(folder: node_id)
|
70
|
+
end
|
71
|
+
|
72
|
+
def trigger(email_address, options={})
|
73
|
+
super if is_folder?
|
74
|
+
EmailCenterApi::Actions.new.trigger(node_id, email_address, options)
|
75
|
+
end
|
76
|
+
|
77
|
+
def is_folder?
|
78
|
+
node_class == 'folder'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module EmailCenterApi::Nodes
|
2
|
+
class TemplateNode
|
3
|
+
TREE_ROOT = 'email_template'
|
4
|
+
|
5
|
+
attr_reader :name, :node_id
|
6
|
+
|
7
|
+
def initialize(name, node_id)
|
8
|
+
@name = name
|
9
|
+
@node_id = node_id.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.all
|
13
|
+
response = EmailCenterApi::Query.new(TREE_ROOT).root
|
14
|
+
response.first['children'].map do |template|
|
15
|
+
self.new(
|
16
|
+
template['text'],
|
17
|
+
template['nodeId']
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module EmailCenterApi
|
2
|
+
class Query
|
3
|
+
class TreeRootRequired < StandardError; end
|
4
|
+
|
5
|
+
attr_reader :tree_root
|
6
|
+
|
7
|
+
def initialize(tree_root=nil)
|
8
|
+
@tree_root = tree_root
|
9
|
+
end
|
10
|
+
|
11
|
+
def root
|
12
|
+
raise TreeRootRequired if tree_root.nil?
|
13
|
+
get(
|
14
|
+
method: 'fetchRoot',
|
15
|
+
tree: tree_root,
|
16
|
+
children: ['root']
|
17
|
+
).validate_and_return_response
|
18
|
+
end
|
19
|
+
|
20
|
+
def tree(node_class, node_id)
|
21
|
+
raise TreeRootRequired if tree_root.nil?
|
22
|
+
get(
|
23
|
+
method: 'fetchTree',
|
24
|
+
:tree => tree_root,
|
25
|
+
:nodeClass => node_class,
|
26
|
+
nodeId: node_id
|
27
|
+
).validate_and_return_response
|
28
|
+
end
|
29
|
+
|
30
|
+
def node(node_class, node_id)
|
31
|
+
get(
|
32
|
+
method: 'fetchNode',
|
33
|
+
nodeClass: node_class,
|
34
|
+
nodeId: node_id
|
35
|
+
).validate_and_return_response
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def get(query)
|
41
|
+
ResponseValidator.new(HttpClient.get('/tree', :query => query))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module EmailCenterApi
|
2
|
+
class ResponseValidator
|
3
|
+
attr_reader :response
|
4
|
+
def initialize(response)
|
5
|
+
@response = response
|
6
|
+
end
|
7
|
+
|
8
|
+
def validate_and_return_response
|
9
|
+
raise_errors unless successful?
|
10
|
+
response
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def raise_errors
|
16
|
+
if response['msg']
|
17
|
+
raise EmailCenterApi::ApiError, "Api Error: #{response['msg']}"
|
18
|
+
else
|
19
|
+
raise EmailCenterApi::HttpError, "status: #{response.code}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def successful?
|
24
|
+
response.success? && missing_failure_status?
|
25
|
+
end
|
26
|
+
|
27
|
+
def missing_failure_status?
|
28
|
+
!(response.is_a?(Hash) && response['success'] == false)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module FakeWebHelpers
|
2
|
+
class Email
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def setup
|
6
|
+
setup_email_to_trigger
|
7
|
+
setup_email_trigger
|
8
|
+
end
|
9
|
+
|
10
|
+
def setup_email_to_trigger
|
11
|
+
url = "https://test:test@maxemail.emailcenteruk.com/api/json/tree?method=fetchTree&tree=email&nodeClass=folder&nodeId=123"
|
12
|
+
|
13
|
+
FakeWeb.register_uri(:get, url,
|
14
|
+
:body => [email_to_trigger].to_json,
|
15
|
+
:content_type => 'application/json')
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup_email_trigger
|
19
|
+
url = "https://test:test@maxemail.emailcenteruk.com/api/json/email_send?method=trigger&emailID=10&emailAddress=test%40reevoo.com&profileData[Reviews][retailer_product_name]=Test%20product&profileData[Reviews][retailer_name]=test%20retailer&profileData[Reviews][retailer_from]=reply%40reevoo.com"
|
20
|
+
|
21
|
+
FakeWeb.register_uri(:get, url,
|
22
|
+
:body => {success: true, message: "Email queued successfully"}.to_json,
|
23
|
+
:content_type => 'application/json')
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def email_to_trigger
|
29
|
+
{text: "Test Email", nodeId: "10", nodeClass: "email"}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
FakeWebHelpers::Email.setup
|
36
|
+
|