groupme-trails 1.1.5.1
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/History.txt +49 -0
- data/Manifest.txt +55 -0
- data/README.txt +46 -0
- data/Rakefile +11 -0
- data/assets/layouts/default_layout.twiml.builder +4 -0
- data/bin/trails +0 -0
- data/lib/trails.rb +13 -0
- data/lib/trails/exception.rb +6 -0
- data/lib/trails/test_helper.rb +147 -0
- data/lib/trails/twilio/account.rb +203 -0
- data/lib/trails/twilio/call_handling.rb +52 -0
- data/lib/trails/twilio/incoming.rb +67 -0
- data/lib/twiliorest.rb +115 -0
- data/test/example/README +243 -0
- data/test/example/Rakefile +10 -0
- data/test/example/app/controllers/application_controller.rb +11 -0
- data/test/example/app/controllers/calls_controller.rb +8 -0
- data/test/example/app/helpers/application_helper.rb +3 -0
- data/test/example/app/helpers/calls_helper.rb +2 -0
- data/test/example/app/views/calls/index.html.erb +1 -0
- data/test/example/app/views/calls/index.twiml.builder +2 -0
- data/test/example/config/boot.rb +110 -0
- data/test/example/config/database.yml +22 -0
- data/test/example/config/environment.rb +43 -0
- data/test/example/config/environments/development.rb +17 -0
- data/test/example/config/environments/production.rb +28 -0
- data/test/example/config/environments/test.rb +28 -0
- data/test/example/config/initializers/backtrace_silencers.rb +7 -0
- data/test/example/config/initializers/inflections.rb +10 -0
- data/test/example/config/initializers/mime_types.rb +5 -0
- data/test/example/config/initializers/new_rails_defaults.rb +21 -0
- data/test/example/config/initializers/session_store.rb +15 -0
- data/test/example/config/locales/en.yml +5 -0
- data/test/example/config/routes.rb +43 -0
- data/test/example/config/twilio.yml +3 -0
- data/test/example/db/development.sqlite3 +0 -0
- data/test/example/db/schema.rb +14 -0
- data/test/example/db/seeds.rb +7 -0
- data/test/example/db/test.sqlite3 +0 -0
- data/test/example/doc/README_FOR_APP +2 -0
- data/test/example/script/about +4 -0
- data/test/example/script/console +3 -0
- data/test/example/script/dbconsole +3 -0
- data/test/example/script/destroy +3 -0
- data/test/example/script/generate +3 -0
- data/test/example/script/performance/benchmarker +3 -0
- data/test/example/script/performance/profiler +3 -0
- data/test/example/script/plugin +3 -0
- data/test/example/script/runner +3 -0
- data/test/example/script/server +3 -0
- data/test/example/test/functional/calls_controller_test.rb +15 -0
- data/test/example/test/performance/browsing_test.rb +9 -0
- data/test/example/test/test_helper.rb +38 -0
- data/test/example/test/unit/helpers/calls_helper_test.rb +4 -0
- data/test/test_trails.rb +11 -0
- metadata +160 -0
data/History.txt
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
=== 1.1.5.1 / 2010-07-15
|
2
|
+
|
3
|
+
* Make Rails 3 - compatible by removing RAILS_ROOT and RAILS_ENV
|
4
|
+
|
5
|
+
=== 1.1.5 / 2010-06-02
|
6
|
+
|
7
|
+
* test support for call guid/call status
|
8
|
+
|
9
|
+
=== 1.1.4 / 2010-05-09
|
10
|
+
|
11
|
+
Backwards-compatible support for environment-specific twilio configuration
|
12
|
+
|
13
|
+
=== 1.1.1 / 2010-03-16
|
14
|
+
|
15
|
+
Typo fix.
|
16
|
+
|
17
|
+
=== 1.1.0 / 2010-03-14
|
18
|
+
|
19
|
+
Twilio's SMS API has changed since the beta release (no url specified for handling sms responses).
|
20
|
+
* Update the send_sms call to reflect that (backwards-incompatible change)
|
21
|
+
* Start cleaning up the documentation a bit.
|
22
|
+
|
23
|
+
=== 1.0.5 / 2010-03-06
|
24
|
+
|
25
|
+
* Ugh. accidentally released with unchecked-in code. undoing.
|
26
|
+
|
27
|
+
=== 1.0.4 / 2010-03-06
|
28
|
+
|
29
|
+
* Clean up logging a bit
|
30
|
+
|
31
|
+
=== 1.0.3 / 2010-03-06
|
32
|
+
|
33
|
+
* Fix Manifest so all required files get added (!)
|
34
|
+
|
35
|
+
=== 1.0.2 / 2010-02-06
|
36
|
+
|
37
|
+
* Add support for default twiml layout
|
38
|
+
* Add example and tests
|
39
|
+
|
40
|
+
=== 1.0.1 / 2010-02-06
|
41
|
+
|
42
|
+
* Fix basic errors; still no tests :(
|
43
|
+
|
44
|
+
=== 1.0.0 / 2010-02-05
|
45
|
+
|
46
|
+
* 1 major enhancement
|
47
|
+
|
48
|
+
* Birthday!
|
49
|
+
|
data/Manifest.txt
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
assets/layouts/default_layout.twiml.builder
|
6
|
+
bin/trails
|
7
|
+
lib/trails.rb
|
8
|
+
lib/trails/exception.rb
|
9
|
+
lib/trails/test_helper.rb
|
10
|
+
lib/trails/twilio/account.rb
|
11
|
+
lib/trails/twilio/call_handling.rb
|
12
|
+
lib/trails/twilio/incoming.rb
|
13
|
+
lib/twiliorest.rb
|
14
|
+
test/example/README
|
15
|
+
test/example/Rakefile
|
16
|
+
test/example/app/controllers/application_controller.rb
|
17
|
+
test/example/app/controllers/calls_controller.rb
|
18
|
+
test/example/app/helpers/application_helper.rb
|
19
|
+
test/example/app/helpers/calls_helper.rb
|
20
|
+
test/example/app/views/calls/index.html.erb
|
21
|
+
test/example/app/views/calls/index.twiml.builder
|
22
|
+
test/example/config/boot.rb
|
23
|
+
test/example/config/database.yml
|
24
|
+
test/example/config/environment.rb
|
25
|
+
test/example/config/environments/development.rb
|
26
|
+
test/example/config/environments/production.rb
|
27
|
+
test/example/config/environments/test.rb
|
28
|
+
test/example/config/initializers/backtrace_silencers.rb
|
29
|
+
test/example/config/initializers/inflections.rb
|
30
|
+
test/example/config/initializers/mime_types.rb
|
31
|
+
test/example/config/initializers/new_rails_defaults.rb
|
32
|
+
test/example/config/initializers/session_store.rb
|
33
|
+
test/example/config/locales/en.yml
|
34
|
+
test/example/config/routes.rb
|
35
|
+
test/example/config/twilio.yml
|
36
|
+
test/example/db/development.sqlite3
|
37
|
+
test/example/db/schema.rb
|
38
|
+
test/example/db/seeds.rb
|
39
|
+
test/example/db/test.sqlite3
|
40
|
+
test/example/doc/README_FOR_APP
|
41
|
+
test/example/script/about
|
42
|
+
test/example/script/console
|
43
|
+
test/example/script/dbconsole
|
44
|
+
test/example/script/destroy
|
45
|
+
test/example/script/generate
|
46
|
+
test/example/script/performance/benchmarker
|
47
|
+
test/example/script/performance/profiler
|
48
|
+
test/example/script/plugin
|
49
|
+
test/example/script/runner
|
50
|
+
test/example/script/server
|
51
|
+
test/example/test/functional/calls_controller_test.rb
|
52
|
+
test/example/test/performance/browsing_test.rb
|
53
|
+
test/example/test/test_helper.rb
|
54
|
+
test/example/test/unit/helpers/calls_helper_test.rb
|
55
|
+
test/test_trails.rb
|
data/README.txt
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
= trails
|
2
|
+
|
3
|
+
* http://code.google.com/p/twilio-on-rails/
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Makes developing twilio applications (even) easier in rails.
|
8
|
+
Support for SMS, twiml MimeType alias, functional test helpers.
|
9
|
+
|
10
|
+
== FEATURES/PROBLEMS:
|
11
|
+
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
|
15
|
+
class ApplicationController < ActionController::Base
|
16
|
+
..
|
17
|
+
include Trails::Twilio::CallHandling
|
18
|
+
..
|
19
|
+
end
|
20
|
+
|
21
|
+
== REQUIREMENTS:
|
22
|
+
|
23
|
+
* twilio-rails REST library (provided by twilio)
|
24
|
+
|
25
|
+
== INSTALL:
|
26
|
+
|
27
|
+
* sudo gem install trails
|
28
|
+
|
29
|
+
== DEVELOPERS:
|
30
|
+
|
31
|
+
|
32
|
+
== LICENSE:
|
33
|
+
|
34
|
+
Copyright 2010 Hemant Bhanoo
|
35
|
+
|
36
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
37
|
+
you may not use this file except in compliance with the License.
|
38
|
+
You may obtain a copy of the License at
|
39
|
+
|
40
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
41
|
+
|
42
|
+
Unless required by applicable law or agreed to in writing, software
|
43
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
44
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
45
|
+
See the License for the specific language governing permissions and
|
46
|
+
limitations under the License.
|
data/Rakefile
ADDED
data/bin/trails
ADDED
File without changes
|
data/lib/trails.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module Trails
|
5
|
+
module TestHelper
|
6
|
+
def open_session_as_twilio( as_twilio_opts = {}, *args )
|
7
|
+
session = open_session( *args )
|
8
|
+
modify_session_with_twilio_opts( session, as_twilio_opts )
|
9
|
+
session
|
10
|
+
end
|
11
|
+
|
12
|
+
def as_twilio_sms( twilio_opts = {}, &block )
|
13
|
+
twilio_opts[:sms] = true
|
14
|
+
as_twilio( twilio_opts, &block )
|
15
|
+
end
|
16
|
+
|
17
|
+
def as_twilio( as_twilio_opts = {}, &block )
|
18
|
+
if( @integration_session )
|
19
|
+
modify_session_with_twilio_opts( @integration_session, as_twilio_opts )
|
20
|
+
# end integration test
|
21
|
+
elsif( @controller ) # ok we're in a functional test
|
22
|
+
# mess with the controller, allowing us to add parameters
|
23
|
+
header_modifier = lambda{ |h,o| modify_headers_with_twilio_opts( h, o ) }
|
24
|
+
param_modifier = lambda{ |p,o| modify_params_with_twilio_opts( p, o ) }
|
25
|
+
@controller.metaclass.send( :define_method, :process_with_twilio_as_caller ) do |request, response|
|
26
|
+
# unfortunately we have to reach a little deep into the request here...
|
27
|
+
parameters_to_add = {}
|
28
|
+
header_modifier.call( request.env, as_twilio_opts )
|
29
|
+
param_modifier.call( parameters_to_add, as_twilio_opts )
|
30
|
+
|
31
|
+
# add_parameters
|
32
|
+
unless( parameters_to_add.blank? )
|
33
|
+
request.instance_variable_set( :@_memoized_query_string, nil ) # cause the query string to be un-memoized
|
34
|
+
add_parameters( parameters_to_add )
|
35
|
+
end
|
36
|
+
|
37
|
+
process_without_twilio_as_caller( request, response )
|
38
|
+
end # def process_with_twilio_as_caller
|
39
|
+
@controller.metaclass.send( :alias_method_chain, :process, :twilio_as_caller )
|
40
|
+
|
41
|
+
# need to to easily add parameters
|
42
|
+
@controller.metaclass.send( :define_method, :add_parameters ) do |params|
|
43
|
+
params ||= {}
|
44
|
+
request.query_parameters.merge!( params )
|
45
|
+
new_uri = request.request_uri + '&' + params.
|
46
|
+
collect{|k,v| "#{CGI::escape(k.to_s)}=#{CGI::escape(v.to_s)}"}.
|
47
|
+
join('&')
|
48
|
+
request.set_REQUEST_URI( new_uri )
|
49
|
+
request.__send__( :instance_variable_set, :@parameters, nil )
|
50
|
+
end # add_parameters
|
51
|
+
end # functional test
|
52
|
+
|
53
|
+
# cool. call the controller action now:
|
54
|
+
block.call()
|
55
|
+
|
56
|
+
end # as_twilio
|
57
|
+
|
58
|
+
# message defaults to @response.body
|
59
|
+
def assert_length_of_sms( message = nil )
|
60
|
+
message ||= @response.body
|
61
|
+
assert_block( build_message( "SMS should have been no longer than ? characters, but was ? characters.",
|
62
|
+
Trails::Twilio::Account::MAX_SMS_LENGTH, message.size ) ) {
|
63
|
+
message.size <= Trails::Twilio::Account::MAX_SMS_LENGTH
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def user_presses( digits )
|
69
|
+
{ 'Digits' => digits }
|
70
|
+
end
|
71
|
+
|
72
|
+
def user_records( sound_url )
|
73
|
+
{ 'RecordingUrl' => sound_url }
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
def modify_session_with_twilio_opts( session, as_twilio_opts )
|
78
|
+
|
79
|
+
header_modifier = lambda{ |h,o| modify_headers_with_twilio_opts( h, o ) }
|
80
|
+
param_modifier = lambda{ |p,o| modify_params_with_twilio_opts( p, o ) }
|
81
|
+
|
82
|
+
session_twilio_opts = as_twilio_opts.dup
|
83
|
+
session_twilio_opts[:call_guid] ||= generate_call_guid
|
84
|
+
|
85
|
+
session.metaclass.send( :define_method, :process_with_twilio_as_caller ) do |method, path, params, headers|
|
86
|
+
params ||= {}
|
87
|
+
headers ||= {}
|
88
|
+
|
89
|
+
header_modifier.call( headers, session_twilio_opts )
|
90
|
+
param_modifier.call( params, session_twilio_opts )
|
91
|
+
|
92
|
+
process_without_twilio_as_caller( method, path, params, headers )
|
93
|
+
end # define process_with_twilio_as_caller
|
94
|
+
session.metaclass.send( :alias_method_chain, :process, :twilio_as_caller )
|
95
|
+
end
|
96
|
+
|
97
|
+
def modify_headers_with_twilio_opts( headers, as_twilio_opts )
|
98
|
+
account = if( as_twilio_opts[:account].blank? )
|
99
|
+
cfg = Twilio::Account.send( :config )
|
100
|
+
cfg[cfg.keys.first]
|
101
|
+
else
|
102
|
+
as_twilio_opts[:account]
|
103
|
+
end
|
104
|
+
headers['HTTP_X_TWILIO_ACCOUNTSID'] = account[:sid]
|
105
|
+
end
|
106
|
+
|
107
|
+
def modify_params_with_twilio_opts( params, as_twilio_opts )
|
108
|
+
caller = as_twilio_opts[:caller] || '4155551212'
|
109
|
+
called = as_twilio_opts[:called] || '6155556161'
|
110
|
+
from = as_twilio_opts[:from] || '6665554321'
|
111
|
+
to = as_twilio_opts[:to] || '3334445678'
|
112
|
+
status = as_twilio_opts[:call_status] || 'in-progress'
|
113
|
+
guid = as_twilio_opts[ :call_guid ] || generate_call_guid
|
114
|
+
params['Caller'] = caller
|
115
|
+
params['Called'] = called
|
116
|
+
params['From'] = from
|
117
|
+
params['To'] = to
|
118
|
+
params['CallStatus'] ||= status
|
119
|
+
params['CallGuid'] ||= guid
|
120
|
+
params['SmsMessageSid'] = 'DummyMessageSid' if( as_twilio_opts[:sms] )
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
module IntegrationDSL
|
125
|
+
end
|
126
|
+
|
127
|
+
def generate_call_guid
|
128
|
+
'CA_FAKE_' + SecureRandom.hex( 12 )
|
129
|
+
end
|
130
|
+
|
131
|
+
end # module TestHelper
|
132
|
+
end # module Trails
|
133
|
+
|
134
|
+
# open up the TwilioRest::Account class so that we can keep track of faked requests
|
135
|
+
class TwilioRest::Account
|
136
|
+
@@fake_requests ||= []
|
137
|
+
def self.faked_requests
|
138
|
+
return @@fake_requests
|
139
|
+
end
|
140
|
+
def request_with_fake( url, method, params )
|
141
|
+
@@fake_requests.push( OpenStruct.new( :url => url, :method => method, :params => params ) )
|
142
|
+
fake_response = OpenStruct.new
|
143
|
+
fake_response.body = 'Fake Body'
|
144
|
+
fake_response
|
145
|
+
end
|
146
|
+
alias_method_chain :request, :fake
|
147
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
module Trails
|
2
|
+
module Twilio
|
3
|
+
class Account
|
4
|
+
attr_reader :config
|
5
|
+
def initialize( opts = {} )
|
6
|
+
_logger = opts[:logger] || ActiveRecord::Base.logger rescue Logger.new( STDERR )
|
7
|
+
if( !opts.blank? )
|
8
|
+
_logger.warn "overriding default opts #{self.class.config.inspect} with #{opts.inspect}"
|
9
|
+
else
|
10
|
+
opts = self.class.config[self.class.config.keys.first]
|
11
|
+
end
|
12
|
+
@config = opts.dup
|
13
|
+
@sid = @config[:sid] || raise( "no sid specified on #{self}" )
|
14
|
+
@token = @config[:token]
|
15
|
+
@logger = _logger
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.sid_from_request( request )
|
19
|
+
( :development == Rails.env.to_sym ) ? request.params['AccountSid'] : request.env["HTTP_X_TWILIO_ACCOUNTSID"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.from_request( request )
|
23
|
+
sid = sid_from_request( request )
|
24
|
+
unless( config.has_key?( sid ) )
|
25
|
+
logger.warn{ "unknown twilio account #{sid}. Request params: #{request.inspect}" }
|
26
|
+
raise Trails::Exception::UnknownAccount.new( sid )
|
27
|
+
end
|
28
|
+
account = new( config[sid].dup )
|
29
|
+
raise Trails::Exception::InvalidSignature unless account.verify_caller( request )
|
30
|
+
account
|
31
|
+
end
|
32
|
+
|
33
|
+
def verify_caller( request )
|
34
|
+
# TODO: check caller credentials here. :)
|
35
|
+
return true
|
36
|
+
end
|
37
|
+
|
38
|
+
# Make outgoing calls:
|
39
|
+
# Required:
|
40
|
+
# - number
|
41
|
+
# - handler_url
|
42
|
+
#
|
43
|
+
# Options:
|
44
|
+
# - :caller
|
45
|
+
# - :method
|
46
|
+
# - :timeout
|
47
|
+
def call( number, handler_url, opts = {} )
|
48
|
+
params = {
|
49
|
+
'Caller' => opts['Caller'] || opts[:caller],
|
50
|
+
'Called' => number,
|
51
|
+
'Url' => handler_url,
|
52
|
+
'Method' => opts['Method'] || opts[:method] || 'GET',
|
53
|
+
'Timeout' => opts['Timeout'] || opts[:timeout] || 15
|
54
|
+
}
|
55
|
+
|
56
|
+
if if_machine = opts[:if_machine]
|
57
|
+
params['IfMachine'] = if_machine.to_s.capitalize
|
58
|
+
end
|
59
|
+
|
60
|
+
request( 'Calls', 'POST', params )
|
61
|
+
end
|
62
|
+
|
63
|
+
MAX_SMS_LENGTH = 160
|
64
|
+
# Required:
|
65
|
+
# - number: to
|
66
|
+
# - body: text
|
67
|
+
#
|
68
|
+
# Options:
|
69
|
+
# - :from: number
|
70
|
+
# - :method: GET/POST
|
71
|
+
#
|
72
|
+
def send_sms( number, body, opts = {} )
|
73
|
+
params = {
|
74
|
+
'From' => opts[:from] || @config[:default_number],
|
75
|
+
'To' => number,
|
76
|
+
'Body' => body,
|
77
|
+
'Method' => opts[:method] || 'POST'
|
78
|
+
}
|
79
|
+
request( 'SMS/Messages', 'POST', params )
|
80
|
+
end
|
81
|
+
|
82
|
+
# Sample Response:
|
83
|
+
# [{"SmsFallbackUrl"=>nil, "SmsUrl"=>nil, "PhoneNumber"=>"4253954994", "AccountSid"=>"AC6c25b3d8b4f0a2a4e49e4936398a2180", "Capabilities"=>{"SMS"=>"false", "Voice"=>"false"}, "Method"=>"POST", "Sid"=>"PNc939a026d5a332d22c23ca94a161ce29", "DateUpdated"=>"Sat, 20 Mar 2010 17:52:33 -0700", "DateCreated"=>"Sat, 20 Mar 2010 17:52:33 -0700", "Url"=>nil, "FriendlyName"=>"(425) 395-4994", "VoiceFallbackUrl"=>nil, "SmsFallbackMethod"=>"POST", "VoiceCallerIdLookup"=>"false", "SmsMethod"=>"POST", "VoiceFallbackMethod"=>"POST"}]
|
84
|
+
def incoming_numbers( reset = false )
|
85
|
+
if( @incoming_numbers.nil? || reset )
|
86
|
+
response =
|
87
|
+
request( 'IncomingPhoneNumbers', 'GET' )
|
88
|
+
|
89
|
+
if( 200 == response.code.to_i )
|
90
|
+
@raw_incoming_numbers = Hash.from_xml( response.body )
|
91
|
+
else
|
92
|
+
raise "got response code #{response.code} and body #{response.body}"
|
93
|
+
end
|
94
|
+
@incoming_numbers = [@raw_incoming_numbers['TwilioResponse']['IncomingPhoneNumbers']['IncomingPhoneNumber']].flatten # returns an array even when it's a single entry
|
95
|
+
end
|
96
|
+
return @incoming_numbers
|
97
|
+
end
|
98
|
+
|
99
|
+
def outgoing_numbers( reset = false )
|
100
|
+
if( @outgoing_numbers.nil? || reset )
|
101
|
+
response =
|
102
|
+
request( 'OutgoingCallerIds', 'GET' )
|
103
|
+
@outgoing_numbers_raw = Hpricot( response.body ) if( 200 == response.code.to_i )
|
104
|
+
@outgoing_numbers = @outgoing_numbers_raw.search( '//phonenumber').
|
105
|
+
collect{|j| j.inner_html}
|
106
|
+
end
|
107
|
+
return @outgoing_numbers
|
108
|
+
end
|
109
|
+
|
110
|
+
# options: [:area_code, :friendly_name, :url, :sms_url]
|
111
|
+
# sameple return:
|
112
|
+
# {"SmsFallbackUrl"=>nil,
|
113
|
+
# "SmsUrl"=>nil,
|
114
|
+
# "PhoneNumber"=>"4253954994",
|
115
|
+
# "AccountSid"=>"AC6c25b3d8b4f0a2a4e49e4936398a2180",
|
116
|
+
# "Capabilities"=>{"SMS"=>"false",
|
117
|
+
# "Voice"=>"false"},
|
118
|
+
# "Method"=>"POST",
|
119
|
+
# "Sid"=>"PNc939a026d5a332d22c23ca94a161ce29",
|
120
|
+
# "DateUpdated"=>"Sat,
|
121
|
+
# 20 Mar 2010 17:52:33 -0700",
|
122
|
+
# "DateCreated"=>"Sat,
|
123
|
+
# 20 Mar 2010 17:52:33 -0700",
|
124
|
+
# "Url"=>nil,
|
125
|
+
# "FriendlyName"=>"(425) 395-4994",
|
126
|
+
# "VoiceFallbackUrl"=>nil,
|
127
|
+
# "SmsFallbackMethod"=>"POST",
|
128
|
+
# "VoiceCallerIdLookup"=>"false",
|
129
|
+
# "SmsMethod"=>"POST",
|
130
|
+
# "VoiceFallbackMethod"=>"POST"}
|
131
|
+
def provision_number( options = {} )
|
132
|
+
params = {}
|
133
|
+
[:area_code, :friendly_name, :url, :sms_url].each do |key|
|
134
|
+
params[key.to_s.camelize] = options[key] if options.has_key?( key )
|
135
|
+
end
|
136
|
+
|
137
|
+
response = request( 'IncomingPhoneNumbers/Local', 'POST', params )
|
138
|
+
if( 201 == response.code.to_i )
|
139
|
+
raw_number_response = Hash.from_xml( response.body )
|
140
|
+
else
|
141
|
+
raise "while trying to acquire a new number, got response #{response.code} and body: #{response.body}"
|
142
|
+
end
|
143
|
+
raw_number_response["TwilioResponse"]["IncomingPhoneNumber"]
|
144
|
+
end
|
145
|
+
|
146
|
+
def release_number( sid )
|
147
|
+
request( File.join( 'IncomingPhoneNumbers', sid ), 'DELETE' )
|
148
|
+
end
|
149
|
+
|
150
|
+
# just specify the resource (e.g. 'Calls' ) and it will
|
151
|
+
# append it to the base uri ("/#{api_version}/Accounts/#{sid}/")
|
152
|
+
# and then call twilio.
|
153
|
+
def request( resource, method = 'GET', params = {})
|
154
|
+
url = File.join( base_uri, resource )
|
155
|
+
make_request( url, method, params )
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
protected
|
160
|
+
|
161
|
+
|
162
|
+
# This makes it easy to create and call the TwilioRest library without
|
163
|
+
# having to worry about where credentials come from and stuff.
|
164
|
+
def make_request( *args )
|
165
|
+
@twilio_account ||= TwilioRest::Account.new( @sid, @token )
|
166
|
+
logger.debug{ "making twilio request with #{args.inspect}" }
|
167
|
+
@twilio_account.request( *args )
|
168
|
+
end
|
169
|
+
|
170
|
+
def base_uri( opts = {} )
|
171
|
+
api_version = opts[:api_version] || @api_version || '2008-08-01'
|
172
|
+
sid = opts[:sid] || @sid
|
173
|
+
"/#{api_version}/Accounts/#{sid}/"
|
174
|
+
end
|
175
|
+
|
176
|
+
def logger
|
177
|
+
self.class.logger
|
178
|
+
end
|
179
|
+
def self.logger
|
180
|
+
return @logger unless @logger.nil?
|
181
|
+
@logger = Logger.new( STDERR )
|
182
|
+
@logger.level = Logger::WARN
|
183
|
+
return @logger
|
184
|
+
end
|
185
|
+
def self.config
|
186
|
+
@@all_cfg ||= YAML::load_file( config_file ).freeze
|
187
|
+
# allow per-environment configuration
|
188
|
+
@@cfg ||= if ( @@all_cfg.has_key?( Rails.env ) )
|
189
|
+
@@all_cfg[ Rails.env ]
|
190
|
+
elsif( @@all_cfg.has_key?( 'default' ) )
|
191
|
+
@@all_cfg['default']
|
192
|
+
else
|
193
|
+
@@all_cfg
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.config_file
|
198
|
+
return Rails.root.join('config', 'twilio.yml').to_s
|
199
|
+
end
|
200
|
+
|
201
|
+
end # class Account
|
202
|
+
end # module Twilio
|
203
|
+
end # module Trails
|