groupme-trails 1.1.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/History.txt +49 -0
  2. data/Manifest.txt +55 -0
  3. data/README.txt +46 -0
  4. data/Rakefile +11 -0
  5. data/assets/layouts/default_layout.twiml.builder +4 -0
  6. data/bin/trails +0 -0
  7. data/lib/trails.rb +13 -0
  8. data/lib/trails/exception.rb +6 -0
  9. data/lib/trails/test_helper.rb +147 -0
  10. data/lib/trails/twilio/account.rb +203 -0
  11. data/lib/trails/twilio/call_handling.rb +52 -0
  12. data/lib/trails/twilio/incoming.rb +67 -0
  13. data/lib/twiliorest.rb +115 -0
  14. data/test/example/README +243 -0
  15. data/test/example/Rakefile +10 -0
  16. data/test/example/app/controllers/application_controller.rb +11 -0
  17. data/test/example/app/controllers/calls_controller.rb +8 -0
  18. data/test/example/app/helpers/application_helper.rb +3 -0
  19. data/test/example/app/helpers/calls_helper.rb +2 -0
  20. data/test/example/app/views/calls/index.html.erb +1 -0
  21. data/test/example/app/views/calls/index.twiml.builder +2 -0
  22. data/test/example/config/boot.rb +110 -0
  23. data/test/example/config/database.yml +22 -0
  24. data/test/example/config/environment.rb +43 -0
  25. data/test/example/config/environments/development.rb +17 -0
  26. data/test/example/config/environments/production.rb +28 -0
  27. data/test/example/config/environments/test.rb +28 -0
  28. data/test/example/config/initializers/backtrace_silencers.rb +7 -0
  29. data/test/example/config/initializers/inflections.rb +10 -0
  30. data/test/example/config/initializers/mime_types.rb +5 -0
  31. data/test/example/config/initializers/new_rails_defaults.rb +21 -0
  32. data/test/example/config/initializers/session_store.rb +15 -0
  33. data/test/example/config/locales/en.yml +5 -0
  34. data/test/example/config/routes.rb +43 -0
  35. data/test/example/config/twilio.yml +3 -0
  36. data/test/example/db/development.sqlite3 +0 -0
  37. data/test/example/db/schema.rb +14 -0
  38. data/test/example/db/seeds.rb +7 -0
  39. data/test/example/db/test.sqlite3 +0 -0
  40. data/test/example/doc/README_FOR_APP +2 -0
  41. data/test/example/script/about +4 -0
  42. data/test/example/script/console +3 -0
  43. data/test/example/script/dbconsole +3 -0
  44. data/test/example/script/destroy +3 -0
  45. data/test/example/script/generate +3 -0
  46. data/test/example/script/performance/benchmarker +3 -0
  47. data/test/example/script/performance/profiler +3 -0
  48. data/test/example/script/plugin +3 -0
  49. data/test/example/script/runner +3 -0
  50. data/test/example/script/server +3 -0
  51. data/test/example/test/functional/calls_controller_test.rb +15 -0
  52. data/test/example/test/performance/browsing_test.rb +9 -0
  53. data/test/example/test/test_helper.rb +38 -0
  54. data/test/example/test/unit/helpers/calls_helper_test.rb +4 -0
  55. data/test/test_trails.rb +11 -0
  56. metadata +160 -0
@@ -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
+
@@ -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
@@ -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.
@@ -0,0 +1,11 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.spec 'trails' do
7
+ developer('Hemant Bhanoo', 'hemant@bhanoo.com')
8
+
9
+ end
10
+
11
+ # vim: syntax=ruby
@@ -0,0 +1,4 @@
1
+ xml.instruct!
2
+ xml.Response do
3
+ xml << yield
4
+ end
File without changes
@@ -0,0 +1,13 @@
1
+ module Trails
2
+ VERSION = '1.1.5.1'
3
+ end
4
+ begin
5
+ TwilioRest
6
+ rescue
7
+ require 'twiliorest.rb'
8
+ end
9
+
10
+ require 'trails/exception.rb'
11
+ require 'trails/twilio/account'
12
+ require 'trails/twilio/call_handling'
13
+ require 'trails/twilio/incoming'
@@ -0,0 +1,6 @@
1
+ module Trails
2
+ module Exception
3
+ class UnknownAccount < ::Exception; end
4
+ class InvalidSignature < ::Exception; end
5
+ end # module Exception
6
+ end # module Trails
@@ -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