Class: SmsSafe::Interceptor

Inherits:
Object
  • Object
show all
Defined in:
lib/sms_safe/interceptor.rb

Overview

Main class with almost all the functionality. When a message is intercepted, Interceptor decides whether we need to do anything with it,

and does it.

The different adaptor classes in the Interceptors module provide mapping to each of the SMS libraries peculiarities.

Instance Method Summary collapse

Instance Method Details

#convert_message(message) ⇒ Message

Converts an SMS message from whatever object the texter gem uses into our generic Message Must be overridden by each gem’s interceptor

Parameters:

  • message (Object)

    that is being sent

Returns:

  • (Message)

    the message converted into our own Message class



157
158
159
# File 'lib/sms_safe/interceptor.rb', line 157

def convert_message(message)
  raise "Must override!"
end

#deliver_email(mail) ⇒ Mail

Delivers the email through Mail, or ActionMailer, whatever is there

Parameters:

  • mail (Mail)

    to send

Returns:

  • (Mail)

    the same mail received as parameter



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/sms_safe/interceptor.rb', line 98

def deliver_email(mail)
  # Ugly hack, or beautiful elegance? No idea, really...
  # We don't want a dependency on ActionMailer, but we want our users that have ActionMailer configured
  #   to not need to configure Mail too, so we want to take the ActionMailer configuration magically
  #   if it's there
  if defined?(ActionMailer)
    ActionMailer::Base.wrap_delivery_behavior(mail)
  end

  mail.deliver!
end

#discardObject

Discards the message. Essentially doesn’t do anything. Will sleep for a bit, however, if

configuration.discard_delay is set.

Returns:

  • nil, to stop the sending



141
142
143
144
145
146
147
148
149
150
# File 'lib/sms_safe/interceptor.rb', line 141

def discard
  # Delay to simulate the time it takes to talk to the external service
  if !SmsSafe.configuration.discard_delay.nil? && SmsSafe.configuration.discard_delay > 0
    delay = SmsSafe.configuration.discard_delay.to_f / 1000 # delay is specified in ms
    sleep delay
  end

  # Must return nil to stop the sending
  nil
end

#email(message) ⇒ Object

Sends an e-mail to the specified address, instead of

Returns:

  • nil, to stop the sending



81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/sms_safe/interceptor.rb', line 81

def email(message)
  recipient = email_recipient(message)
  body = email_body(message)
  mail = Mail.new do
    from     recipient
    to       recipient
    subject  "SmsSafe: #{message.to} - #{message.text}"
    body     body
  end
  deliver_email(mail)

  nil # Must return nil to stop the sending
end

#email_body(message) ⇒ String

Returns the Body for the e-mail that we’ll send

Parameters:

  • message (Message)

    the message we are emailing

Returns:

  • (String)

    the email body



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/sms_safe/interceptor.rb', line 126

def email_body(message)
  <<-EOS
This email was originally an SMS that SmsSafe intercepted:

From: #{message.from}
To: #{message.to}
Text: #{message.text}

Full object: #{message.original_message.inspect}
  EOS
end

#email_recipient(message) ⇒ String

Decides which email address to send the SMS to

Parameters:

  • message (Message)

    the message we are emailing

Returns:

  • (String)

    the email address to email it to



113
114
115
116
117
118
119
120
121
# File 'lib/sms_safe/interceptor.rb', line 113

def email_recipient(message)
  target = SmsSafe.configuration.email_target
  case target
    when String then target
    when Proc   then target.call(message)
    else
      raise InvalidConfigSettingError.new("Ensure email_target is a String or a Proc. It was: #{SmsSafe.configuration.email_target.inspect}")
  end
end

#intercept_message!(message) ⇒ Object

Once we’ve decided to intercept the message, act on it, based on the intercept_mechanism set

Parameters:

  • message (Message)

    the message we are evaluating

Returns:

  • (Object)

    the message to send, of the type that corresponds to the texter gem (if :redirecting) or nil to cancel sending (if :email or :discard)



47
48
49
50
51
52
53
54
55
# File 'lib/sms_safe/interceptor.rb', line 47

def intercept_message!(message)
  case SmsSafe.configuration.intercept_mechanism
    when :redirect then redirect(message)
    when :email then email(message)
    when :discard then discard
    else
      raise InvalidConfigSettingError.new("Ensure intercept_mechanism is either :redirect, :email or :discard. It was: #{SmsSafe.configuration.intercept_mechanism.inspect}")
  end
end

#intercept_message?(message) ⇒ Boolean

Decides whether to intercept the message that is being sent, or to let it go through

Parameters:

  • message (Message)

    the message we are evaluating

Returns:

  • (Boolean)

    whether to intercept the message (true) or let it go through (false)



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/sms_safe/interceptor.rb', line 29

def intercept_message?(message)
  matching_rules = [SmsSafe.configuration.internal_phone_numbers].flatten.compact
  internal_recipient = matching_rules.any? do |rule|
    case rule
      when String then message.to == rule
      when Regexp then !!(message.to =~ rule)
      when Proc   then rule.call(message)
      else
        raise InvalidConfigSettingError.new("Ensure internal_phone_numbers is a String, a Regexp or a Proc (or an array of them). It was: #{SmsSafe.configuration.internal_phone_numbers.inspect}")
    end
  end
  !internal_recipient # Intercept messages that are *not* going to one of the allowed numbers
end

#process_message(original_message) ⇒ Object

Method called by all the sub-classes to process the SMS being sent

Parameters:

  • original_message (Object)

    the message we intercepted from the texter gem. May be of varying types, depending on which texter gem is being used.

Returns:

  • (Object)

    the message to send (if modified recipient / text), of the same type we received or nil if no SMS should be sent



16
17
18
19
20
21
22
23
24
# File 'lib/sms_safe/interceptor.rb', line 16

def process_message(original_message)
  message = convert_message(original_message)

  if intercept_message?(message)
    intercept_message!(message)
  else
    original_message
  end
end

#redirect(message) ⇒ Object

Returns a modified version of the original message with new recipient and text,

to give back to the texter gem to send.

Must be overridden by each gem’s interceptor Call redirect_phone_number and redirect_text to get the new recipient and text, and

modify message.original_message

Parameters:

  • message (Message)

    that is being sent, unmodified

Returns:

  • (Object)

    modified message to send, of the type the texter gem uses



169
170
171
# File 'lib/sms_safe/interceptor.rb', line 169

def redirect(message)
  raise "Must override!"
end

#redirect_phone_number(message) ⇒ String

Decides which phone number to redirect the message to

Parameters:

  • message (Message)

    the message we are redirecting

Returns:

  • (String)

    the phone number to redirect the number to



60
61
62
63
64
65
66
67
68
# File 'lib/sms_safe/interceptor.rb', line 60

def redirect_phone_number(message)
  target = SmsSafe.configuration.redirect_target
  case target
    when String then target
    when Proc   then target.call(message)
    else
      raise InvalidConfigSettingError.new("Ensure redirect_target is a String or a Proc. It was: #{SmsSafe.configuration.redirect_target.inspect}")
  end
end

#redirect_text(message) ⇒ String

Modifies the text of the message to indicate it was redirected Simply appends “(SmsSafe: original_recipient_number)”, for brevity

Parameters:

  • message (Message)

    the message we are redirecting

Returns:

  • (String)

    the new text for the SMS



75
76
77
# File 'lib/sms_safe/interceptor.rb', line 75

def redirect_text(message)
  "#{message.text} (SmsSafe: #{message.to})"
end