Permalink
Browse files

import attempt from google code

  • Loading branch information...
1 parent 0f2ca8c commit 14b7f4a0a9eb75dcd7b8e1c4dc0275d2bd630949 Hemant Bhanoo committed Mar 19, 2010
Showing with 1,337 additions and 245 deletions.
  1. +37 −0 History.txt
  2. +56 −0 Manifest.txt
  3. +46 −0 README.txt
  4. +11 −0 Rakefile
  5. +4 −0 assets/layouts/default_layout.twiml.builder
  6. 0 bin/trails
  7. +13 −0 lib/trails.rb
  8. +6 −0 lib/trails/exception.rb
  9. +22 −6 twilio-test.rb → lib/trails/test_helper.rb
  10. +143 −0 lib/trails/twilio/account.rb
  11. +52 −0 lib/trails/twilio/call_handling.rb
  12. +63 −0 lib/trails/twilio/incoming.rb
  13. +115 −0 lib/twiliorest.rb
  14. +243 −0 test/example/README
  15. +10 −0 test/example/Rakefile
  16. +11 −0 test/example/app/controllers/application_controller.rb
  17. +8 −0 test/example/app/controllers/calls_controller.rb
  18. +3 −0 test/example/app/helpers/application_helper.rb
  19. +2 −0 test/example/app/helpers/calls_helper.rb
  20. +1 −0 test/example/app/views/calls/index.html.erb
  21. +2 −0 test/example/app/views/calls/index.twiml.builder
  22. +110 −0 test/example/config/boot.rb
  23. +22 −0 test/example/config/database.yml
  24. +43 −0 test/example/config/environment.rb
  25. +17 −0 test/example/config/environments/development.rb
  26. +28 −0 test/example/config/environments/production.rb
  27. +28 −0 test/example/config/environments/test.rb
  28. +7 −0 test/example/config/initializers/backtrace_silencers.rb
  29. +10 −0 test/example/config/initializers/inflections.rb
  30. +5 −0 test/example/config/initializers/mime_types.rb
  31. +21 −0 test/example/config/initializers/new_rails_defaults.rb
  32. +15 −0 test/example/config/initializers/session_store.rb
  33. +5 −0 test/example/config/locales/en.yml
  34. +43 −0 test/example/config/routes.rb
  35. +3 −0 test/example/config/twilio.yml
  36. BIN test/example/db/development.sqlite3
  37. +14 −0 test/example/db/schema.rb
  38. +7 −0 test/example/db/seeds.rb
  39. BIN test/example/db/test.sqlite3
  40. +2 −0 test/example/doc/README_FOR_APP
  41. +1 −0 test/example/log/test.log
  42. +4 −0 test/example/script/about
  43. +3 −0 test/example/script/console
  44. +3 −0 test/example/script/dbconsole
  45. +3 −0 test/example/script/destroy
  46. +3 −0 test/example/script/generate
  47. +3 −0 test/example/script/performance/benchmarker
  48. +3 −0 test/example/script/performance/profiler
  49. +3 −0 test/example/script/plugin
  50. +3 −0 test/example/script/runner
  51. +3 −0 test/example/script/server
  52. +15 −0 test/example/test/functional/calls_controller_test.rb
  53. +9 −0 test/example/test/performance/browsing_test.rb
  54. +38 −0 test/example/test/test_helper.rb
  55. +4 −0 test/example/test/unit/helpers/calls_helper_test.rb
  56. +11 −0 test/test_trails.rb
  57. +0 −239 twilio.rb
