groupme-trails 1.1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|