em-smsified 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +20 -0
- data/README.md +66 -0
- data/examples/local_test.rb +40 -0
- data/examples/sending_and_subscribing.rb +68 -0
- data/lib/em-smsified/base.rb +100 -0
- data/lib/em-smsified/helpers.rb +61 -0
- data/lib/em-smsified/incoming_message.rb +35 -0
- data/lib/em-smsified/oneapi.rb +49 -0
- data/lib/em-smsified/reporting.rb +59 -0
- data/lib/em-smsified/response.rb +41 -0
- data/lib/em-smsified/subscriptions.rb +137 -0
- data/lib/em-smsified.rb +15 -0
- data/spec/em-smsified_spec.rb +559 -0
- data/spec/spec_helper.rb +16 -0
- metadata +183 -0
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,66 @@
|
|
1
|
+
em-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 with EventMachine.
|
7
|
+
|
8
|
+
This library was originally released by Tropo at http://github.com/smsified/smsified-ruby by Jason Goecke and John Dyer. It has been modified to work in the context of EventMachine by Kristian Kristensen.
|
9
|
+
|
10
|
+
Installation
|
11
|
+
------------
|
12
|
+
|
13
|
+
gem install em-smsified
|
14
|
+
|
15
|
+
Example
|
16
|
+
-------
|
17
|
+
|
18
|
+
All of the API methods take an anonymous block which is the method called when the server returns. It yields the response so you can access the result of executing the API operation. The examples below illustrates this. If you don't care about the result of the operation, don't pass a block.
|
19
|
+
|
20
|
+
Send an SMS:
|
21
|
+
|
22
|
+
require 'rubygems'
|
23
|
+
require 'em-smsified'
|
24
|
+
require 'eventmachine'
|
25
|
+
|
26
|
+
oneapi = Smsified::OneAPI.new(:username => 'user', :password => 'bug.fungus24')
|
27
|
+
|
28
|
+
EM.run do
|
29
|
+
oneapi.send_sms :address => '14155551212', :message => 'Hi there!', :sender_address => '13035551212'
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
Find a subscription:
|
34
|
+
|
35
|
+
require 'rubygems'
|
36
|
+
require 'smsified'
|
37
|
+
require 'eventmachine'
|
38
|
+
|
39
|
+
subscriptions = Smsified::Subscriptions.new(:username => 'user', :password => 'bug.fungus24')
|
40
|
+
|
41
|
+
EM.run do
|
42
|
+
subscriptions.inbound_subscriptions('17177455076')
|
43
|
+
end
|
44
|
+
|
45
|
+
Parse the JSON for a callback Incoming Message:
|
46
|
+
|
47
|
+
require 'rubygems'
|
48
|
+
require 'smsified'
|
49
|
+
|
50
|
+
# Also require your favorite web framework such as Rails or Sinatra
|
51
|
+
incoming_message = Smsified::IncomingMessage.new json_body
|
52
|
+
puts incoming_message.date_time # Wed May 11 18:05:54 UTC 2011
|
53
|
+
puts incoming_message.destination_address # '16575550100'
|
54
|
+
puts incoming_message.message # 'Inbound test'
|
55
|
+
puts incoming_message.message_id # 'ef795d3dac56a62fef3ff1852b0c123a'
|
56
|
+
puts incoming_message.sender_address # '14075550100'
|
57
|
+
|
58
|
+
Documentation
|
59
|
+
-------------
|
60
|
+
|
61
|
+
May be found at http://kristiankristensen.github.com/em-smsified & http://smsified.com.
|
62
|
+
|
63
|
+
License
|
64
|
+
-------
|
65
|
+
|
66
|
+
MIT - See LICENSE.txt
|
@@ -0,0 +1,40 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
require 'rubygems'
|
3
|
+
require 'smsified'
|
4
|
+
require 'yaml'
|
5
|
+
require 'eventmachine'
|
6
|
+
|
7
|
+
config = YAML.load(File.open('examples/config.yml'))
|
8
|
+
|
9
|
+
|
10
|
+
EM.run do
|
11
|
+
Signal.trap("INT") { EM.stop}
|
12
|
+
Signal.trap("TRAP") { EM.stop}
|
13
|
+
|
14
|
+
puts "Hit CTRL-C to stop"
|
15
|
+
puts "=================="
|
16
|
+
puts "Server started at " + Time.now.to_s
|
17
|
+
|
18
|
+
smsified = Smsified::OneAPI.new( :username => config['smsified']['username'],
|
19
|
+
:password => config['smsified']['password'],
|
20
|
+
:sender_address => '12892050134'
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
puts "Send SMS started " + Time.now.to_s
|
25
|
+
|
26
|
+
# smsified.send_sms(:message => 'Hello there!',
|
27
|
+
# :address => '19179712649',
|
28
|
+
#:notify_url => config['postbin'],
|
29
|
+
# :sender_address => '12892050134') do |http|
|
30
|
+
# puts "Response returned " + Time.now.to_s
|
31
|
+
# puts http.data
|
32
|
+
# puts http.http
|
33
|
+
# end
|
34
|
+
|
35
|
+
puts "Reporting Request started " + Time.now.to_s
|
36
|
+
smsified.delivery_status(:request_id => 'e7e12f5d6870447a8599bb420e5e9a0d') do |resp|
|
37
|
+
puts "Response returned " + Time.now.to_s
|
38
|
+
puts resp.data
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
##
|
2
|
+
# Run this file from the smsified root dir, ie. :
|
3
|
+
# ruby examples/sending_and_subscribing.rb
|
4
|
+
#
|
5
|
+
# Remember to copy config.yml.sample to config.yml and insert your SMSified credentials
|
6
|
+
# Also you need to change the "sender_address" parameter below to your registered SMSified number, and the "receiver_address" to the mobile number you want to send texts to.
|
7
|
+
#
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__), '..', 'lib')
|
10
|
+
require 'rubygems'
|
11
|
+
require 'smsified'
|
12
|
+
require 'yaml'
|
13
|
+
require 'eventmachine'
|
14
|
+
|
15
|
+
config = YAML.load(File.open('examples/config.yml'))
|
16
|
+
|
17
|
+
smsified = EventMachine::Smsified::OneAPI.new(:username => config['smsified']['username'],
|
18
|
+
:password => config['smsified']['password'])
|
19
|
+
|
20
|
+
sender_address = '14157044517'
|
21
|
+
receiver_address = '17177455076'
|
22
|
+
|
23
|
+
EM.run do
|
24
|
+
Signal.trap("INT") { EM.stop}
|
25
|
+
Signal.trap("TRAP") { EM.stop}
|
26
|
+
|
27
|
+
puts "Hit CTRL-C to stop"
|
28
|
+
puts "=================="
|
29
|
+
puts "Server started at " + Time.now.to_s
|
30
|
+
|
31
|
+
|
32
|
+
puts "Send an SMS to one address " + Time.now.to_s
|
33
|
+
smsified.send_sms( :message => 'Hello there!',
|
34
|
+
:address => receiver_address,
|
35
|
+
:notify_url => config['postbin'],
|
36
|
+
:sender_address => sender_address) do |result|
|
37
|
+
puts result.data.inspect
|
38
|
+
puts result.http.inspect
|
39
|
+
end
|
40
|
+
|
41
|
+
puts "Send an SMS to multiple addresses" + Time.now.to_s
|
42
|
+
smsified.send_sms( :message => 'Hello there, multiple recipients!',
|
43
|
+
:address => [receiver_address, receiver_address],
|
44
|
+
:notify_url => config['postbin'],
|
45
|
+
:sender_address => sender_address) do |result|
|
46
|
+
puts "Response returned " + Time.now.to_s
|
47
|
+
puts result.data.inspect
|
48
|
+
puts result.http.inspect
|
49
|
+
end
|
50
|
+
|
51
|
+
puts "Create in inbound subscription" + Time.now.to_s
|
52
|
+
smsified.create_inbound_subscription( sender_address,
|
53
|
+
:notify_url => config['postbin']
|
54
|
+
) do |result|
|
55
|
+
puts "Response returned " + Time.now.to_s
|
56
|
+
puts result.data.inspect
|
57
|
+
puts result.http.inspect
|
58
|
+
end
|
59
|
+
|
60
|
+
puts "Get some of your sent SMS details" + Time.now.to_s
|
61
|
+
smsified.search_sms( 'start=2011-11-14&end=2011-11-15') do |result|
|
62
|
+
puts "Response returned " + Time.now.to_s
|
63
|
+
puts result.data.inspect
|
64
|
+
puts result.data.inspect
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Smsified
|
3
|
+
SMSIFIED_ONEAPI_PUBLIC_URI = 'https://api.smsified.com/v1'
|
4
|
+
SMSIFIED_HTTP_HEADERS = { 'Content-Type' => 'application/x-www-form-urlencoded','Accept'=>'application/json' }
|
5
|
+
|
6
|
+
class Base
|
7
|
+
attr_reader :base_uri, :auth, :destination_address, :sender_address
|
8
|
+
|
9
|
+
##
|
10
|
+
# Intantiate a new class to work with OneAPI
|
11
|
+
#
|
12
|
+
# @param [required, Hash] params to create the user
|
13
|
+
# @option params [required, String] :username username to authenticate with
|
14
|
+
# @option params [required, String] :password to authenticate with
|
15
|
+
# @option params [optional, String] :base_uri of an alternative location of SMSified
|
16
|
+
# @option params [optional, String] :destination_address to use with subscriptions
|
17
|
+
# @option params [optional, String] :sender_address to use with subscriptions
|
18
|
+
# @option params [optional, Boolean] :debug to turn on the HTTparty debugging to stdout
|
19
|
+
# @raise [ArgumentError] if :username is not passed as an option
|
20
|
+
# @raise [ArgumentError] if :password is not passed as an option
|
21
|
+
def initialize(options)
|
22
|
+
raise ArgumentError, 'an options Hash is required' if !options.instance_of?(Hash)
|
23
|
+
raise ArgumentError, ':username required' if options[:username].nil?
|
24
|
+
raise ArgumentError, ':password required' if options[:password].nil?
|
25
|
+
|
26
|
+
@base_uri = options[:base_uri] || SMSIFIED_ONEAPI_PUBLIC_URI
|
27
|
+
@auth = { :username => options[:username], :password => options[:password] }
|
28
|
+
|
29
|
+
@destination_address = options[:destination_address]
|
30
|
+
@sender_address = options[:sender_address]
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# HTTP GET's a request
|
35
|
+
# @param [required, String] :url to GET from
|
36
|
+
#
|
37
|
+
def get(url, headers)
|
38
|
+
conn = create_connection_object(url)
|
39
|
+
|
40
|
+
http = conn.get(:head => add_authorization_to_header(headers, @auth))
|
41
|
+
|
42
|
+
action = proc do
|
43
|
+
response = Response.new(http.response.parsed, http)#.response.raw)
|
44
|
+
yield response if block_given?
|
45
|
+
end
|
46
|
+
|
47
|
+
http.callback &action
|
48
|
+
http.errback &action
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# HTTP DELETE's a request
|
53
|
+
# @param [required, String] :url to GET from
|
54
|
+
#
|
55
|
+
def delete(url, headers)
|
56
|
+
conn = create_connection_object(url)
|
57
|
+
|
58
|
+
http = conn.delete(:head => add_authorization_to_header(headers, @auth))
|
59
|
+
|
60
|
+
action = proc do
|
61
|
+
response = Response.new(http.response.parsed, http)#.response.raw)
|
62
|
+
yield response if block_given?
|
63
|
+
end
|
64
|
+
|
65
|
+
http.callback &action
|
66
|
+
http.errback &action
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# HTTP POST's a request
|
71
|
+
# @param [required, String] :url to GET from
|
72
|
+
#
|
73
|
+
def post(url, body, headers)
|
74
|
+
conn = create_connection_object(url)
|
75
|
+
|
76
|
+
http = conn.post(:body => body,
|
77
|
+
:head => add_authorization_to_header(headers, @auth))
|
78
|
+
|
79
|
+
action = proc do
|
80
|
+
response = Response.new(http.response.parsed, http)#.response.raw)
|
81
|
+
yield response if block_given?
|
82
|
+
end
|
83
|
+
|
84
|
+
http.callback &action
|
85
|
+
http.errback &action
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
def create_connection_object(url)
|
90
|
+
conn = EM::HttpRequest.new(SMSIFIED_ONEAPI_PUBLIC_URI + url)
|
91
|
+
conn.use JSONify
|
92
|
+
return conn
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_authorization_to_header(headers, auth)
|
96
|
+
return headers.merge({'Authorization' => [auth[:username], auth[:password]]})
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Smsified
|
3
|
+
module Helpers
|
4
|
+
private
|
5
|
+
|
6
|
+
##
|
7
|
+
# Camelcases the options
|
8
|
+
def camelcase_keys(options)
|
9
|
+
options = options.clone
|
10
|
+
|
11
|
+
if options[:destination_address]
|
12
|
+
options[:destinationAddress] = options[:destination_address]
|
13
|
+
options.delete(:destination_address)
|
14
|
+
end
|
15
|
+
|
16
|
+
if options[:notify_url]
|
17
|
+
options[:notifyURL] = options[:notify_url]
|
18
|
+
options.delete(:notify_url)
|
19
|
+
end
|
20
|
+
|
21
|
+
if options[:client_correlator]
|
22
|
+
options[:clientCorrelator] = options[:client_correlator]
|
23
|
+
options.delete(:client_correlator)
|
24
|
+
end
|
25
|
+
|
26
|
+
if options[:callback_data]
|
27
|
+
options[:callbackData] = options[:callback_data]
|
28
|
+
options.delete(:callback_data)
|
29
|
+
end
|
30
|
+
|
31
|
+
options
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Builds the necessary query string
|
36
|
+
def build_query_string(options)
|
37
|
+
options = camelcase_keys(options)
|
38
|
+
|
39
|
+
query = ''
|
40
|
+
|
41
|
+
options.each do |k,v|
|
42
|
+
if k == :address
|
43
|
+
if RUBY_VERSION.to_f == 1.9
|
44
|
+
if v.instance_of?(String)
|
45
|
+
v.each_line { |address| query += "#{ '&' if query != '' }address=#{CGI.escape address}" }
|
46
|
+
else
|
47
|
+
v.each { |address| query += "#{ '&' if query != '' }address=#{CGI.escape address}" }
|
48
|
+
end
|
49
|
+
else
|
50
|
+
v.each { |address| query += "#{ '&' if query != '' }address=#{CGI.escape address}" }
|
51
|
+
end
|
52
|
+
else
|
53
|
+
query += "#{ '&' if query != '' }#{k.to_s}=#{CGI.escape v}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
query
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Smsified
|
3
|
+
class IncomingMessage
|
4
|
+
attr_reader :date_time, :destination_address, :message, :message_id, :sender_address, :json
|
5
|
+
|
6
|
+
##
|
7
|
+
# Intantiate a new object to provide convenience methods on an Incoming Message
|
8
|
+
# http://www.smsified.com/sms-api-documentation/receiving
|
9
|
+
#
|
10
|
+
# @param [required, String] valid JSON for an Incoming Message to be parsed
|
11
|
+
# @return [Object] the parsed incoming message
|
12
|
+
# @raise [ArgumentError] if json is not valid JSON or an Incoming Message type
|
13
|
+
# @example
|
14
|
+
# incoming_message = IncomingMessage.new(json)
|
15
|
+
# puts incoming_message.message # foobar
|
16
|
+
def initialize(json)
|
17
|
+
begin
|
18
|
+
@json = JSON.parse json
|
19
|
+
|
20
|
+
contents = @json['inboundSMSMessageNotification']['inboundSMSMessage']
|
21
|
+
|
22
|
+
@date_time = Time.parse contents['dateTime']
|
23
|
+
@destination_address = contents['destinationAddress']
|
24
|
+
@message = contents['message']
|
25
|
+
@message_id = contents['messageId']
|
26
|
+
@sender_address = contents['senderAddress']
|
27
|
+
rescue => error
|
28
|
+
raise MessageError, "Not valid JSON or IncomingMessage"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class MessageError < StandardError; end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Smsified
|
3
|
+
class OneAPI < Base
|
4
|
+
include Helpers
|
5
|
+
include SubscriptionsModule
|
6
|
+
include ReportingModule
|
7
|
+
|
8
|
+
##
|
9
|
+
# @example
|
10
|
+
# one_api = OneAPI.new :username => 'user', :password => '123'
|
11
|
+
def initialize(options)
|
12
|
+
super(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Send an SMS to one or more addresses
|
17
|
+
#
|
18
|
+
# @param [required, Hash] params to send an sms
|
19
|
+
# @option params [required, String] :address to send the SMS to
|
20
|
+
# @option params [required, String] :message to send with the SMS
|
21
|
+
# @option params [optional, String] :sender_address to use with subscriptions, required if not provided on initialization of OneAPI
|
22
|
+
# @option params [optional, String] :notify_url to send callbacks to
|
23
|
+
# @param
|
24
|
+
# @return [Object] A Response Object with http and data instance methods
|
25
|
+
# @raise [ArgumentError] if :sender_address is not passed as an option when not passed on object creation
|
26
|
+
# @raise [ArgumentError] if :address is not provided as an option
|
27
|
+
# @raise [ArgumentError] if :message is not provided as an option
|
28
|
+
# @example
|
29
|
+
# one_api.send_sms :address => '14155551212', :message => 'Hi there!', :sender_address => '13035551212'
|
30
|
+
# one_api.send_sms :address => ['14155551212', '13035551212'], :message => 'Hi there!', :sender_address => '13035551212'
|
31
|
+
# one_api.send_sms(:address => '14155551212', :message => 'Hi there!', :sender_address => '13035551212') do |result| ... end
|
32
|
+
def send_sms(options, &blk)
|
33
|
+
raise ArgumentError, 'an options Hash is required' if !options.instance_of?(Hash)
|
34
|
+
raise ArgumentError, ':sender_address is required' if options[:sender_address].nil? && @sender_address.nil?
|
35
|
+
raise ArgumentError, ':address is required' if options[:address].nil?
|
36
|
+
raise ArgumentError, ':message is required' if options[:message].nil?
|
37
|
+
|
38
|
+
options[:sender_address] = options[:sender_address] || @sender_address
|
39
|
+
query_options = options.clone
|
40
|
+
query_options.delete(:sender_address)
|
41
|
+
query_options = camelcase_keys(query_options)
|
42
|
+
|
43
|
+
post("/smsmessaging/outbound/#{options[:sender_address]}/requests",
|
44
|
+
build_query_string(query_options),
|
45
|
+
SMSIFIED_HTTP_HEADERS, &blk)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Smsified
|
3
|
+
module ReportingModule
|
4
|
+
##
|
5
|
+
# Get the delivery status of an outstanding SMS request
|
6
|
+
#
|
7
|
+
# @param [required, Hash] params to get the delivery status
|
8
|
+
# @option params [required, String] :request_id to fetch the status for
|
9
|
+
# @option params [optional, String] :sender_address used to send the SMS, required if not provided on initialization of OneAPI
|
10
|
+
# @return [Object] A Response Object with http and data instance methods
|
11
|
+
# @raise [ArgumentError] of :sender_address is not passed here when not passed on instantiating the object
|
12
|
+
# @example
|
13
|
+
# one_api.delivery_status :request_id => 'f359193765f6a3149ca76a4508e21234', :sender_address => '14155551212'
|
14
|
+
def delivery_status(options, &blk)
|
15
|
+
raise ArgumentError, 'an options Hash is required' if !options.instance_of?(Hash)
|
16
|
+
raise ArgumentError, ':sender_address is required' if options[:sender_address].nil? && @sender_address.nil?
|
17
|
+
|
18
|
+
options[:sender_address] = options[:sender_address] || @sender_address
|
19
|
+
|
20
|
+
get("/smsmessaging/outbound/#{options[:sender_address]}/requests/#{options[:request_id]}/deliveryInfos", SMSIFIED_HTTP_HEADERS, &blk)
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Retrieve a single SMS
|
25
|
+
#
|
26
|
+
# @param [required, String] message_id of the message to retrieve
|
27
|
+
# @return [Object] A Response Object with http and data instance methods
|
28
|
+
# @example
|
29
|
+
# reporting.retrieve_sms '74ae6147f915eabf87b35b9ea30c5916'
|
30
|
+
def retrieve_sms(message_id, &blk)
|
31
|
+
get("/messages/#{message_id}", SMSIFIED_HTTP_HEADERS, &blk)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Retrieve multiple SMS messages based on a query string
|
36
|
+
#
|
37
|
+
# @param [required, String] query_string to search SMS messages for
|
38
|
+
# @return [Object] A Response Object with http and data instance methods
|
39
|
+
# @example
|
40
|
+
# reporting.search_sms 'start=2011-02-14&end=2011-02-15'
|
41
|
+
def search_sms(query_string, &blk)
|
42
|
+
get("/messages?#{query_string}", SMSIFIED_HTTP_HEADERS, &blk)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
class Reporting < Base
|
48
|
+
include ReportingModule
|
49
|
+
##
|
50
|
+
# Intantiate a new class to work with reporting
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
# subscription = Subscription.new :username => 'user', :password => '123'
|
54
|
+
def initialize(options)
|
55
|
+
super(options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Smsified
|
3
|
+
|
4
|
+
##
|
5
|
+
# Functions as a proxy on the EventMachine HTTP Response so you can get the raw and parsed response
|
6
|
+
#
|
7
|
+
class ResponseProxy
|
8
|
+
attr_reader :raw, :parsed
|
9
|
+
|
10
|
+
def initialize(parsed, raw)
|
11
|
+
@parsed = parsed
|
12
|
+
@raw = raw
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Used by em-http-request to parse the JSON coming in
|
18
|
+
#
|
19
|
+
class JSONify
|
20
|
+
def response(resp)
|
21
|
+
resp.response = ResponseProxy.new(Yajl::Parser.parse(resp.response), resp.response)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# The result object from the API. Used to access the parsed and raw HTTP response.
|
27
|
+
#
|
28
|
+
class Response
|
29
|
+
attr_reader :data, :http
|
30
|
+
|
31
|
+
##
|
32
|
+
# Provides the standard response for the library
|
33
|
+
#
|
34
|
+
# @param [Object] an HTTParty result object
|
35
|
+
def initialize(parsed, raw)
|
36
|
+
@data = parsed
|
37
|
+
@http = raw
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Smsified
|
3
|
+
module SubscriptionsModule
|
4
|
+
##
|
5
|
+
# Creates an inbound subscription
|
6
|
+
#
|
7
|
+
# @param [required, String] destination_address to subscribe to
|
8
|
+
# @param [required, Hash] params to send an sms
|
9
|
+
# @option params [optional, String] :notify_url to send callbacks to
|
10
|
+
# @option params [optional, String] :client_correlator to update
|
11
|
+
# @option params [optional, String] :callback_data to update
|
12
|
+
# @return [Object] A Response Object with http and data instance methods
|
13
|
+
# @param [required, String] notify_url to send callbacks to
|
14
|
+
# @return [Object] A Response Object with http and data instance methods
|
15
|
+
# @example
|
16
|
+
# subscriptions.create_inbound_subscription('tel:+14155551212', :notify_url => 'http://foobar.com')
|
17
|
+
def create_inbound_subscription(destination_address, options, &blk)
|
18
|
+
query = options.merge({ :destination_address => destination_address })
|
19
|
+
|
20
|
+
post("/smsmessaging/inbound/subscriptions",
|
21
|
+
camelcase_keys(query),
|
22
|
+
SMSIFIED_HTTP_HEADERS, &blk
|
23
|
+
)
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Creates an outbound subscription
|
29
|
+
#
|
30
|
+
# @param [required, String] sender_address to subscribe to
|
31
|
+
# @option params [optional, String] :notify_url to send callbacks to
|
32
|
+
# @option params [optional, String] :client_correlator to update
|
33
|
+
# @option params [optional, String] :callback_data to update
|
34
|
+
# @return [Object] A Response Object with http and data instance methods
|
35
|
+
# @example
|
36
|
+
# subscriptions.create_outbound_subscription('tel:+14155551212', :notify_url => 'http://foobar.com')
|
37
|
+
def create_outbound_subscription(sender_address, options, &blk)
|
38
|
+
post("/smsmessaging/outbound/#{sender_address}/subscriptions",
|
39
|
+
build_query_string(options),
|
40
|
+
SMSIFIED_HTTP_HEADERS, &blk
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Deletes an inbound subscription
|
46
|
+
#
|
47
|
+
# @param [required, String] subscription_id to delete
|
48
|
+
# @return [Object] A Response Object with http and data instance methods
|
49
|
+
# @example
|
50
|
+
# subscriptions.delete_inbound_subscription('89edd71c1c7f3d349f9a3a4d5d2d410c')
|
51
|
+
def delete_inbound_subscription(subscription_id, &blk)
|
52
|
+
delete("/smsmessaging/inbound/subscriptions/#{subscription_id}", SMSIFIED_HTTP_HEADERS, &blk)
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Deletes an outbound subscription
|
57
|
+
#
|
58
|
+
# @param [required, String] subscription_id to delete
|
59
|
+
# @return [Object] A Response Object with http and data instance methods
|
60
|
+
# @example
|
61
|
+
# subscriptions.delete_outbound_subscription('89edd71c1c7f3d349f9a3a4d5d2d410c')
|
62
|
+
def delete_outbound_subscription(sender_address, &blk)
|
63
|
+
delete("/smsmessaging/outbound/subscriptions/#{sender_address}", SMSIFIED_HTTP_HEADERS, &blk)
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Fetches the inbound subscriptions
|
68
|
+
#
|
69
|
+
# @param [required, String] destination_address to fetch the subscriptions for
|
70
|
+
# @return [Object] A Response Object with http and data instance methods
|
71
|
+
# @example
|
72
|
+
# subscriptions.inbound_subscriptions('tel:+14155551212')
|
73
|
+
def inbound_subscriptions(destination_address, &blk)
|
74
|
+
get("/smsmessaging/inbound/subscriptions?destinationAddress=#{destination_address}", SMSIFIED_HTTP_HEADERS, &blk)
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Fetches the outbound subscriptions
|
79
|
+
#
|
80
|
+
# @param [required, String] sender_address to fetch the subscriptions for
|
81
|
+
# @return [Object] A Response Object with http and data instance methods
|
82
|
+
# @example
|
83
|
+
# subscriptions.outbound_subscriptions('tel:+14155551212')
|
84
|
+
def outbound_subscriptions(sender_address, &blk)
|
85
|
+
get("/smsmessaging/outbound/subscriptions?senderAddress=#{sender_address}", SMSIFIED_HTTP_HEADERS, &blk)
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Updates an inbound subscription
|
90
|
+
#
|
91
|
+
# @option params [required, String] subscription_id updating
|
92
|
+
# @param [required, Hash] params to update the inbound subscription with
|
93
|
+
# @option params [optional, String] :notify_url to send callbacks to
|
94
|
+
# @option params [optional, String] :client_correlator to update
|
95
|
+
# @option params [optional, String] :callback_data to update
|
96
|
+
# @return [Object] A Response Object with http and data instance methods
|
97
|
+
# @example
|
98
|
+
# subscriptions.update_inbound_subscription('89edd71c1c7f3d349f9a3a4d5d2d410c', :notify_url => 'foobar')
|
99
|
+
def update_inbound_subscription(subscription_id, options, &blk)
|
100
|
+
post("/smsmessaging/inbound/subscriptions/#{subscription_id}",
|
101
|
+
build_query_string(options),
|
102
|
+
SMSIFIED_HTTP_HEADERS, &blk
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
##
|
107
|
+
# Updates an outbound subscription
|
108
|
+
#
|
109
|
+
# @option params [required, String] sender_address updating
|
110
|
+
# @param [required, Hash] params to update the outbound subscription with
|
111
|
+
# @option params [optional, String] :notify_url to send callbacks to
|
112
|
+
# @option params [optional, String] :client_correlator to update
|
113
|
+
# @option params [optional, String] :callback_data to update
|
114
|
+
# @return [Object] A Response Object with http and data instance methods
|
115
|
+
# @example
|
116
|
+
# subscriptions.update_outbound_subscription('tel:+14155551212', :notify_url => 'foobar')
|
117
|
+
def update_outbound_subscription(sender_address, options, &blk)
|
118
|
+
post("/smsmessaging/outbound/#{sender_address}/subscriptions", build_query_string(options),
|
119
|
+
SMSIFIED_HTTP_HEADERS, &blk
|
120
|
+
)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class Subscriptions < Base
|
125
|
+
include Helpers
|
126
|
+
include SubscriptionsModule
|
127
|
+
##
|
128
|
+
# Intantiate a new class to work with subscriptions
|
129
|
+
#
|
130
|
+
# @example
|
131
|
+
# subscription = Subscription.new :username => 'user', :password => '123'
|
132
|
+
def initialize(options)
|
133
|
+
super(options)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|