diff --git a/app/models/twilio/send_twilio_message_job.rb b/app/models/twilio/send_twilio_message_job.rb index 0c4cb8ee..2f768979 100644 --- a/app/models/twilio/send_twilio_message_job.rb +++ b/app/models/twilio/send_twilio_message_job.rb @@ -19,26 +19,28 @@ class SendTwilioMessageJob < SendMessageJob @@max_length = 160 def managed_perform - @client = Twilio::REST::Client.new @config[:account_sid], @config[:auth_token] + @client = TwilioClient.new @config[:account_sid], @config[:auth_token] begin message_text = @msg.subject_and_body # Send first part of the message and store relative id response = send_message(message_text) - @msg.channel_relative_id = response.sid + @msg.channel_relative_id = response['sid'] if response['sid'] + @msg.custom_attributes["twilio_api_uri"] = "https://api.twilio.com/#{response['uri']}" if response['uri'] # Continue sending other portions of the message while message_text.length > 0 send_message(message_text) end - rescue Twilio::REST::RequestError => e - if e.message == 'Authenticate' - raise PermanentException.new(e) + rescue RestClient::BadRequest => e + response = JSON.parse e.response + + case response['status'] + when 401 + raise PermanentException.new(Exception.new response) else - raise MessageException.new(e) + raise MessageException.new(Exception.new response) end - rescue Twilio::REST::ServerError => e - raise MessageException.new(e) end end @@ -46,7 +48,7 @@ def managed_perform def send_message(text) part = text.slice!(0..(@@max_length-1)) - @client.account.sms.messages.create sms_params(part) + @client.create_sms sms_params(part) end def sms_params(body) diff --git a/app/models/twilio/twilio_client.rb b/app/models/twilio/twilio_client.rb new file mode 100644 index 00000000..6aa3b7fc --- /dev/null +++ b/app/models/twilio/twilio_client.rb @@ -0,0 +1,22 @@ +class TwilioClient + def initialize(account_sid, auth_token) + @account_sid = account_sid + @auth_token = auth_token + end + + def create_sms(params) + # POST https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages.json + endpoint = "https://api.twilio.com/2010-04-01/Accounts/#{@account_sid}/Messages.json" + message_params = { + ShortenUrls: false, + To: params[:to], + From: params[:from], + Body: params[:body], + StatusCallback: params[:status_callback] + } + + raw_response = RestClient::Request.execute(:method => :post, :url => endpoint, :payload => message_params, :user => @account_sid, :password => @auth_token, :timeout => 30) + + JSON.parse raw_response + end +end diff --git a/test/unit/send_twilio_message_job_test.rb b/test/unit/send_twilio_message_job_test.rb index 8462baf6..324ffa20 100644 --- a/test/unit/send_twilio_message_job_test.rb +++ b/test/unit/send_twilio_message_job_test.rb @@ -31,9 +31,8 @@ def @chan.configure_phone_number end should "perform" do - response = mock('response') - @messages.expects(:create).returns(response) - response.expects(:sid).returns('sms_sid') + response = {'sid' => 'sms_sid'} + @twilio_client.expects(:create_sms).returns(response) deliver @msg @@ -44,7 +43,7 @@ def @chan.configure_phone_number end should "perform error" do - @messages.expects(:create).raises(Twilio::REST::ServerError.new) + @twilio_client.expects(:create_sms).raises(RestClient::BadRequest.new('{"status": 503}')) deliver @msg @@ -57,7 +56,7 @@ def @chan.configure_phone_number end should "perform authenticate error" do - @messages.expects(:create).raises(Twilio::REST::RequestError.new("Authenticate")) + @twilio_client.expects(:create_sms).raises(RestClient::BadRequest.new('{"status": 401}')) begin deliver @msg @@ -75,10 +74,9 @@ def @chan.configure_phone_number end should "perform with expected parameters" do - response = mock('response') - response.stubs(:sid).returns('sms_sid') + response = {'sid' => 'sms_sid'} - @messages.expects(:create).with do |params| + @twilio_client.expects(:create_sms).with do |params| params[:from] == @config[:from] && params[:to] == "+#{@msg.to.without_protocol}" && params[:body] == @msg.subject_and_body @@ -90,10 +88,9 @@ def @chan.configure_phone_number should "perform with callback url" do NamedRoutes.expects(:twilio_ack_url).returns('http://nuntium/foo/twilio/ack') - response = mock('response') - response.stubs(:sid).returns('sms_sid') + response = {'sid' => 'sms_sid'} - @messages.expects(:create).with do |params| + @twilio_client.expects(:create_sms).with do |params| params[:status_callback] == "http://#{@chan.name}:#{@config[:incoming_password]}@nuntium/foo/twilio/ack" end.returns(response) @@ -104,16 +101,15 @@ def @chan.configure_phone_number long_msg = AoMessage.make :account => @chan.account, :channel => @chan, :guid => '1-2', :subject => nil, :body => ("a" * 160 + "b" * 40) # First part of the message - response = mock('response') - @messages.expects(:create).with do |params| + response = {'sid' => 'sms_sid'} + @twilio_client.expects(:create_sms).with do |params| params[:from] == @config[:from] && params[:to] == "+#{long_msg.to.without_protocol}" && params[:body] == "a" * 160 end.returns(response) - response.expects(:sid).returns('sms_sid') # Second part - @messages.expects(:create).with do |params| + @twilio_client.expects(:create_sms).with do |params| params[:from] == @config[:from] && params[:to] == "+#{long_msg.to.without_protocol}" && params[:body] == "b" * 40 @@ -133,14 +129,8 @@ def deliver(msg) end def stub_twilio - twilio_client = mock('twilio') - account = mock('account') - sms = mock('sms') - @messages = mock('messages') - Twilio::REST::Client.expects(:new).with(@config[:account_sid], @config[:auth_token]).returns(twilio_client) - twilio_client.stubs(:account).returns(account) - account.stubs(:sms).returns(sms) - sms.stubs(:messages).returns(@messages) + @twilio_client = mock('TwilioClient') + TwilioClient.expects(:new).with(@config[:account_sid], @config[:auth_token]).returns(@twilio_client) end end