Skip to content

Commit

Permalink
import attempt from google code
Browse files Browse the repository at this point in the history
  • Loading branch information
Hemant Bhanoo committed Mar 19, 2010
1 parent 0f2ca8c commit 14b7f4a
Show file tree
Hide file tree
Showing 57 changed files with 1,337 additions and 245 deletions.
37 changes: 37 additions & 0 deletions History.txt
Original file line number Original file line Diff line number Diff line change
@@ -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!

56 changes: 56 additions & 0 deletions Manifest.txt
Original file line number Original file line Diff line number Diff line change
@@ -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
46 changes: 46 additions & 0 deletions README.txt
Original file line number Original file line Diff line number Diff line change
@@ -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.
11 changes: 11 additions & 0 deletions Rakefile
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- ruby -*-

require 'rubygems'
require 'hoe'

Hoe.spec 'trails' do
developer('Hemant Bhanoo', 'hemant@bhanoo.com')

end

# vim: syntax=ruby
4 changes: 4 additions & 0 deletions assets/layouts/default_layout.twiml.builder
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,4 @@
xml.instruct!
xml.Response do
xml << yield
end
Empty file added bin/trails
Empty file.
13 changes: 13 additions & 0 deletions lib/trails.rb
Original file line number Original file line Diff line number Diff line change
@@ -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'
6 changes: 6 additions & 0 deletions lib/trails/exception.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,6 @@
module Trails
module Exception
class UnknownAccount < ::Exception; end
class InvalidSignature < ::Exception; end
end # module Exception
end # module Trails
28 changes: 22 additions & 6 deletions twilio-test.rb → lib/trails/test_helper.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,13 +1,18 @@
require 'ostruct' require 'ostruct'


module Twilio module Trails
module TestHelper module TestHelper
def open_session_as_twilio( as_twilio_opts = {}, *args ) def open_session_as_twilio( as_twilio_opts = {}, *args )
session = open_session( *args ) session = open_session( *args )
modify_session_with_twilio_opts( session, as_twilio_opts ) modify_session_with_twilio_opts( session, as_twilio_opts )
session session
end 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 ) def as_twilio( as_twilio_opts = {}, &block )
if( @integration_session ) if( @integration_session )
modify_session_with_twilio_opts( @integration_session, as_twilio_opts ) modify_session_with_twilio_opts( @integration_session, as_twilio_opts )
Expand Down Expand Up @@ -48,6 +53,16 @@ def as_twilio( as_twilio_opts = {}, &block )
block.call() block.call()


end # as_twilio 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 ) def user_presses( digits )
{ 'Digits' => digits } { 'Digits' => digits }
Expand Down Expand Up @@ -88,30 +103,31 @@ def modify_headers_with_twilio_opts( headers, as_twilio_opts )
def modify_params_with_twilio_opts( params, as_twilio_opts ) def modify_params_with_twilio_opts( params, as_twilio_opts )
caller = as_twilio_opts[:caller] || '4155551212' caller = as_twilio_opts[:caller] || '4155551212'
called = as_twilio_opts[:called] || '6155556161' called = as_twilio_opts[:called] || '6155556161'
from = as_twilio_opts[:from] || '6665554321'
params['Caller'] = caller params['Caller'] = caller
params['Called'] = called params['Called'] = called
params['From'] = from
params['SmsMessageSid'] = 'DummyMessageSid' if( as_twilio_opts[:sms] )
end end


private private
module IntegrationDSL module IntegrationDSL
end end


end # module TestHelper 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 class TwilioRest::Account
@@fake_requests ||= []
def self.faked_requests def self.faked_requests
return @@fake_requests return @@fake_requests
end end
def request_with_fake( url, method, params ) def request_with_fake( url, method, params )
@@fake_requests ||= []
@@fake_requests.push( OpenStruct.new( :url => url, :method => method, :params => params ) ) @@fake_requests.push( OpenStruct.new( :url => url, :method => method, :params => params ) )
fake_response = OpenStruct.new fake_response = OpenStruct.new
fake_response.body = 'Fake Body' fake_response.body = 'Fake Body'
fake_response fake_response
end end
alias_method_chain :request, :fake alias_method_chain :request, :fake
end end



143 changes: 143 additions & 0 deletions lib/trails/twilio/account.rb
Original file line number Original file line Diff line number Diff line change
@@ -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
Loading

0 comments on commit 14b7f4a

Please sign in to comment.