Module: TwilioContactable::Contactable

Defined in:
lib/contactable.rb

Defined Under Namespace

Classes: Configuration

Constant Summary collapse

Attributes =
[
  :phone_number,
  :formatted_phone_number,
  :sms_blocked,
  :sms_confirmation_code,
  :sms_confirmation_attempted,
  :sms_confirmed_phone_number,
  :voice_blocked,
  :voice_confirmation_code,
  :voice_confirmation_attempted,
  :voice_confirmed_phone_number
]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(model) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/contactable.rb', line 38

def self.included(model)

  # set up the configuration, available within the class object
  # via this same 'twilio_contactable' method
  class << model
    def twilio_contactable(&block)
      @twilio_contactable = Configuration.new(&block) if block
      @twilio_contactable ||= Configuration.new
    end
  end

  # normalize the phone number before it's saved in the database
  # (only for model classes using callbacks a la ActiveModel,
  #  other folks will have to do this by hand)
  if model.respond_to?(:before_save)
    model.before_save :format_phone_number
    model.class_eval do
      def format_phone_number
        self._TC_formatted_phone_number =
          TwilioContactable.internationalize(_TC_phone_number)
      end
    end
  end
end

Instance Method Details

#has_valid_phone_number?Boolean

Returns:

  • (Boolean)


80
81
82
83
# File 'lib/contactable.rb', line 80

def has_valid_phone_number?
  format_phone_number
  _TC_formatted_phone_number =~ /^\+[\d]{10,12}$/
end

#send_sms!(msg, allow_multiple = false) ⇒ Object

Sends one or more TXT messages to the contactable record’s mobile number (if the number has been confirmed). Any messages longer than 160 characters will need to be accompanied by a second argument true to clarify that sending multiple messages is intentional.



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/contactable.rb', line 181

def send_sms!(msg, allow_multiple = false)
  if msg.to_s.size > 160 && !allow_multiple
    raise ArgumentError, "SMS Message is too long. Either specify that you want multiple messages or shorten the string."
  end
  return false if msg.to_s.strip.blank? || _TC_sms_blocked
  return false unless sms_confirmed?

  # split into pieces that fit as individual messages.
  msg.to_s.scan(/.{1,160}/m).map do |text|
    if TwilioContactable::Gateway.deliver_sms(text, _TC_formatted_phone_number).success?
      text.size
    else
      false
    end
  end
end

#send_sms_confirmation!Object

Sends an SMS validation request through the gateway



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/contactable.rb', line 86

def send_sms_confirmation!
  return false if _TC_sms_blocked
  return true  if sms_confirmed?
  return false if _TC_phone_number.blank?

  format_phone_number
  confirmation_code = TwilioContactable.confirmation_code(self, :sms)

  # Use this class' confirmation_message method if it
  # exists, otherwise use the generic message
  message = (self.class.respond_to?(:confirmation_message) ?
               self.class :
               TwilioContactable).confirmation_message(confirmation_code)

  if message.to_s.size > 160
    raise ArgumentError, "SMS Confirmation Message is too long. Limit it to 160 characters of unescaped text."
  end

  response = TwilioContactable::Gateway.deliver(message, _TC_phone_number)

  if response.success?
    update_twilio_contactable_sms_confirmation confirmation_code
  end

  response
end

#send_voice_confirmation!Object

Begins a phone call to the user where they’ll need to type their confirmation code



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/contactable.rb', line 115

def send_voice_confirmation!
  return false if _TC_voice_blocked
  return true  if voice_confirmed?
  return false if _TC_phone_number.blank?

  format_phone_number
  confirmation_code = TwilioContactable.confirmation_code(self, :voice)

  response = TwilioContactable::Gateway.initiate_voice_call(self, _TC_formatted_phone_number)

  if response.success?
    update_twilio_contactable_voice_confirmation confirmation_code
  end

  response
end

#sms_confirm_with(code) ⇒ Object

Compares user-provided code with the stored confirmation code. If they match then the current phone number is set as confirmed by the user.



135
136
137
138
139
140
141
142
143
144
# File 'lib/contactable.rb', line 135

def sms_confirm_with(code)
  check_for_twilio_contactable_columns(:sms)
  if _TC_sms_confirmation_code.to_s.downcase == code.downcase
    # save the phone number into the 'confirmed phone number' attribute
    self._TC_sms_confirmed_phone_number = _TC_formatted_phone_number
    save
  else
    false
  end
end

#sms_confirmed?Boolean

Returns true if the current phone number has been confirmed by the user for recieving TXT messages.

Returns:

  • (Boolean)


148
149
150
151
152
# File 'lib/contactable.rb', line 148

def sms_confirmed?
  check_for_twilio_contactable_columns(:sms)
  return false if _TC_sms_confirmed_phone_number.blank?
  self._TC_sms_confirmed_phone_number == _TC_formatted_phone_number
end

#twilio_contactableObject

Set up a bridge to access the data for a specific instance by referring to the column values in the configuration.



65
66
67
# File 'lib/contactable.rb', line 65

def twilio_contactable
  self.class.twilio_contactable
end

#voice_confirm_with(code) ⇒ Object

Compares user-provided code with the stored confirmation code. If they match then the current phone number is set as confirmed by the user.



157
158
159
160
161
162
163
164
165
166
# File 'lib/contactable.rb', line 157

def voice_confirm_with(code)
  check_for_twilio_contactable_columns(:voice)
  if _TC_voice_confirmation_code.to_s.downcase == code.downcase
    # save the phone number into the 'confirmed phone number' attribute
    self._TC_voice_confirmed_phone_number = _TC_formatted_phone_number
    save
  else
    false
  end
end

#voice_confirmed?Boolean

Returns true if the current phone number has been confirmed by the user by receiving a phone call

Returns:

  • (Boolean)


170
171
172
173
174
# File 'lib/contactable.rb', line 170

def voice_confirmed?
  check_for_twilio_contactable_columns(:voice)
  return false if _TC_voice_confirmed_phone_number.blank?
  self._TC_voice_confirmed_phone_number == _TC_formatted_phone_number
end