esendex 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/esendex/application_controller.rb +4 -4
- data/app/controllers/esendex/inbound_messages_controller.rb +11 -11
- data/app/controllers/esendex/message_delivered_events_controller.rb +11 -11
- data/app/controllers/esendex/message_failed_events_controller.rb +11 -11
- data/app/controllers/esendex/push_notification_handler.rb +41 -41
- data/config/routes.rb +5 -5
- data/lib/esendex.rb +63 -62
- data/lib/esendex/account.rb +44 -44
- data/lib/esendex/api_connection.rb +29 -29
- data/lib/esendex/dispatcher_result.rb +25 -25
- data/lib/esendex/engine.rb +4 -4
- data/lib/esendex/exceptions.rb +25 -25
- data/lib/esendex/hash_serialisation.rb +23 -23
- data/lib/esendex/inbound_message.rb +30 -30
- data/lib/esendex/message.rb +38 -38
- data/lib/esendex/message_batch_submission.rb +50 -50
- data/lib/esendex/message_delivered_event.rb +29 -29
- data/lib/esendex/message_failed_event.rb +29 -29
- data/lib/esendex/railtie.rb +11 -11
- data/lib/esendex/version.rb +3 -3
- data/lib/esendex/voice_message.rb +25 -0
- data/lib/tasks/esendex.rake +29 -29
- data/licence.txt +23 -23
- data/readme.md +186 -186
- data/spec/account_spec.rb +211 -211
- data/spec/api_connection_spec.rb +78 -78
- data/spec/controllers/message_delivered_events_controller_spec.rb +29 -29
- data/spec/controllers/push_notification_handler_spec.rb +96 -96
- data/spec/dummy/README.rdoc +261 -261
- data/spec/dummy/Rakefile +7 -7
- data/spec/dummy/app/assets/javascripts/application.js +15 -15
- data/spec/dummy/app/assets/stylesheets/application.css +13 -13
- data/spec/dummy/app/controllers/application_controller.rb +3 -3
- data/spec/dummy/app/helpers/application_helper.rb +2 -2
- data/spec/dummy/app/views/layouts/application.html.erb +14 -14
- data/spec/dummy/config.ru +4 -4
- data/spec/dummy/config/application.rb +66 -66
- data/spec/dummy/config/boot.rb +9 -9
- data/spec/dummy/config/environment.rb +5 -5
- data/spec/dummy/config/environments/development.rb +37 -37
- data/spec/dummy/config/environments/production.rb +67 -67
- data/spec/dummy/config/environments/test.rb +39 -39
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -7
- data/spec/dummy/config/initializers/inflections.rb +15 -15
- data/spec/dummy/config/initializers/mime_types.rb +5 -5
- data/spec/dummy/config/initializers/secret_token.rb +7 -7
- data/spec/dummy/config/initializers/session_store.rb +8 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -14
- data/spec/dummy/config/locales/en.yml +5 -5
- data/spec/dummy/config/routes.rb +4 -4
- data/spec/dummy/public/404.html +26 -26
- data/spec/dummy/public/422.html +26 -26
- data/spec/dummy/public/500.html +25 -25
- data/spec/dummy/script/rails +6 -6
- data/spec/hash_serialisation_spec.rb +52 -52
- data/spec/inbound_message_spec.rb +42 -42
- data/spec/message_batch_submission_spec.rb +54 -54
- data/spec/message_delivered_event_spec.rb +32 -32
- data/spec/message_failed_event_spec.rb +32 -32
- data/spec/message_spec.rb +49 -49
- data/spec/spec_helper.rb +41 -41
- data/spec/voice_message_spec.rb +29 -0
- metadata +12 -9
@@ -1,25 +1,25 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
|
3
|
-
module Esendex
|
4
|
-
class DispatcherResult
|
5
|
-
attr_reader :batch_id, :messages
|
6
|
-
|
7
|
-
def initialize(batch_id, messages)
|
8
|
-
@batch_id = batch_id
|
9
|
-
@messages = messages
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.from_xml(source)
|
13
|
-
doc = Nokogiri::XML source
|
14
|
-
batch_id = doc.at_xpath('//api:messageheaders', 'api' => Esendex::API_NAMESPACE)['batchid']
|
15
|
-
messages = doc.xpath('//api:messageheader', 'api' => Esendex::API_NAMESPACE).map do |header|
|
16
|
-
{ id: header['id'], uri: header['uri'] }
|
17
|
-
end
|
18
|
-
DispatcherResult.new batch_id, messages
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_s
|
22
|
-
batch_id
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Esendex
|
4
|
+
class DispatcherResult
|
5
|
+
attr_reader :batch_id, :messages
|
6
|
+
|
7
|
+
def initialize(batch_id, messages)
|
8
|
+
@batch_id = batch_id
|
9
|
+
@messages = messages
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from_xml(source)
|
13
|
+
doc = Nokogiri::XML source
|
14
|
+
batch_id = doc.at_xpath('//api:messageheaders', 'api' => Esendex::API_NAMESPACE)['batchid']
|
15
|
+
messages = doc.xpath('//api:messageheader', 'api' => Esendex::API_NAMESPACE).map do |header|
|
16
|
+
{ id: header['id'], uri: header['uri'] }
|
17
|
+
end
|
18
|
+
DispatcherResult.new batch_id, messages
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
batch_id
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/esendex/engine.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
module Esendex
|
2
|
-
class Engine < Rails::Engine
|
3
|
-
isolate_namespace Esendex
|
4
|
-
end
|
1
|
+
module Esendex
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
isolate_namespace Esendex
|
4
|
+
end
|
5
5
|
end
|
data/lib/esendex/exceptions.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
module Esendex
|
2
|
-
class ApiErrorFactory
|
3
|
-
def get_api_error(source_error)
|
4
|
-
case source_error
|
5
|
-
when Nestful::ForbiddenAccess
|
6
|
-
return ForbiddenError.new
|
7
|
-
when Nestful::UnauthorizedAccess
|
8
|
-
return NotAuthorizedError.new
|
9
|
-
else
|
10
|
-
return ApiError.new(source_error)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class ApiError < StandardError
|
16
|
-
end
|
17
|
-
|
18
|
-
class NotAuthorizedError < ApiError
|
19
|
-
end
|
20
|
-
|
21
|
-
class ForbiddenError < ApiError
|
22
|
-
end
|
23
|
-
|
24
|
-
class AccountReferenceError < ApiError
|
25
|
-
end
|
1
|
+
module Esendex
|
2
|
+
class ApiErrorFactory
|
3
|
+
def get_api_error(source_error)
|
4
|
+
case source_error
|
5
|
+
when Nestful::ForbiddenAccess
|
6
|
+
return ForbiddenError.new
|
7
|
+
when Nestful::UnauthorizedAccess
|
8
|
+
return NotAuthorizedError.new
|
9
|
+
else
|
10
|
+
return ApiError.new(source_error)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ApiError < StandardError
|
16
|
+
end
|
17
|
+
|
18
|
+
class NotAuthorizedError < ApiError
|
19
|
+
end
|
20
|
+
|
21
|
+
class ForbiddenError < ApiError
|
22
|
+
end
|
23
|
+
|
24
|
+
class AccountReferenceError < ApiError
|
25
|
+
end
|
26
26
|
end
|
@@ -1,24 +1,24 @@
|
|
1
|
-
# Handles serialisation and deserialisation of object as a hash
|
2
|
-
#
|
3
|
-
module Esendex
|
4
|
-
module HashSerialisation
|
5
|
-
def initialize(attrs={})
|
6
|
-
attrs.each_pair do |k, v|
|
7
|
-
raise ArgumentError.new("#{k} not an attribute of #{self.class.name}") unless respond_to?("#{k}=")
|
8
|
-
send("#{k}=", v)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_hash
|
13
|
-
attrs = {}
|
14
|
-
public_methods
|
15
|
-
.select { |m| m =~ /\w\=$/ }
|
16
|
-
.select { |m| respond_to?(m.to_s.chop) }
|
17
|
-
.collect { |m| m.to_s.chop.to_sym }
|
18
|
-
.each do |method|
|
19
|
-
attrs[method] = send(method)
|
20
|
-
end
|
21
|
-
attrs
|
22
|
-
end
|
23
|
-
end
|
1
|
+
# Handles serialisation and deserialisation of object as a hash
|
2
|
+
#
|
3
|
+
module Esendex
|
4
|
+
module HashSerialisation
|
5
|
+
def initialize(attrs={})
|
6
|
+
attrs.each_pair do |k, v|
|
7
|
+
raise ArgumentError.new("#{k} not an attribute of #{self.class.name}") unless respond_to?("#{k}=")
|
8
|
+
send("#{k}=", v)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_hash
|
13
|
+
attrs = {}
|
14
|
+
public_methods
|
15
|
+
.select { |m| m =~ /\w\=$/ }
|
16
|
+
.select { |m| respond_to?(m.to_s.chop) }
|
17
|
+
.collect { |m| m.to_s.chop.to_sym }
|
18
|
+
.each do |method|
|
19
|
+
attrs[method] = send(method)
|
20
|
+
end
|
21
|
+
attrs
|
22
|
+
end
|
23
|
+
end
|
24
24
|
end
|
@@ -1,31 +1,31 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
|
3
|
-
# <InboundMessage>
|
4
|
-
# <Id>{guid-of-push-notification}</Id>
|
5
|
-
# <MessageId>{guid-of-inbound-message}</MessageId>
|
6
|
-
# <AccountId>{guid-of-esendex-account-for-message}</AccountId>
|
7
|
-
# <MessageText>{Message text of inbound message}</MessageText>
|
8
|
-
# <From>{phone number of sender of the message}</From>
|
9
|
-
# <To>{phone number for the Virtual Mobile Number of your Account}</To>
|
10
|
-
# </InboundMessage>
|
11
|
-
|
12
|
-
module Esendex
|
13
|
-
class InboundMessage
|
14
|
-
include HashSerialisation
|
15
|
-
|
16
|
-
attr_accessor :id, :message_id, :account_id, :message_text, :from, :to
|
17
|
-
|
18
|
-
def self.from_xml(source)
|
19
|
-
doc = Nokogiri::XML source
|
20
|
-
event = InboundMessage.new
|
21
|
-
event.id = doc.at_xpath("/InboundMessage/Id").content
|
22
|
-
event.message_id = doc.at_xpath("/InboundMessage/MessageId").content
|
23
|
-
event.account_id = doc.at_xpath("/InboundMessage/AccountId").content
|
24
|
-
event.message_text = doc.at_xpath("/InboundMessage/MessageText").content
|
25
|
-
event.from = doc.at_xpath("/InboundMessage/From").content
|
26
|
-
event.to = doc.at_xpath("/InboundMessage/To").content
|
27
|
-
event
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
# <InboundMessage>
|
4
|
+
# <Id>{guid-of-push-notification}</Id>
|
5
|
+
# <MessageId>{guid-of-inbound-message}</MessageId>
|
6
|
+
# <AccountId>{guid-of-esendex-account-for-message}</AccountId>
|
7
|
+
# <MessageText>{Message text of inbound message}</MessageText>
|
8
|
+
# <From>{phone number of sender of the message}</From>
|
9
|
+
# <To>{phone number for the Virtual Mobile Number of your Account}</To>
|
10
|
+
# </InboundMessage>
|
11
|
+
|
12
|
+
module Esendex
|
13
|
+
class InboundMessage
|
14
|
+
include HashSerialisation
|
15
|
+
|
16
|
+
attr_accessor :id, :message_id, :account_id, :message_text, :from, :to
|
17
|
+
|
18
|
+
def self.from_xml(source)
|
19
|
+
doc = Nokogiri::XML source
|
20
|
+
event = InboundMessage.new
|
21
|
+
event.id = doc.at_xpath("/InboundMessage/Id").content
|
22
|
+
event.message_id = doc.at_xpath("/InboundMessage/MessageId").content
|
23
|
+
event.account_id = doc.at_xpath("/InboundMessage/AccountId").content
|
24
|
+
event.message_text = doc.at_xpath("/InboundMessage/MessageText").content
|
25
|
+
event.from = doc.at_xpath("/InboundMessage/From").content
|
26
|
+
event.to = doc.at_xpath("/InboundMessage/To").content
|
27
|
+
event
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
31
|
end
|
data/lib/esendex/message.rb
CHANGED
@@ -1,38 +1,38 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
|
3
|
-
# <message>
|
4
|
-
# <to>$TO</to>
|
5
|
-
# <body>$BODY</body>
|
6
|
-
# </message>
|
7
|
-
|
8
|
-
module Esendex
|
9
|
-
class Message
|
10
|
-
attr_accessor :to, :body, :from
|
11
|
-
|
12
|
-
def initialize(to, body, from=nil)
|
13
|
-
@to = to
|
14
|
-
@body = body
|
15
|
-
@from = from
|
16
|
-
end
|
17
|
-
|
18
|
-
def xml_node
|
19
|
-
doc = Nokogiri::XML('<message/>')
|
20
|
-
|
21
|
-
to = Nokogiri::XML::Node.new 'to', doc
|
22
|
-
to.content = @to
|
23
|
-
doc.root.add_child(to)
|
24
|
-
|
25
|
-
body = Nokogiri::XML::Node.new 'body', doc
|
26
|
-
body.content = @body
|
27
|
-
doc.root.add_child(body)
|
28
|
-
|
29
|
-
if @from
|
30
|
-
from = Nokogiri::XML::Node.new 'from', doc
|
31
|
-
from.content = @from
|
32
|
-
doc.root.add_child(from)
|
33
|
-
end
|
34
|
-
|
35
|
-
doc.root
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
# <message>
|
4
|
+
# <to>$TO</to>
|
5
|
+
# <body>$BODY</body>
|
6
|
+
# </message>
|
7
|
+
|
8
|
+
module Esendex
|
9
|
+
class Message
|
10
|
+
attr_accessor :to, :body, :from
|
11
|
+
|
12
|
+
def initialize(to, body, from=nil)
|
13
|
+
@to = to
|
14
|
+
@body = body
|
15
|
+
@from = from
|
16
|
+
end
|
17
|
+
|
18
|
+
def xml_node
|
19
|
+
doc = Nokogiri::XML('<message/>')
|
20
|
+
|
21
|
+
to = Nokogiri::XML::Node.new 'to', doc
|
22
|
+
to.content = @to
|
23
|
+
doc.root.add_child(to)
|
24
|
+
|
25
|
+
body = Nokogiri::XML::Node.new 'body', doc
|
26
|
+
body.content = @body
|
27
|
+
doc.root.add_child(body)
|
28
|
+
|
29
|
+
if @from
|
30
|
+
from = Nokogiri::XML::Node.new 'from', doc
|
31
|
+
from.content = @from
|
32
|
+
doc.root.add_child(from)
|
33
|
+
end
|
34
|
+
|
35
|
+
doc.root
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,51 +1,51 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
|
3
|
-
#<messages>
|
4
|
-
# <accountreference>EX000000</accountreference>
|
5
|
-
# <message>
|
6
|
-
# <to>someone</to>
|
7
|
-
# <body>$BODY</body>
|
8
|
-
# </message>
|
9
|
-
# <message>
|
10
|
-
# <to>$TO_</to>
|
11
|
-
# <body>$BODY</body>
|
12
|
-
# </message>
|
13
|
-
#</messages>
|
14
|
-
|
15
|
-
module Esendex
|
16
|
-
class MessageBatchSubmission
|
17
|
-
attr_accessor :account_reference, :messages, :send_at
|
18
|
-
|
19
|
-
def initialize(account_reference, messages)
|
20
|
-
raise AccountReferenceError unless account_reference
|
21
|
-
raise StandardError, "Need at least one message" unless messages.kind_of?(Array) && !messages.empty?
|
22
|
-
|
23
|
-
@account_reference = account_reference
|
24
|
-
@messages = messages
|
25
|
-
end
|
26
|
-
|
27
|
-
def xml_node
|
28
|
-
doc = Nokogiri::XML'<messages/>'
|
29
|
-
|
30
|
-
account_reference = Nokogiri::XML::Node.new 'accountreference', doc
|
31
|
-
account_reference.content = self.account_reference
|
32
|
-
doc.root.add_child(account_reference)
|
33
|
-
|
34
|
-
if send_at
|
35
|
-
send_at_node = Nokogiri::XML::Node.new 'sendat', doc
|
36
|
-
send_at_node.content = send_at.strftime("%Y-%m-%dT%H:%M:%S")
|
37
|
-
doc.root.add_child(send_at_node)
|
38
|
-
end
|
39
|
-
|
40
|
-
@messages.each do |message|
|
41
|
-
doc.root.add_child(message.xml_node)
|
42
|
-
end
|
43
|
-
|
44
|
-
doc.root
|
45
|
-
end
|
46
|
-
|
47
|
-
def to_s
|
48
|
-
xml_node.to_s
|
49
|
-
end
|
50
|
-
end
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
#<messages>
|
4
|
+
# <accountreference>EX000000</accountreference>
|
5
|
+
# <message>
|
6
|
+
# <to>someone</to>
|
7
|
+
# <body>$BODY</body>
|
8
|
+
# </message>
|
9
|
+
# <message>
|
10
|
+
# <to>$TO_</to>
|
11
|
+
# <body>$BODY</body>
|
12
|
+
# </message>
|
13
|
+
#</messages>
|
14
|
+
|
15
|
+
module Esendex
|
16
|
+
class MessageBatchSubmission
|
17
|
+
attr_accessor :account_reference, :messages, :send_at
|
18
|
+
|
19
|
+
def initialize(account_reference, messages)
|
20
|
+
raise AccountReferenceError unless account_reference
|
21
|
+
raise StandardError, "Need at least one message" unless messages.kind_of?(Array) && !messages.empty?
|
22
|
+
|
23
|
+
@account_reference = account_reference
|
24
|
+
@messages = messages
|
25
|
+
end
|
26
|
+
|
27
|
+
def xml_node
|
28
|
+
doc = Nokogiri::XML'<messages/>'
|
29
|
+
|
30
|
+
account_reference = Nokogiri::XML::Node.new 'accountreference', doc
|
31
|
+
account_reference.content = self.account_reference
|
32
|
+
doc.root.add_child(account_reference)
|
33
|
+
|
34
|
+
if send_at
|
35
|
+
send_at_node = Nokogiri::XML::Node.new 'sendat', doc
|
36
|
+
send_at_node.content = send_at.strftime("%Y-%m-%dT%H:%M:%S")
|
37
|
+
doc.root.add_child(send_at_node)
|
38
|
+
end
|
39
|
+
|
40
|
+
@messages.each do |message|
|
41
|
+
doc.root.add_child(message.xml_node)
|
42
|
+
end
|
43
|
+
|
44
|
+
doc.root
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
xml_node.to_s
|
49
|
+
end
|
50
|
+
end
|
51
51
|
end
|
@@ -1,30 +1,30 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
|
3
|
-
# <MessageDelivered>
|
4
|
-
# <Id>{guid-of-push-notification}</Id>
|
5
|
-
# <MessageId>{guid-of-inbound-message}</MessageId>
|
6
|
-
# <AccountId>{guid-of-esendex-account-for-message}</AccountId>
|
7
|
-
# <OccurredAt>
|
8
|
-
# {the UTC DateTime (yyyy-MM-ddThh:mm:ss) the message was delivered}
|
9
|
-
# </OccurredAt>
|
10
|
-
# </MessageDelivered>
|
11
|
-
|
12
|
-
module Esendex
|
13
|
-
class MessageDeliveredEvent
|
14
|
-
include HashSerialisation
|
15
|
-
|
16
|
-
attr_accessor :id, :message_id, :account_id, :occurred_at
|
17
|
-
|
18
|
-
def self.from_xml(source)
|
19
|
-
doc = Nokogiri::XML source
|
20
|
-
event = MessageDeliveredEvent.new
|
21
|
-
event.id = doc.at_xpath("/MessageDelivered/Id").content
|
22
|
-
event.message_id = doc.at_xpath("/MessageDelivered/MessageId").content
|
23
|
-
event.account_id = doc.at_xpath("/MessageDelivered/AccountId").content
|
24
|
-
occurred_at_s = doc.at_xpath("/MessageDelivered/OccurredAt").content
|
25
|
-
event.occurred_at = DateTime.strptime(occurred_at_s, "%Y-%m-%dT%H:%M:%S").to_time
|
26
|
-
event
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
# <MessageDelivered>
|
4
|
+
# <Id>{guid-of-push-notification}</Id>
|
5
|
+
# <MessageId>{guid-of-inbound-message}</MessageId>
|
6
|
+
# <AccountId>{guid-of-esendex-account-for-message}</AccountId>
|
7
|
+
# <OccurredAt>
|
8
|
+
# {the UTC DateTime (yyyy-MM-ddThh:mm:ss) the message was delivered}
|
9
|
+
# </OccurredAt>
|
10
|
+
# </MessageDelivered>
|
11
|
+
|
12
|
+
module Esendex
|
13
|
+
class MessageDeliveredEvent
|
14
|
+
include HashSerialisation
|
15
|
+
|
16
|
+
attr_accessor :id, :message_id, :account_id, :occurred_at
|
17
|
+
|
18
|
+
def self.from_xml(source)
|
19
|
+
doc = Nokogiri::XML source
|
20
|
+
event = MessageDeliveredEvent.new
|
21
|
+
event.id = doc.at_xpath("/MessageDelivered/Id").content
|
22
|
+
event.message_id = doc.at_xpath("/MessageDelivered/MessageId").content
|
23
|
+
event.account_id = doc.at_xpath("/MessageDelivered/AccountId").content
|
24
|
+
occurred_at_s = doc.at_xpath("/MessageDelivered/OccurredAt").content
|
25
|
+
event.occurred_at = DateTime.strptime(occurred_at_s, "%Y-%m-%dT%H:%M:%S").to_time
|
26
|
+
event
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
30
|
end
|