View
@@ -0,0 +1,37 @@
+=== 1.1.1 / 2010-03-16
+
+Typo fix.
+
+=== 1.1.0 / 2010-03-14
+
+Twilio's SMS API has changed since the beta release (no url specified for handling sms responses).
+* Update the send_sms call to reflect that (backwards-incompatible change)
+* Start cleaning up the documentation a bit.
+
+=== 1.0.5 / 2010-03-06
+
+* Ugh. accidentally released with unchecked-in code. undoing.
+
+=== 1.0.4 / 2010-03-06
+
+* Clean up logging a bit
+
+=== 1.0.3 / 2010-03-06
+
+* Fix Manifest so all required files get added (!)
+
+=== 1.0.2 / 2010-02-06
+
+* Add support for default twiml layout
+* Add example and tests
+
+=== 1.0.1 / 2010-02-06
+
+* Fix basic errors; still no tests :(
+
+=== 1.0.0 / 2010-02-05
+
+* 1 major enhancement
+
+ * Birthday!
+
View
@@ -0,0 +1,56 @@
+.autotest
+History.txt
+Manifest.txt
+README.txt
+Rakefile
+assets/layouts/default_layout.twiml.builder
+bin/trails
+lib/trails.rb
+lib/trails/exception.rb
+lib/trails/test_helper.rb
+lib/trails/twilio/account.rb
+lib/trails/twilio/call_handling.rb
+lib/trails/twilio/incoming.rb
+lib/twiliorest.rb
+test/example/README
+test/example/Rakefile
+test/example/app/controllers/application_controller.rb
+test/example/app/controllers/calls_controller.rb
+test/example/app/helpers/application_helper.rb
+test/example/app/helpers/calls_helper.rb
+test/example/app/views/calls/index.html.erb
+test/example/app/views/calls/index.twiml.builder
+test/example/config/boot.rb
+test/example/config/database.yml
+test/example/config/environment.rb
+test/example/config/environments/development.rb
+test/example/config/environments/production.rb
+test/example/config/environments/test.rb
+test/example/config/initializers/backtrace_silencers.rb
+test/example/config/initializers/inflections.rb
+test/example/config/initializers/mime_types.rb
+test/example/config/initializers/new_rails_defaults.rb
+test/example/config/initializers/session_store.rb
+test/example/config/locales/en.yml
+test/example/config/routes.rb
+test/example/config/twilio.yml
+test/example/db/development.sqlite3
+test/example/db/schema.rb
+test/example/db/seeds.rb
+test/example/db/test.sqlite3
+test/example/doc/README_FOR_APP
+test/example/script/about
+test/example/script/console
+test/example/script/dbconsole
+test/example/script/destroy
+test/example/script/generate
+test/example/script/performance/benchmarker
+test/example/script/performance/profiler
+test/example/script/plugin
+test/example/script/runner
+test/example/script/server
+test/example/test/functional/calls_controller_test.rb
+test/example/test/performance/browsing_test.rb
+test/example/test/test_helper.rb
+test/example/test/unit/helpers/calls_helper_test.rb
+test/test_trails.rb
View
@@ -0,0 +1,46 @@
+= trails
+
+* http://code.google.com/p/twilio-on-rails/
+
+== DESCRIPTION:
+
+Makes developing twilio applications (even) easier in rails.
+Support for SMS, twiml MimeType alias, functional test helpers.
+
+== FEATURES/PROBLEMS:
+
+
+== SYNOPSIS:
+
+ class ApplicationController < ActionController::Base
+ ..
+ include Twilio::CallHandling
+ ..
+ end
+
+== REQUIREMENTS:
+
+* twilio-rails REST library (provided by twilio)
+
+== INSTALL:
+
+* sudo gem install trails
+
+== DEVELOPERS:
+
+
+== LICENSE:
+
+ Copyright 2010 Hemant Bhanoo
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
View
@@ -0,0 +1,11 @@
+# -*- ruby -*-
+
+require 'rubygems'
+require 'hoe'
+
+Hoe.spec 'trails' do
+ developer('Hemant Bhanoo', 'hemant@bhanoo.com')
+
+end
+
+# vim: syntax=ruby
@@ -0,0 +1,4 @@
+xml.instruct!
+xml.Response do
+ xml << yield
+end
View
No changes.
View
@@ -0,0 +1,13 @@
+module Trails
+ VERSION = '1.1.2'
+end
+begin
+ TwilioRest
+rescue
+ require 'twiliorest.rb'
+end
+
+require 'trails/exception.rb'
+require 'trails/twilio/account'
+require 'trails/twilio/call_handling'
+require 'trails/twilio/incoming'
View
@@ -0,0 +1,6 @@
+module Trails
+ module Exception
+ class UnknownAccount < ::Exception; end
+ class InvalidSignature < ::Exception; end
+ end # module Exception
+end # module Trails
@@ -1,13 +1,18 @@
require 'ostruct'
-module Twilio
+module Trails
module TestHelper
def open_session_as_twilio( as_twilio_opts = {}, *args )
session = open_session( *args )
modify_session_with_twilio_opts( session, as_twilio_opts )
session
end
+ def as_twilio_sms( twilio_opts = {}, &block )
+ twilio_opts[:sms] = true
+ as_twilio( twilio_opts, &block )
+ end
+
def as_twilio( as_twilio_opts = {}, &block )
if( @integration_session )
modify_session_with_twilio_opts( @integration_session, as_twilio_opts )
@@ -48,6 +53,16 @@ def as_twilio( as_twilio_opts = {}, &block )
block.call()
end # as_twilio
+
+ # message defaults to @response.body
+ def assert_length_of_sms( message = nil )
+ message ||= @response.body
+ assert_block( build_message( "SMS should have been no longer than ? characters, but was ? characters.",
+ Trails::Twilio::Account::MAX_SMS_LENGTH, message.size ) ) {
+ message.size <= Trails::Twilio::Account::MAX_SMS_LENGTH
+ }
+ end
+
def user_presses( digits )
{ 'Digits' => digits }
@@ -88,30 +103,31 @@ def modify_headers_with_twilio_opts( headers, as_twilio_opts )
def modify_params_with_twilio_opts( params, as_twilio_opts )
caller = as_twilio_opts[:caller] || '4155551212'
called = as_twilio_opts[:called] || '6155556161'
+ from = as_twilio_opts[:from] || '6665554321'
params['Caller'] = caller
params['Called'] = called
+ params['From'] = from
+ params['SmsMessageSid'] = 'DummyMessageSid' if( as_twilio_opts[:sms] )
end
private
module IntegrationDSL
end
end # module TestHelper
-end # module Twilio
+end # module Trails
+# open up the TwilioRest::Account class so that we can keep track of faked requests
class TwilioRest::Account
+ @@fake_requests ||= []
def self.faked_requests
return @@fake_requests
end
def request_with_fake( url, method, params )
- @@fake_requests ||= []
@@fake_requests.push( OpenStruct.new( :url => url, :method => method, :params => params ) )
fake_response = OpenStruct.new
fake_response.body = 'Fake Body'
fake_response
end
alias_method_chain :request, :fake
end
-
-
-
@@ -0,0 +1,143 @@
+module Trails
+ module Twilio
+ class Account
+ attr_reader :config
+ def initialize( opts = {} )
+ _logger = opts[:logger] || ActiveRecord::Base.logger rescue Logger.new( STDERR )
+ if( !opts.blank? )
+ _logger.warn "overriding default opts #{self.class.config.inspect} with #{opts.inspect}"
+ else
+ opts = self.class.config[self.class.config.keys.first]
+ end
+ @config = opts.dup
+ @sid = @config[:sid] || raise( "no sid specified on #{self}" )
+ @token = @config[:token]
+ @logger = _logger
+ end
+
+ def self.sid_from_request( request )
+ ( :development == RAILS_ENV.to_sym ) ? request.params['AccountSid'] : request.env["HTTP_X_TWILIO_ACCOUNTSID"]
+ end
+
+ def self.from_request( request )
+ sid = sid_from_request( request )
+ unless( config.has_key?( sid ) )
+ logger.warn{ "unknown twilio account #{sid}. Request params: #{request.inspect}" }
+ raise Trails::Exception::UnknownAccount.new( sid )
+ end
+ account = new( config[sid].dup )
+ raise Trails::Exception::InvalidSignature unless account.verify_caller( request )
+ account
+ end
+
+ def verify_caller( request )
+ # TODO: check caller credentials here. :)
+ return true
+ end
+
+ # Make outgoing calls:
+ # Required:
+ # - number
+ # - handler_url
+ #
+ # Options:
+ # - :caller
+ # - :method
+ # - :timeout
+ def call( number, handler_url, opts = {} )
+ params = {
+ 'Caller' => opts['Caller'] || opts[:caller],
+ 'Called' => number,
+ 'Url' => handler_url,
+ 'Method' => opts['Method'] || opts[:method] || 'GET',
+ 'Timeout' => opts['Timeout'] || opts[:timeout] || 15
+ }
+ api_version = opts[:api_version] || '2008-08-01'
+ make_request( File.join( base_uri, 'Calls' ), 'POST', params )
+ end
+
+ MAX_SMS_LENGTH = 160
+ # Required:
+ # - number: to
+ # - body: text
+ #
+ # Options:
+ # - :from: number
+ # - :method: GET/POST
+ #
+ def send_sms( number, body, opts = {} )
+ params = {
+ 'From' => opts[:from] || @config[:default_number],
+ 'To' => number,
+ 'Body' => body,
+ 'Method' => opts[:method] || 'POST'
+ }
+ url = File.join( base_uri, 'SMS/Messages' )
+ make_request(url, 'POST', params )
+ end
+
+ def incoming_numbers( reset = false )
+ if( @incoming_numbers.nil? || reset )
+ response =
+ make_request( File.join( base_uri, 'IncomingPhoneNumbers' ), 'GET' )
+
+ if( 200 == response.code.to_i )
+ @raw_incoming_numbers = Hpricot( response.body )
+ else
+ raise "got response code #{response.code} and body #{response.body}"
+ end
+ @incoming_numbers = @raw_incoming_numbers.search( '//phonenumber').
+ collect{|j| j.inner_html}
+ end
+ return @incoming_numbers
+ end
+
+ def outgoing_numbers( reset = false )
+ if( @outgoing_numbers.nil? || reset )
+ response =
+ make_request( "/2008-08-01/Accounts/#{@sid}/OutgoingCallerIds",
+ 'GET' )
+ @outgoing_numbers_raw = Hpricot( response.body ) if( 200 == response.code.to_i )
+ @outgoing_numbers = @outgoing_numbers_raw.search( '//phonenumber').
+ collect{|j| j.inner_html}
+ end
+ return @outgoing_numbers
+ end
+
+ protected
+
+
+ # This makes it easy to create and call the TwilioRest library without
+ # having to worry about where credentials come from and stuff.
+ def make_request( *args )
+ @twilio_account ||= TwilioRest::Account.new( @sid, @token )
+ logger.debug{ "making twilio request with #{args.inspect}" }
+ @twilio_account.request( *args )
+ end
+
+ def base_uri( opts = {} )
+ api_version = opts[:api_version] || @api_version || '2008-08-01'
+ sid = opts[:sid] || @sid
+ "/#{api_version}/Accounts/#{sid}/"
+ end
+
+ def logger
+ self.class.logger
+ end
+ def self.logger
+ return @logger unless @logger.nil?
+ @logger = Logger.new( STDERR )
+ @logger.level = Logger::WARN
+ return @logger
+ end
+ def self.config
+ @@cfg ||= YAML::load_file( config_file )
+ end
+
+ def self.config_file
+ return File.join( RAILS_ROOT, 'config', 'twilio.yml' )
+ end
+
+ end # class Account
+ end # module Twilio
+end # module Trails
Oops, something went wrong.

0 comments on commit 14b7f4a

Please sign in to comment.