From db5cb918bfb8f6ea96aa499e17e13e3b0f0e094f Mon Sep 17 00:00:00 2001 From: Andrew Cantino Date: Wed, 8 May 2013 22:09:37 -0700 Subject: [PATCH] cleanup the new TwilioAgent a bit --- Gemfile.lock | 7 ++ app/models/agents/twilio_agent.rb | 102 ++++++++++++----------- spec/models/agents/twilio_agent_spec.rb | 104 +++++++++++++----------- 3 files changed, 116 insertions(+), 97 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ff138e49..04fd2693 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -116,6 +116,8 @@ GEM json (1.7.7) jsonpath (0.5.1) multi_json + jwt (0.1.8) + multi_json (>= 1.5) kaminari (0.14.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) @@ -228,6 +230,10 @@ GEM treetop (1.4.12) polyglot polyglot (>= 0.3.1) + twilio-ruby (3.9.0) + builder (>= 2.1.2) + jwt (>= 0.1.2) + multi_json (>= 1.3.0) twitter (4.4.0) faraday (~> 0.8) multi_json (~> 1.3) @@ -286,6 +292,7 @@ DEPENDENCIES select2-rails shoulda-matchers system_timer + twilio-ruby twitter twitter-stream (>= 0.1.16) typhoeus diff --git a/app/models/agents/twilio_agent.rb b/app/models/agents/twilio_agent.rb index d73c362c..c14307ad 100644 --- a/app/models/agents/twilio_agent.rb +++ b/app/models/agents/twilio_agent.rb @@ -1,58 +1,62 @@ -require 'rubygems' -require 'twilio-ruby' +require 'twilio-ruby' module Agents - class TwilioAgent < Agent + class TwilioAgent < Agent + default_schedule "every_10m" - default_schedule "every_10m" + description <<-MD + The TwilioAgent receives and collects events and sends them via text message when scheduled. - description <<-MD - The TwilioAgent receives and collects events and send them via text message to cellphone when scheduled.It is assumed that events have `:message`,`:text` or `:sms` key, the value of which is sent as the content of the text message. - Set `receiver_cell` to the number on which you would like to receive text messages. - `expected_receive_period_in_days` is maximum days that you would expect to pass between events being received by this agent. - MD + It is assumed that events have a `:message`, `:text`, or `:sms` key, the value of which is sent as the content of the text message. - def default_options - { - :account_sid => "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - :auth_token => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - :sender_cell => "xxxxxxxxxx", - :receiver_cell => "xxxxxxxxxx", - :expected_receive_period_in_days => "x" - } - end + Set `receiver_cell` to the number to receive text messages and `sender_cell` to the number sending them. - def validate_options - errors.add(:base, "account_sid,auth_token,sender_cell,receiver_cell,expected_receive_period_in_days are all required") unless options[:account_sid].present? && options[:auth_token].present? && options[:sender_cell].present? && options[:receiver_cell].present? && options[:expected_receive_period_in_days].present? - end + `expected_receive_period_in_days` is maximum number of days that you would expect to pass between events being received by this agent. + MD - def receive(incoming_events) - incoming_events.each do |event| - self.memory[:queue] ||= [] # If memory[:queue] is not true, assign [] to it, a || a = b - self.memory[:queue] << event.payload # Append - end - end - - def working? - last_receive_at && last_receive_at > options[:expected_receive_period_in_days].to_i.days.ago - end - - def send_message(client,message) - client.account.sms.messages.create(:from=>options[:sender_cell],:to=>options[:receiver_cell],:body=>message) - end - - def check - if self.memory[:queue] && self.memory[:queue].length > 0 - @client = Twilio::REST::Client.new options[:account_sid],options[:auth_token] - self.memory[:queue].each do |text| - message = text[:message] || text[:text] || text[:sms] - if message - message.slice! 160, message.length - send_message @client, message - end - end - self.memory[:queue] = [] - end - end + def default_options + { + :account_sid => 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + :auth_token => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + :sender_cell => 'xxxxxxxxxx', + :receiver_cell => 'xxxxxxxxxx', + :expected_receive_period_in_days => 'x' + } end + + def validate_options + unless options[:account_sid].present? && options[:auth_token].present? && options[:sender_cell].present? && options[:receiver_cell].present? && options[:expected_receive_period_in_days].present? + errors.add(:base, 'account_sid, auth_token, sender_cell, receiver_cell, and expected_receive_period_in_days are all required') + end + end + + def receive(incoming_events) + memory[:queue] ||= [] + incoming_events.each do |event| + memory[:queue] << event.payload + end + end + + def working? + last_receive_at && last_receive_at > options[:expected_receive_period_in_days].to_i.days.ago + end + + def send_message(client, message) + client.account.sms.messages.create(:from => options[:sender_cell], :to => options[:receiver_cell], :body => message) + end + + def check + if memory[:queue] && memory[:queue].length > 0 + @client = Twilio::REST::Client.new(options[:account_sid], options[:auth_token]) + memory[:queue].each do |text| + message = text[:message] || text[:text] || text[:sms] + if message + message.slice! 160, message.length + send_message @client, message + end + end + memory[:queue] = [] + end + end + end end \ No newline at end of file diff --git a/spec/models/agents/twilio_agent_spec.rb b/spec/models/agents/twilio_agent_spec.rb index 178ea8b9..8b368b6d 100644 --- a/spec/models/agents/twilio_agent_spec.rb +++ b/spec/models/agents/twilio_agent_spec.rb @@ -1,56 +1,64 @@ require 'spec_helper' describe Agents::TwilioAgent do + before do + @checker = Agents::TwilioAgent.new(:name => 'somename', + :options => { :account_sid => 'x', + :auth_token => 'x', + :sender_cell => 'x', + :receiver_cell => 'x', + :expected_receive_period_in_days => '1' }) + @checker.user = users(:bob) + @checker.save! + + @event = Event.new + @event.agent = agents(:bob_weather_agent) + @event.payload = { :message => 'Gonna rain..' } + @event.save! + + @sent_messages = [] + stub.any_instance_of(Agents::TwilioAgent).send_message { |client, message| @sent_messages << message} + end + + describe '#receive' do + it 'should queue any payload it receives' do + event1 = Event.new + event1.agent = agents(:bob_rain_notifier_agent) + event1.payload = 'Some payload' + event1.save! + + event2 = Event.new + event2.agent = agents(:bob_weather_agent) + event2.payload = 'More payload' + event2.save! + + Agents::TwilioAgent.async_receive(@checker.id, [event1.id, event2.id]) + @checker.reload.memory[:queue].should == ['Some payload', 'More payload'] + @sent_messages.should be_empty + end + end + + describe '#working?' do + it 'checks if events have been received within the expected receive period' do + @checker.should_not be_working # No events received + Agents::TwilioAgent.async_receive @checker.id, [@event.id] + @checker.reload.should be_working # Just received events + two_days_from_now = 2.days.from_now + stub(Time).now { two_days_from_now } + @checker.reload.should_not be_working # More time has passed than the expected receive period without any new events + end + end + + describe '#check' do before do - @checker = Agents::TwilioAgent.new(:name => "somename", :options => {:account_sid => "x",:auth_token => "x",:sender_cell => "x", :receiver_cell => "x", :expected_receive_period_in_days => "1"}) - @checker.user = users(:bob) - @checker.save! - - @event = Event.new - @event.agent = agents(:bob_weather_agent) - @event.payload = {:message => "Gonna rain.."} - @event.save! - - stub.any_instance_of(Agents::TwilioAgent).send_message {} + Agents::TwilioAgent.async_receive @checker.id, [@event.id] end - describe "#receive" do - it "should queue any payload it receives" do - event1 = Event.new - event1.agent = agents(:bob_rain_notifier_agent) - event1.payload = "Some payload" - event1.save! - - event2 = Event.new - event2.agent = agents(:bob_weather_agent) - event2.payload = "More payload" - event2.save! - - Agents::TwilioAgent.async_receive(@checker.id, [event1.id,event2.id]) - @checker.reload.memory[:queue].should == ["Some payload", "More payload"] - end - end - - describe "#working?" do - it "checks if events have been received within expected receive period" do - @checker.should_not be_working # No events received - Agents::TwilioAgent.async_receive @checker.id, [@event.id] - @checker.reload.should be_working # Just received events - two_days_from_now = 2.days.from_now - stub(Time).now { two_days_from_now } - @checker.reload.should_not be_working # More time have passed than expected receive period without sign of any new event - end - end - - describe "#check" do - before do - Agents::TwilioAgent.async_receive @checker.id, [@event.id] - end - it "should send text message and Memory should be empty after that" do - @checker.reload.memory[:queue].should == [{:message => "Gonna rain.."}] - Agents::TwilioAgent.async_check(@checker.id) - @checker.reload.memory[:queue].should == [] - - end + it 'should send text message and Memory should be empty after that' do + @checker.reload.memory[:queue].should == [ { :message => 'Gonna rain..' } ] + Agents::TwilioAgent.async_check(@checker.id) + @checker.reload.memory[:queue].should == [] + @sent_messages.should == ['Gonna rain..'] end + end end \ No newline at end of file