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 CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  test_email_center.rb
19
+ config/email_center_api.yml
data/README.md CHANGED
@@ -20,22 +20,75 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- Experimental and Feature Incomplete. Will allow some manipulation of
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.configure do |config|
34
- config.username = 'yourusername'
35
- config.password = 'yourpassword'
36
- end
89
+ EmailCenterApi::Nodes::TemplateNode.all
37
90
 
38
- binding.pry
91
+ This returns a array of template instances which exposes ```name``` and ```nodeId``` attributes.
39
92
 
40
93
  ## Contributing
41
94
 
@@ -0,0 +1,3 @@
1
+ base_uri: 'https://maxemail.emailcenteruk.com/api/json/'
2
+ username: username@foo.com
3
+ password: password
@@ -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 = %q{ A RubyGem That wraps EmailCenter's maxemail JSON Api }
13
- gem.summary = %q{ A RubyGem That wraps EmailCenter's maxemail JSON Api }
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.9.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.11.0")
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
@@ -1,13 +1,37 @@
1
- require "httparty"
2
- require "email_center_api/version"
3
- require "email_center_api/configuration"
4
- require "email_center_api/base"
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
- module EmailCenterApi
8
- extend Configuration
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 "email_center_api/list"
12
- require "email_center_api/recipient"
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
@@ -1,3 +1,3 @@
1
1
  module EmailCenterApi
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  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
+