module TwilioContactable module Controller def self.included(controller) controller.instance_eval do # the developer should specify which model(s) will be sought # when the app receives incoming requests. # See the 'Controller' part of the README for details protected def twilio_contactable(*klasses) @@contactable_classes = klasses klasses.each do |klass| klass.twilio_contactable.controller = self.class.name.underscore.chomp('_controller') end end end end def receive_sms_message unless defined?(@@contactable_classes) && !@@contactable_classes.blank? raise RuntimeError, "Please define which model(s) this controller should receive for via the 'twilio_contactable' method" end request = params[:request] render :text => 'unknown format', :status => 500 and return unless request case request['type'] when 'BLOCK' @contactable = find_contactable_by_phone_number(request[:block][:recipient][:id]) @contactable._TC_sms_blocked = true @contactable.save! when 'MESSAGE' @contactable = find_contactable_by_phone_number(request[:message][:sender][:id]) if @contactable.respond_to?(:receive_sms) @contactable.receive_sms(request[:message][:text]) else warn "An SMS message was received but #{@contactable.class.name.inspect} doesn't have a receive_sms method!" end end render :text => 'OK', :status => 200 end def start_voice_confirmation render :xml => (Twilio::Response.new.tap do |response| response.addGather( :action => url_for( :action => 'receive_voice_confirmation', :contactable_type => params[:contactable_type], :contactable_id => params[:contactable_id] ) ).tap do |gather| gather.addSay "Please type the numbers that appear on your screen, followed by the pound sign" end response.addSay "Thank you, please return to the website and continue" response.addPause end.respond) end def receive_voice_confirmation @contactable = params[:contactable_type].constantize.find(params[:contactable_id]) @contactable.voice_confirm_with(params['Digits']) render :xml => '' end protected def find_contactable_by_phone_number(number) [number, number.sub(/^\+/,''), number.sub(/^\+1/,'')].uniq.compact.each do |possible_phone_number| @@contactable_classes.each do |klass| found = klass.find( :first, :conditions => { klass.twilio_contactable.formatted_phone_number_column => possible_phone_number } ) return found if found end end nil # rescue => error # render :text => error.inspect end end end