diff --git a/app/controllers/attempts_controller.rb b/app/controllers/attempts_controller.rb index dbc5fac1..57576ea5 100644 --- a/app/controllers/attempts_controller.rb +++ b/app/controllers/attempts_controller.rb @@ -4,6 +4,14 @@ class AttemptsController < ApplicationController def twilio attempt = Recipient.where(phone: twilio_params['From']).first.attempts.last + + if (twilio_params[:Body].downcase == 'cancel') + attempt.recipient.update_attributes(opted_out: true) + attempt.update_attributes(twilio_details: twilio_params.to_h.to_yaml) + render plain: 'Thank you, you have been opted out of these messages and will no longer receive them.' + return + end + attempt.update_attributes( answer_index: twilio_params[:Body].to_i, twilio_details: twilio_params.to_h.to_yaml diff --git a/app/models/attempt.rb b/app/models/attempt.rb index cfc80f8a..e82eeca6 100644 --- a/app/models/attempt.rb +++ b/app/models/attempt.rb @@ -14,18 +14,28 @@ class Attempt < ApplicationRecord scope :for_school, -> (school) { joins(:recipient).merge(Recipient.for_school(school)) } scope :with_response, -> { where('answer_index is not null or open_response_id is not null')} + def messages + [ + question.text, + "#{question.option1}: Reply 1\n\r#{question.option2}: Reply 2\n\r#{question.option3}: Reply 3\n\r#{question.option4}: Reply 4\n\r#{question.option5}: Reply 5\n\rReply 'cancel' to stop these messages." + ] + end + def send_message twilio_number = ENV['TWILIO_NUMBER'] client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN'] - message = client.messages.create( - from: twilio_number, - to: recipient.phone, - body: "#{question.text}\n\r#{question.option1}: Reply 1\n\r#{question.option2}: Reply 2\n\r#{question.option3}: Reply 3\n\r#{question.option4}: Reply 4\n\r#{question.option5}: Reply 5" - ) + sids = [] + messages.each do |message| + sids << client.messages.create( + from: twilio_number, + to: recipient.phone, + body: message + ).sid + end - update_attributes(sent_at: Time.new, twilio_sid: message.sid) - recipient.update_attributes(phone: client.messages.get(message.sid).to) + update_attributes(sent_at: Time.new, twilio_sid: sids.join(',')) + recipient.update_attributes(phone: client.messages.get(sids.last).to) end def response diff --git a/spec/controllers/attempts_controller_spec.rb b/spec/controllers/attempts_controller_spec.rb index b49a9120..6817dc93 100644 --- a/spec/controllers/attempts_controller_spec.rb +++ b/spec/controllers/attempts_controller_spec.rb @@ -48,5 +48,24 @@ RSpec.describe AttemptsController, type: :controller do expect(response.body).to eq('Thank you!') end end + + context 'with cancel params' do + let(:twilio_attributes) { + {'MessageSid' => 'ewuefhwieuhfweiuhfewiuhf','AccountSid' => 'wefiuwhefuwehfuwefinwefw','MessagingServiceSid' => 'efwneufhwuefhweiufhiuewhf','From' => '+11231231234','To' => '2223334444','Body' => 'cAnCel','NumMedia' => '0'} + } + + it "updates the last attempt by recipient phone number" do + post :twilio, params: twilio_attributes + attempt.reload + expect(attempt.answer_index).to be_nil + expect(attempt.twilio_details).to eq(twilio_attributes.with_indifferent_access.to_yaml) + expect(attempt.recipient).to be_opted_out + end + + it "sends back a message" do + post :twilio, params: twilio_attributes + expect(response.body).to eq('Thank you, you have been opted out of these messages and will no longer receive them.') + end + end end end diff --git a/spec/models/attempt_spec.rb b/spec/models/attempt_spec.rb index f902ff58..d76158cb 100644 --- a/spec/models/attempt_spec.rb +++ b/spec/models/attempt_spec.rb @@ -92,8 +92,9 @@ RSpec.describe Attempt, type: :model do end it 'should contact the Twilio API' do - expect(FakeSMS.messages.length).to eq(1) - expect(FakeSMS.messages.first.body).to eq("Question 0:1\n\rOption 0:1 A: Reply 1\n\rOption 0:1 B: Reply 2\n\rOption 0:1 C: Reply 3\n\rOption 0:1 D: Reply 4\n\rOption 0:1 E: Reply 5") + expect(FakeSMS.messages.length).to eq(2) + expect(FakeSMS.messages.first.body).to eq("Question 0:1") + expect(FakeSMS.messages.last.body).to eq("Option 0:1 A: Reply 1\n\rOption 0:1 B: Reply 2\n\rOption 0:1 C: Reply 3\n\rOption 0:1 D: Reply 4\n\rOption 0:1 E: Reply 5\n\rReply 'cancel' to stop these messages.") expect(FakeSMS.messages.first.to).to eq('1111111111') end