smsified 0.1.3

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/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Jason Goecke
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ smsified
2
+ ========
3
+
4
+ SMSified is a simple API for sending and receiving text messages using regular phone numbers or short codes. SMSified uses a simple REST interface based on the GSMA OneAPI standard and is backed by Voxeo - the worlds largest communications cloud. Ruby lib for consuming the SMSified OneAPI.
5
+
6
+ This is a Ruby gem for consuming the SMSified OneAPI.
7
+
8
+ Installation
9
+ ------------
10
+
11
+ gem install smsified
12
+
13
+ Example
14
+ -------
15
+
16
+ Send an SMS:
17
+
18
+ require 'rubygems'
19
+ require 'smsified'
20
+ oneapi = Smsified::OneAPI.new(:username => 'user', :password => 'bug.fungus24')
21
+ oneapi.send_sms :address => '14155551212', :message => 'Hi there!', :sender_address => '13035551212'
22
+
23
+
24
+ Find a subscription:
25
+
26
+ require 'rubygems'
27
+ require 'smsified'
28
+ subscriptions = Smsified::Subscriptions.new(:username => 'user', :password => 'bug.fungus24')
29
+ subscriptions.inbound_subscriptions('17177455076')
30
+
31
+ Documentation
32
+ -------------
33
+
34
+ May be found at http://tropo.github.com/smsified & http://smsified.com.
35
+
36
+ License
37
+ -------
38
+
39
+ MIT - See LICENSE.txt
@@ -0,0 +1,39 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__), '..', 'lib')
2
+ require 'rubygems'
3
+ require 'smsified'
4
+ require 'yaml'
5
+
6
+ config = YAML.load(File.open('examples/config.yml'))
7
+
8
+ smsified = Smsified::OneAPI.new :username => config['smsified']['username'],
9
+ :password => config['smsified']['password']
10
+
11
+ # Send an SMS to one address
12
+ result = smsified.send_sms :message => 'Hello there!',
13
+ :address => '14157044517',
14
+ :notify_url => config['postbin'],
15
+ :sender_address => '17177455076'
16
+ puts result.data.inspect
17
+ puts result.http.inspect
18
+
19
+ # Send an SMS to multiple addresses
20
+ result = smsified.send_sms :message => 'Hello there!',
21
+ :address => ['14157044517', '14153675082'],
22
+ :notify_url => config['postbin'],
23
+ :sender_address => '17177455076'
24
+ puts result.data.inspect
25
+ puts result.http.inspect
26
+
27
+ # Create in inbound subscription
28
+ result = smsified.create_inbound_subscription '17177455076', :notify_url => config['postbin']
29
+ puts result.data.inspect
30
+ puts result.http.inspect
31
+
32
+ # Get some of your sent SMS details
33
+ result = smsified.search_sms 'startDate=2011-02-14&endDate=2011-02-15'
34
+ puts result.data.inspect
35
+ puts result.data.inspect
36
+
37
+
38
+
39
+
@@ -0,0 +1,33 @@
1
+ module Smsified
2
+ module Helpers
3
+ private
4
+
5
+ ##
6
+ # Camelcases the options
7
+ def camelcase_keys(options)
8
+ options = options.clone
9
+
10
+ if options[:destination_address]
11
+ options[:destinationAddress] = options[:destination_address]
12
+ options.delete(:destination_address)
13
+ end
14
+
15
+ if options[:notify_url]
16
+ options[:notifyURL] = options[:notify_url]
17
+ options.delete(:notify_url)
18
+ end
19
+
20
+ if options[:client_correlator]
21
+ options[:clientCorrelator] = options[:client_correlator]
22
+ options.delete(:client_correlator)
23
+ end
24
+
25
+ if options[:callback_data]
26
+ params[:callbackData] = options[:callback_data]
27
+ options.delete(:callback_data)
28
+ end
29
+
30
+ options
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,107 @@
1
+ module Smsified
2
+ SMSIFIED_ONEAPI_PUBLIC_URI = 'https://api.smsified.com/v1'
3
+ SMSIFIED_HTTP_HEADERS = { 'Content-Type' => 'application/x-www-form-urlencoded' }
4
+
5
+ class OneAPI
6
+ include Helpers
7
+
8
+ include HTTParty
9
+ format :json
10
+
11
+ ##
12
+ # Intantiate a new class to work with OneAPI
13
+ #
14
+ # @param [required, Hash] params to create the user
15
+ # @option params [required, String] :username username to authenticate with
16
+ # @option params [required, String] :password to authenticate with
17
+ # @option params [optional, String] :base_uri of an alternative location of SMSified
18
+ # @option params [optional, String] :destination_address to use with subscriptions
19
+ # @option params [optional, String] :sender_address to use with subscriptions
20
+ # @option params [optional, Boolean] :debug to turn on the HTTparty debugging to stdout
21
+ # @raise [ArgumentError] if :username is not passed as an option
22
+ # @raise [ArgumentError] if :password is not passed as an option
23
+ # @example
24
+ # one_api = OneAPI.new :username => 'user', :password => '123'
25
+ def initialize(options)
26
+ raise ArgumentError, ':username required' if options[:username].nil?
27
+ raise ArgumentError, ':password required' if options[:password].nil?
28
+
29
+ self.class.debug_output $stdout if options[:debug]
30
+ self.class.base_uri options[:base_uri] || SMSIFIED_ONEAPI_PUBLIC_URI
31
+ @auth = { :username => options[:username], :password => options[:password] }
32
+
33
+ @destination_address = options[:destination_address]
34
+ @sender_address = options[:sender_address]
35
+
36
+ @subscriptions = Subscriptions.new(options)
37
+ @reporting = Reporting.new(options)
38
+ end
39
+
40
+ ##
41
+ # Send an SMS to one or more addresses
42
+ #
43
+ # @param [required, Hash] params to send an sms
44
+ # @option params [required, String] :address to send the SMS to
45
+ # @option params [required, String] :message to send with the SMS
46
+ # @option params [optional, String] :sender_address to use with subscriptions, required if not provided on initialization of OneAPI
47
+ # @option params [optional, String] :notify_url to send callbacks to
48
+ # @return [Object] A Response Object with http and data instance methods
49
+ # @raise [ArgumentError] if :sender_address is not passed as an option when not passed on object creation
50
+ # @raise [ArgumentError] if :address is not provided as an option
51
+ # @raise [ArgumentError] if :message is not provided as an option
52
+ # @example
53
+ # one_api.send_sms :address => '14155551212', :message => 'Hi there!', :sender_address => '13035551212'
54
+ # one_api.send_sms :address => ['14155551212', '13035551212'], :message => 'Hi there!', :sender_address => '13035551212'
55
+ def send_sms(options)
56
+ raise ArgumentError, ':sender_address is required' if options[:sender_address].nil? && @sender_address.nil?
57
+ raise ArgumentError, ':address is required' if options[:address].nil?
58
+ raise ArgumentError, ':message is required' if options[:message].nil?
59
+
60
+ options[:sender_address] = options[:sender_address] || @sender_address
61
+ query_options = options.clone
62
+ query_options.delete(:sender_address)
63
+ query_options = camelcase_keys(query_options)
64
+
65
+ Response.new self.class.post("/smsmessaging/outbound/#{options[:sender_address]}/requests",
66
+ :body => build_query_string(query_options),
67
+ :basic_auth => @auth,
68
+ :headers => SMSIFIED_HTTP_HEADERS)
69
+ end
70
+
71
+ ##
72
+ # Dispatches method calls to other objects for subscriptions and reporting
73
+ def method_missing(method, *args)
74
+ if method.to_s.match /subscription/
75
+ if args.size == 2
76
+ @subscriptions.send method, args[0], args[1]
77
+ else
78
+ @subscriptions.send method, args[0]
79
+ end
80
+ else
81
+ if method == :delivery_status || method == :retrieve_sms || method == :search_sms
82
+ @reporting.send method, args[0]
83
+ else
84
+ raise RuntimeError, 'Unknown method'
85
+ end
86
+ end
87
+ end
88
+
89
+ private
90
+
91
+ ##
92
+ # Builds the necessary query string
93
+ def build_query_string(options)
94
+ query = ''
95
+
96
+ options.each do |k,v|
97
+ if k == :address
98
+ v.each { |address| query += "#{ '&' if query != '' }address=#{CGI.escape address}" }
99
+ else
100
+ query += "#{ '&' if query != '' }#{k.to_s}=#{CGI.escape v}"
101
+ end
102
+ end
103
+
104
+ query
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,70 @@
1
+ module Smsified
2
+ class Reporting
3
+ include HTTParty
4
+ format :json
5
+
6
+ ##
7
+ # Intantiate a new class to work with reporting
8
+ #
9
+ # @param [required, Hash] params to create the Reporting object with
10
+ # @option params [required, String] :username username to authenticate with
11
+ # @option params [required, String] :password to authenticate with
12
+ # @option params [optional, String] :base_uri of an alternative location of SMSified
13
+ # @option params [optional, String] :destination_address to use with subscriptions
14
+ # @option params [optional, String] :sender_address to use with subscriptions
15
+ # @option params [optional, Boolean] :debug to turn on the HTTparty debugging to stdout
16
+ # @example
17
+ # subscription = Subscription.new :username => 'user', :password => '123'
18
+ def initialize(options)
19
+ raise ArgumentError, ':username required' if options[:username].nil?
20
+ raise ArgumentError, ':password required' if options[:password].nil?
21
+
22
+ self.class.debug_output $stdout if options[:debug]
23
+ self.class.base_uri options[:base_uri] || SMSIFIED_ONEAPI_PUBLIC_URI
24
+ @auth = { :username => options[:username], :password => options[:password] }
25
+
26
+ @destination_address = options[:destination_address]
27
+ @sender_address = options[:sender_address]
28
+ end
29
+
30
+ ##
31
+ # Get the delivery status of an outstanding SMS request
32
+ #
33
+ # @param [required, Hash] params to get the delivery status
34
+ # @option params [required, String] :request_id to fetch the status for
35
+ # @option params [optional, String] :sender_address used to send the SMS, required if not provided on initialization of OneAPI
36
+ # @return [Object] A Response Object with http and data instance methods
37
+ # @raise [ArgumentError] of :sender_address is not passed here when not passed on instantiating the object
38
+ # @example
39
+ # one_api.delivery_status :request_id => 'f359193765f6a3149ca76a4508e21234', :sender_address => '14155551212'
40
+ def delivery_status(options)
41
+ raise ArgumentError, ':sender_address is required' if options[:sender_address].nil? && @sender_address.nil?
42
+
43
+ options[:sender_address] = options[:sender_address] || @sender_address
44
+
45
+ Response.new self.class.get("/smsmessaging/outbound/#{options[:sender_address]}/requests/#{options[:request_id]}/deliveryInfos", :basic_auth => @auth)
46
+ end
47
+
48
+ ##
49
+ # Retrieve a single SMS
50
+ #
51
+ # @param [required, String] message_id of the message to retrieve
52
+ # @return [Object] A Response Object with http and data instance methods
53
+ # @example
54
+ # reporting.retrieve_sms '74ae6147f915eabf87b35b9ea30c5916'
55
+ def retrieve_sms(message_id)
56
+ Response.new self.class.get("/messages/#{message_id}", :basic_auth => @auth)
57
+ end
58
+
59
+ ##
60
+ # Retrieve multiple SMS messages based on a query string
61
+ #
62
+ # @param [required, String] query_string to search SMS messages for
63
+ # @return [Object] A Response Object with http and data instance methods
64
+ # @example
65
+ # reporting.search_sms 'startDate=2011-02-14&endDate=2011-02-15'
66
+ def search_sms(query_string)
67
+ Response.new self.class.get("/messages?#{query_string}", :basic_auth => @auth)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,14 @@
1
+ module Smsified
2
+ class Response
3
+ attr_reader :data, :http
4
+
5
+ ##
6
+ # Provides the standard response for the library
7
+ #
8
+ # @param [Object] an HTTParty result object
9
+ def initialize(httparty)
10
+ @data = httparty.parsed_response
11
+ @http = httparty.response
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,147 @@
1
+ module Smsified
2
+ class Subscriptions
3
+ include Helpers
4
+
5
+ include HTTParty
6
+ format :json
7
+
8
+ ##
9
+ # Intantiate a new class to work with subscriptions
10
+ #
11
+ # @param [required, Hash] params to create the user
12
+ # @option params [required, String] :username username to authenticate with
13
+ # @option params [required, String] :password to authenticate with
14
+ # @option params [optional, String] :base_uri of an alternative location of SMSified
15
+ # @option params [optional, String] :destination_address to use with subscriptions
16
+ # @option params [optional, String] :sender_address to use with subscriptions
17
+ # @option params [optional, Boolean] :debug to turn on the HTTparty debugging to stdout
18
+ # @example
19
+ # subscription = Subscription.new :username => 'user', :password => '123'
20
+ def initialize(options)
21
+ raise ArgumentError, ':username required' if options[:username].nil?
22
+ raise ArgumentError, ':password required' if options[:password].nil?
23
+
24
+ self.class.debug_output $stdout if options[:debug]
25
+ self.class.base_uri options[:base_uri] || SMSIFIED_ONEAPI_PUBLIC_URI
26
+ @auth = { :username => options[:username], :password => options[:password] }
27
+
28
+ @destination_address = options[:destination_address]
29
+ @sender_address = options[:sender_address]
30
+ end
31
+
32
+ ##
33
+ # Creates an inbound subscription
34
+ #
35
+ # @param [required, String] destination_address to subscribe to
36
+ # @param [required, Hash] params to send an sms
37
+ # @option params [optional, String] :notify_url to send callbacks to
38
+ # @option params [optional, String] :client_correlator to update
39
+ # @option params [optional, String] :callback_data to update
40
+ # @return [Object] A Response Object with http and data instance methods
41
+ # @param [required, String] notify_url to send callbacks to
42
+ # @return [Object] A Response Object with http and data instance methods
43
+ # @example
44
+ # subscriptions.create_inbound_subscription('tel:+14155551212', :notify_url => 'http://foobar.com')
45
+ def create_inbound_subscription(destination_address, options)
46
+ query = options.merge({ :destination_address => destination_address })
47
+
48
+ Response.new self.class.post("/smsmessaging/inbound/subscriptions",
49
+ :basic_auth => @auth,
50
+ :body => camelcase_keys(query))
51
+ end
52
+
53
+ ##
54
+ # Creates an outbound subscription
55
+ #
56
+ # @param [required, String] sender_address to subscribe to
57
+ # @option params [optional, String] :notify_url to send callbacks to
58
+ # @option params [optional, String] :client_correlator to update
59
+ # @option params [optional, String] :callback_data to update
60
+ # @return [Object] A Response Object with http and data instance methods
61
+ # @example
62
+ # subscriptions.create_outbound_subscription('tel:+14155551212', :notify_url => 'http://foobar.com')
63
+ def create_outbound_subscription(sender_address, options)
64
+ Response.new self.class.post("/smsmessaging/outbound/#{sender_address}/subscriptions",
65
+ :basic_auth => @auth,
66
+ :body => camelcase_keys(options))
67
+ end
68
+
69
+ ##
70
+ # Deletes an inbound subscription
71
+ #
72
+ # @param [required, String] subscription_id to delete
73
+ # @return [Object] A Response Object with http and data instance methods
74
+ # @example
75
+ # subscriptions.delete_inbound_subscription('89edd71c1c7f3d349f9a3a4d5d2d410c')
76
+ def delete_inbound_subscription(subscription_id)
77
+ Response.new self.class.delete("/smsmessaging/inbound/subscriptions/#{subscription_id}", :basic_auth => @auth)
78
+ end
79
+
80
+ ##
81
+ # Deletes an outbound subscription
82
+ #
83
+ # @param [required, String] subscription_id to delete
84
+ # @return [Object] A Response Object with http and data instance methods
85
+ # @example
86
+ # subscriptions.delete_outbound_subscription('89edd71c1c7f3d349f9a3a4d5d2d410c')
87
+ def delete_outbound_subscription(sender_address)
88
+ Response.new self.class.delete("/smsmessaging/outbound/subscriptions/#{sender_address}", :basic_auth => @auth)
89
+ end
90
+
91
+ ##
92
+ # Fetches the inbound subscriptions
93
+ #
94
+ # @param [required, String] destination_address to fetch the subscriptions for
95
+ # @return [Object] A Response Object with http and data instance methods
96
+ # @example
97
+ # subscriptions.inbound_subscriptions('tel:+14155551212')
98
+ def inbound_subscriptions(destination_address)
99
+ Response.new self.class.get("/smsmessaging/inbound/subscriptions?destinationAddress=#{destination_address}", :basic_auth => @auth)
100
+ end
101
+
102
+ ##
103
+ # Fetches the outbound subscriptions
104
+ #
105
+ # @param [required, String] sender_address to fetch the subscriptions for
106
+ # @return [Object] A Response Object with http and data instance methods
107
+ # @example
108
+ # subscriptions.outbound_subscriptions('tel:+14155551212')
109
+ def outbound_subscriptions(sender_address)
110
+ Response.new self.class.get("/smsmessaging/outbound/subscriptions?senderAddress=#{sender_address}", :basic_auth => @auth)
111
+ end
112
+
113
+ ##
114
+ # Updates an inbound subscription
115
+ #
116
+ # @option params [required, String] subscription_id updating
117
+ # @param [required, Hash] params to update the inbound subscription with
118
+ # @option params [optional, String] :notify_url to send callbacks to
119
+ # @option params [optional, String] :client_correlator to update
120
+ # @option params [optional, String] :callback_data to update
121
+ # @return [Object] A Response Object with http and data instance methods
122
+ # @example
123
+ # subscriptions.update_inbound_subscription('89edd71c1c7f3d349f9a3a4d5d2d410c', :notify_url => 'foobar')
124
+ def update_inbound_subscription(subscription_id, options)
125
+ Response.new self.class.post("/smsmessaging/inbound/subscriptions/#{subscription_id}",
126
+ :basic_auth => @auth,
127
+ :body => camelcase_keys(options))
128
+ end
129
+
130
+ ##
131
+ # Updates an outbound subscription
132
+ #
133
+ # @option params [required, String] sender_address updating
134
+ # @param [required, Hash] params to update the outbound subscription with
135
+ # @option params [optional, String] :notify_url to send callbacks to
136
+ # @option params [optional, String] :client_correlator to update
137
+ # @option params [optional, String] :callback_data to update
138
+ # @return [Object] A Response Object with http and data instance methods
139
+ # @example
140
+ # subscriptions.update_outbound_subscription('tel:+14155551212', :notify_url => 'foobar')
141
+ def update_outbound_subscription(sender_address, options)
142
+ Response.new self.class.post("/smsmessaging/outbound/#{sender_address}/subscriptions",
143
+ :basic_auth => @auth,
144
+ :body => camelcase_keys(options))
145
+ end
146
+ end
147
+ end
data/lib/smsified.rb ADDED
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ %w(cgi httparty smsified/helpers smsified/oneapi smsified/subscriptions smsified/reporting smsified/response).each { |lib| require lib }
@@ -0,0 +1,416 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ # These tests are all local unit tests
4
+ FakeWeb.allow_net_connect = false
5
+
6
+ describe "Smsified" do
7
+ before(:all) do
8
+ @username = 'user'
9
+ @password = 'pass'
10
+ @address = '14155551212'
11
+ @sender_address = '13035551212'
12
+ end
13
+
14
+ describe "OneAPI" do
15
+ before(:all) do
16
+ @one_api = Smsified::OneAPI.new :username => @username, :password => @password, :debug => true
17
+
18
+ @message_sent = { "resourceReference" => { "resourceURL" => "https://api.smsified.com/v1/smsmessaging/outbound/tel%3A%2B#{@sender_address}/requests/795bd02c8e343b2dfd673b67dd0ee55a" } }
19
+
20
+ FakeWeb.register_uri(:post,
21
+ "https://#{@username}:#{@password}@api.smsified.com/v1/smsmessaging/outbound/#{@sender_address}/requests",
22
+ :status => ["200", "OK"],
23
+ :body => @message_sent.to_json)
24
+ end
25
+
26
+ it "Should get errors if instantiating without all of the right parameters" do
27
+ begin
28
+ Smsified::OneAPI.new 'foobar'
29
+ rescue => e
30
+ e.to_s.should eql ':username required'
31
+ end
32
+
33
+ begin
34
+ Smsified::OneAPI.new(:username => @username)
35
+ rescue => e
36
+ e.to_s.should eql ':password required'
37
+ end
38
+ end
39
+
40
+ it "Should raise an error if no :sender_address specified" do
41
+ begin
42
+ @one_api.send_sms('foobar')
43
+ rescue => e
44
+ e.to_s.should eql ':sender_address is required'
45
+ end
46
+ end
47
+
48
+ it "Should not raise an error if a :sender_address was specified at instantiation" do
49
+ one_api = Smsified::OneAPI.new :username => @username, :password => @password, :debug => true, :sender_address => @sender_address
50
+ response = one_api.send_sms :address => @address, :message => 'Hola from RSpec!'
51
+ response.data.should eql @message_sent
52
+ end
53
+
54
+ it "Should raise an error if all required params are not passed when sending an SMS" do
55
+ begin
56
+ @one_api.send_sms(:message => 'Hola from RSpec!', :sender_address => @sender_address)
57
+ rescue => e
58
+ e.to_s.should eql ':address is required'
59
+ end
60
+
61
+ begin
62
+ @one_api.send_sms(:address => @address, :sender_address => @sender_address)
63
+ rescue => e
64
+ e.to_s.should eql ':message is required'
65
+ end
66
+ end
67
+
68
+ it "Should instantiate a OneAPI object" do
69
+ oneapi = Smsified::OneAPI.new :username => @username, :password => @password, :debug => true
70
+ oneapi.instance_of?(Smsified::OneAPI).should eql true
71
+ end
72
+
73
+ it "Should send an SMS" do
74
+ response = @one_api.send_sms(:address => @address, :message => 'Hola from RSpec!', :sender_address => @sender_address)
75
+ response.data.should eql @message_sent
76
+ end
77
+
78
+ it "Should send an SMS to multiple destinations" do
79
+ response = @one_api.send_sms(:address => ['14155551212', '13035551212'],
80
+ :message => 'Hola from RSpec!',
81
+ :sender_address => @sender_address)
82
+ response.data.should eql @message_sent
83
+ end
84
+
85
+ it "Should raise an error if you pass an unknown method name" do
86
+ begin
87
+ @one_api.foobar
88
+ rescue => e
89
+ e.to_s.should eql "Unknown method"
90
+ end
91
+ end
92
+ end
93
+
94
+ describe 'Subscriptions' do
95
+ before(:all) do
96
+ @subscriptions = Smsified::Subscriptions.new :username => @username, :password => @password, :debug => true
97
+ end
98
+
99
+ it "Should instantiate a Subscriptions object" do
100
+ smsified = Smsified::Subscriptions.new(:username => @username, :password => @password)
101
+ smsified.instance_of?(Smsified::Subscriptions).should eql true
102
+ end
103
+
104
+ it "Should get errors if instantiating without all of the right parameters" do
105
+ begin
106
+ Smsified::Subscriptions.new 'foobar'
107
+ rescue => e
108
+ e.to_s.should eql ':username required'
109
+ end
110
+
111
+ begin
112
+ Smsified::Subscriptions.new(:username => @username)
113
+ rescue => e
114
+ e.to_s.should eql ':password required'
115
+ end
116
+ end
117
+
118
+ describe 'Listing subscriptions' do
119
+ before(:all) do
120
+ @no_subscription = { "inboundSubscriptionList" => { "numberOfSubscriptions" => "0" } }
121
+
122
+ @inbound_subscriptions = {
123
+ "inboundSubscriptionList" => {
124
+ "inboundSubscription" => [
125
+ {
126
+ "resourceURL" => "https://api.smsified.com/v1/smsmessaging/inbound/subscriptions/3cf88f9cfd0dae96cbfdf16f18c07411",
127
+ "subscriptionId" => "3cf88f9cfd0dae96cbfdf16f18c07411",
128
+ "notificationFormat" => "JSON",
129
+ "destinationAddress" => "tel:+17177455076",
130
+ "notifyURL" => "http://98.207.5.162:8080"
131
+ },
132
+ {
133
+ "resourceURL" => "https://api.smsified.com/v1/smsmessaging/inbound/subscriptions/75bb5bef239aed425c2966cbb95f33c9",
134
+ "subscriptionId" => "75bb5bef239aed425c2966cbb95f33c9",
135
+ "notificationFormat" => "JSON",
136
+ "destinationAddress" => "tel:+17177455076",
137
+ "notifyURL" => "http://98.207.5.162:8080"
138
+ }
139
+ ],
140
+ "numberOfSubscriptions" => "2",
141
+ "resourceURL" => "https://api.smsified.com/v1/smsmessaging/inbound/subscriptions"
142
+ }
143
+ }
144
+
145
+ @outbound_subscriptions = {
146
+ "outboundSubscriptionList" => {
147
+ "numberOfSubscriptions" => "2",
148
+ "resourceURL" => "https://api.smsified.com/v1/smsmessaging/outbound/subscriptions",
149
+ "outboundSubscription" => [
150
+ {
151
+ "senderAddress" => "tel:+17177455076",
152
+ "resourceURL" => "https://api.smsified.com/v1/smsmessaging/outbound/subscriptions/68faa512b1c81ee0d33a6b97004d1212",
153
+ "subscriptionId" => "68faa512b1c81ee0d33a6b97004d1212",
154
+ "notificationFormat" => "JSON",
155
+ "notifyURL" => "http://98.207.5.162:8080"
156
+ },
157
+ {
158
+ "senderAddress" => "tel:+17177455076",
159
+ "resourceURL" => "https://api.smsified.com/v1/smsmessaging/outbound/subscriptions/6e64fb72cd2a27b8a9460caccbd4dc53",
160
+ "subscriptionId" => "6e64fb72cd2a27b8a9460caccbd4dc53",
161
+ "notificationFormat" => "JSON",
162
+ "notifyURL" => "http://98.207.5.162:8080"
163
+ }
164
+ ]
165
+ }
166
+ }
167
+
168
+ FakeWeb.register_uri(:get,
169
+ "https://#{@username}:#{@password}@api.smsified.com/v1/smsmessaging/inbound/subscriptions?destinationAddress=#{@address}",
170
+ :status => ["200", "OK"],
171
+ :body => @no_subscription.to_json)
172
+
173
+ FakeWeb.register_uri(:get,
174
+ "https://#{@username}:#{@password}@api.smsified.com/v1/smsmessaging/inbound/subscriptions?destinationAddress=#{@sender_address}",
175
+ :status => ["200", "OK"],
176
+ :body => @inbound_subscriptions.to_json)
177
+
178
+ FakeWeb.register_uri(:get,
179
+ "https://#{@username}:#{@password}@api.smsified.com/v1/smsmessaging/outbound/subscriptions?senderAddress=#{@sender_address}",
180
+ :status => ["200", "OK"],
181
+ :body => @outbound_subscriptions.to_json)
182
+ end
183
+
184
+ it "Should let me instantiate a OneAPI object and call subscription methods" do
185
+ one_api = Smsified::OneAPI.new :username => @username, :password => @password, :debug => true
186
+ inbound_subscriptions = one_api.inbound_subscriptions(@address)
187
+ inbound_subscriptions.data.should eql @no_subscription
188
+ end
189
+
190
+ it "Should find no subscriptions" do
191
+ inbound_subscriptions = @subscriptions.inbound_subscriptions(@address)
192
+ inbound_subscriptions.data.should eql @no_subscription
193
+ end
194
+
195
+ it "Should get a list of inbound subscriptions" do
196
+ inbound_subscriptions = @subscriptions.inbound_subscriptions(@sender_address)
197
+ inbound_subscriptions.http.code.should eql '200'
198
+ inbound_subscriptions.data.should eql @inbound_subscriptions
199
+ end
200
+
201
+ it "Should get a list of outbound subscriptions" do
202
+ outbound_subscriptions = @subscriptions.outbound_subscriptions(@sender_address)
203
+ outbound_subscriptions.http.code.should eql '200'
204
+ outbound_subscriptions.data.should eql @outbound_subscriptions
205
+ end
206
+ end
207
+
208
+ describe 'Create subscriptions' do
209
+ before(:all) do
210
+ @inbound_subscription = { "resourceReference" => { "resourceURL" => "https://api.smsified.com/v1/smsmessaging/inbound/subscriptions/e636368b7fddac0e93e34ae03bad33dd" } }
211
+ @outbound_subscription = { "resourceReference" => { "resourceURL" => "https://api.smsified.com/v1/smsmessaging/outbound/subscriptions/4bc465cd394c9f5e78802af5ad6bb442" } }
212
+
213
+ FakeWeb.register_uri(:post,
214
+ %r|https://#{@username}:#{@password}@api.smsified.com/v1/smsmessaging/inbound/subscriptions?|,
215
+ :status => ["200", "OK"],
216
+ :body => @inbound_subscription.to_json)
217
+
218
+ FakeWeb.register_uri(:post,
219
+ %r|https://#{@username}:#{@password}@api.smsified.com/v1/smsmessaging/outbound/17177455076/subscriptions?|,
220
+ :status => ["200", "OK"],
221
+ :body => @outbound_subscription.to_json)
222
+ end
223
+
224
+ it 'Should create an inbound subscription' do
225
+ result = @subscriptions.create_inbound_subscription('17177455076', :notify_url => 'http://foobar.com')
226
+ result.http.code.should eql '200'
227
+ result.data.should eql @inbound_subscription
228
+ end
229
+
230
+ it 'Should create an outbound subscription' do
231
+ result = @subscriptions.create_outbound_subscription('17177455076', :notify_url => 'http://foobar.com')
232
+ result.http.code.should eql '200'
233
+ result.data.should eql @outbound_subscription
234
+ end
235
+ end
236
+
237
+ describe 'Updated subscriptions' do
238
+ before(:all) do
239
+ @outbound_subscription = { "resourceReference" => { "resourceURL" => "https://api.smsified.com/v1/smsmessaging/outbound/subscriptions/4bc465cd394c9f5e78802af5ad6bb442" } }
240
+
241
+ FakeWeb.register_uri(:post,
242
+ "https://#{@username}:#{@password}@api.smsified.com/v1/smsmessaging/outbound/#{@sender_address}/subscriptions",
243
+ :status => ["200", "OK"],
244
+ :body => @outbound_subscription.to_json)
245
+ end
246
+
247
+ it 'Should update an inbound subscription' do
248
+ pending('udpate resources being deployed')
249
+ result = @subscriptions.update_inbound_subscription('c880c96f161f6220d4977b29b4bfc111', :notify_url => 'http://foobar1.com')
250
+
251
+ result.http.code.should eql '200'
252
+ result.data.should eql nil
253
+ end
254
+
255
+ it 'Should update an outbound subscription' do
256
+ result = @subscriptions.update_outbound_subscription(@sender_address, :notify_url => 'http://foobar.com')
257
+ result.http.code.should eql '200'
258
+ result.data.should eql @outbound_subscription
259
+ end
260
+ end
261
+
262
+ describe 'Deleting subscriptions' do
263
+ before(:all) do
264
+ FakeWeb.register_uri(:delete,
265
+ %r|https://#{@username}:#{@password}@api.smsified.com/v1/smsmessaging/|,
266
+ :status => ["204", "OK"])
267
+ end
268
+
269
+ it "Should delete an inbound subscription" do
270
+ result = @subscriptions.delete_inbound_subscription('3cf88f9cfd0dae96cbfdf16f18c07411')
271
+ result.http.code.should eql '204'
272
+ end
273
+
274
+ it "Should delete an outbound subscription" do
275
+ result = @subscriptions.delete_outbound_subscription('342b61efc3ba9fd2fd992e58903ef050')
276
+ result.http.code.should eql '204'
277
+ end
278
+ end
279
+ end
280
+
281
+ describe "Reporting" do
282
+ before(:all) do
283
+ @reporting = Smsified::Reporting.new :username => @username, :password => @password, :debug => true
284
+
285
+ @delivery_status = {
286
+ "deliveryInfoList" => {
287
+ "deliveryInfo" => [
288
+ {
289
+ "address" => "tel:+14153675082",
290
+ "parts" => "1",
291
+ "senderAddress" => "tel:+17177455076",
292
+ "messageId" => "74ae6147f915eabf87b35b9ea30c5916",
293
+ "code" => "0",
294
+ "createdDateTime" => 'Fri May 13 16:14:50 UTC 2011',
295
+ "sentDateTime" => 'Fri May 13 16:14:53 UTC 2011',
296
+ "deliveryStatus" => "DeliveredToNetwork",
297
+ "message" => "Hola from RSpec!",
298
+ "direction" => "outbound"
299
+ }
300
+ ],
301
+ "resourceURL" => "https://api.smsified.com/v1/smsmessaging/outbound/tel%3A%2B17177455076/requests/795bd02c8e343b2dfd673b67dd0ee55a/deliveryInfos"
302
+ }
303
+ }
304
+
305
+ @message = { "parts" => 1,
306
+ "sent" => "2011-05-13T16:14:50.480+0000",
307
+ "code" => "0",
308
+ "body" => "Hola from RSpec!",
309
+ "messageId" => "74ae6147f915eabf87b35b9ea30c5916",
310
+ "from" => "17177455076",
311
+ "to" => "14153675082",
312
+ "direction" => "out",
313
+ "status" => "success",
314
+ "created" => "2011-05-13T16:14:50.480+0000"}
315
+
316
+ @message_range = [
317
+ {
318
+ "parts" => 1,
319
+ "sent" => "2011-05-13T20:27:56.690+0000",
320
+ "code" => "-1",
321
+ "body" => "foobar9446",
322
+ "messageId" => "d194e91c32de943ae942ad4043b7905b",
323
+ "from" => "17177455076",
324
+ "to" => "14155551",
325
+ "direction" => "out",
326
+ "status" => "fail",
327
+ "created" => "2011-05-13T20:27:56.690+0000"
328
+ },
329
+ {
330
+ "parts" => 1,
331
+ "sent" => "2011-05-13T20:27:53.660+0000",
332
+ "code" => "-1",
333
+ "body" => "foobar4374",
334
+ "messageId" => "4d9237b323618ab164fb6d646882da99",
335
+ "from" => "17177455076",
336
+ "to" => "14155551212",
337
+ "direction" => "out",
338
+ "status" => "fail",
339
+ "created" => "2011-05-13T20:27:53.660+0000"
340
+ }
341
+ ]
342
+
343
+ FakeWeb.register_uri(:get,
344
+ "https://#{@username}:#{@password}@api.smsified.com/v1/messages/74ae6147f915eabf87b35b9ea30c5916",
345
+ :status => ["200", "OK"],
346
+ :body => @message.to_json)
347
+
348
+ FakeWeb.register_uri(:get,
349
+ "https://#{@username}:#{@password}@api.smsified.com/v1/messages?startDate=2011-05-12&endDate=2011-05-12",
350
+ :status => ["200", "OK"],
351
+ :body => @message_range.to_json)
352
+
353
+ FakeWeb.register_uri(:get,
354
+ "https://#{@username}:#{@password}@api.smsified.com/v1/smsmessaging/outbound/#{@sender_address}/requests/795bd02c8e343b2dfd673b67dd0ee55a/deliveryInfos",
355
+ :status => ["200", "OK"],
356
+ :body => @delivery_status.to_json)
357
+ end
358
+
359
+ it "Should instantiate a Reporting object" do
360
+ reporting = Smsified::Reporting.new :username => 'smsified_tester_smsified', :password => 'bug.fungus52', :debug => true
361
+ reporting.instance_of?(Smsified::Reporting).should eql true
362
+ end
363
+
364
+ it "Should get errors if instantiating without all of the right parameters" do
365
+ begin
366
+ Smsified::Reporting.new 'foobar'
367
+ rescue => e
368
+ e.to_s.should eql ':username required'
369
+ end
370
+
371
+ begin
372
+ Smsified::Reporting.new(:username => @username)
373
+ rescue => e
374
+ e.to_s.should eql ':password required'
375
+ end
376
+ end
377
+
378
+ it "Should raise an error if no :sender_address specified" do
379
+ begin
380
+ @reporting.delivery_status('foobar')
381
+ rescue => e
382
+ e.to_s.should eql ':sender_address is required'
383
+ end
384
+ end
385
+
386
+ it "Should not raise an error if a :sender_address was specified at instantiation" do
387
+ reporting = Smsified::Reporting.new :username => @username, :password => @password, :debug => true, :sender_address => @sender_address
388
+ delivery_response = reporting.delivery_status :request_id => '795bd02c8e343b2dfd673b67dd0ee55a'
389
+ delivery_response.data.should == @delivery_status
390
+ end
391
+
392
+ it "Should retrieve an SMS message" do
393
+ response = @reporting.retrieve_sms '74ae6147f915eabf87b35b9ea30c5916'
394
+ response.data.should eql @message
395
+ end
396
+
397
+ it "Should retrieve SMS messages based on a query string" do
398
+ response = @reporting.search_sms 'startDate=2011-05-12&endDate=2011-05-12'
399
+ response.data.should eql @message_range
400
+ end
401
+
402
+ it "Should send an SMS and get the Delivery status" do
403
+ delivery_response = @reporting.delivery_status :request_id => '795bd02c8e343b2dfd673b67dd0ee55a', :sender_address => @sender_address
404
+ delivery_response.data.should == @delivery_status
405
+ end
406
+
407
+ it "Should let me instantiate a OneAPI object and call reporting methods" do
408
+ one_api = Smsified::OneAPI.new :username => @username, :password => @password, :debug => true
409
+ delivery_response = one_api.delivery_status :request_id => '795bd02c8e343b2dfd673b67dd0ee55a', :sender_address => @sender_address
410
+ delivery_response.data.should eql @delivery_status
411
+
412
+ sms_message = one_api.retrieve_sms '74ae6147f915eabf87b35b9ea30c5916'
413
+ sms_message.data.should eql @message
414
+ end
415
+ end
416
+ end
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'smsified'
5
+ require 'fakeweb'
6
+ require 'awesome_print'
7
+ require 'json'
8
+
9
+ # Requires supporting files with custom matchers and macros, etc,
10
+ # in ./support/ and its subdirectories.
11
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
12
+
13
+ RSpec.configure do |config|
14
+
15
+ end
metadata ADDED
@@ -0,0 +1,213 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smsified
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 3
10
+ version: 0.1.3
11
+ platform: ruby
12
+ authors:
13
+ - Jason Goecke
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-20 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ type: :development
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 2
31
+ - 3
32
+ - 0
33
+ version: 2.3.0
34
+ name: rspec
35
+ version_requirements: *id001
36
+ prerelease: false
37
+ - !ruby/object:Gem::Dependency
38
+ type: :development
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 7
45
+ segments:
46
+ - 0
47
+ - 6
48
+ - 0
49
+ version: 0.6.0
50
+ name: yard
51
+ version_requirements: *id002
52
+ prerelease: false
53
+ - !ruby/object:Gem::Dependency
54
+ type: :development
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 23
61
+ segments:
62
+ - 1
63
+ - 0
64
+ - 0
65
+ version: 1.0.0
66
+ name: bundler
67
+ version_requirements: *id003
68
+ prerelease: false
69
+ - !ruby/object:Gem::Dependency
70
+ type: :development
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ hash: 7
77
+ segments:
78
+ - 1
79
+ - 5
80
+ - 2
81
+ version: 1.5.2
82
+ name: jeweler
83
+ version_requirements: *id004
84
+ prerelease: false
85
+ - !ruby/object:Gem::Dependency
86
+ type: :development
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ name: rcov
97
+ version_requirements: *id005
98
+ prerelease: false
99
+ - !ruby/object:Gem::Dependency
100
+ type: :development
101
+ requirement: &id006 !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 3
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ name: fakeweb
111
+ version_requirements: *id006
112
+ prerelease: false
113
+ - !ruby/object:Gem::Dependency
114
+ type: :development
115
+ requirement: &id007 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: 3
121
+ segments:
122
+ - 0
123
+ version: "0"
124
+ name: awesome_print
125
+ version_requirements: *id007
126
+ prerelease: false
127
+ - !ruby/object:Gem::Dependency
128
+ type: :development
129
+ requirement: &id008 !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ name: json
139
+ version_requirements: *id008
140
+ prerelease: false
141
+ - !ruby/object:Gem::Dependency
142
+ type: :runtime
143
+ requirement: &id009 !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ hash: 3
149
+ segments:
150
+ - 0
151
+ version: "0"
152
+ name: httparty
153
+ version_requirements: *id009
154
+ prerelease: false
155
+ description: Gem for consuming the SMSified OneAPI
156
+ email: jsgoecke@voxeo.com
157
+ executables: []
158
+
159
+ extensions: []
160
+
161
+ extra_rdoc_files:
162
+ - LICENSE.txt
163
+ - README.md
164
+ files:
165
+ - README.md
166
+ - lib/smsified.rb
167
+ - lib/smsified/helpers.rb
168
+ - lib/smsified/oneapi.rb
169
+ - lib/smsified/reporting.rb
170
+ - lib/smsified/response.rb
171
+ - lib/smsified/subscriptions.rb
172
+ - LICENSE.txt
173
+ - examples/sending_and_subscribing.rb
174
+ - spec/smsified_spec.rb
175
+ - spec/spec_helper.rb
176
+ has_rdoc: true
177
+ homepage: http://github.com/tropo/smsified-oneapi
178
+ licenses:
179
+ - MIT
180
+ post_install_message:
181
+ rdoc_options: []
182
+
183
+ require_paths:
184
+ - lib
185
+ required_ruby_version: !ruby/object:Gem::Requirement
186
+ none: false
187
+ requirements:
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ hash: 3
191
+ segments:
192
+ - 0
193
+ version: "0"
194
+ required_rubygems_version: !ruby/object:Gem::Requirement
195
+ none: false
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ hash: 3
200
+ segments:
201
+ - 0
202
+ version: "0"
203
+ requirements: []
204
+
205
+ rubyforge_project:
206
+ rubygems_version: 1.5.2
207
+ signing_key:
208
+ specification_version: 3
209
+ summary: Gem for consuming the SMSified OneAPI
210
+ test_files:
211
+ - examples/sending_and_subscribing.rb
212
+ - spec/smsified_spec.rb
213
+ - spec/spec_helper.rb