Module: Txter::Contactable

Defined in:
lib/contactable.rb

Constant Summary collapse

Attributes =
[  :sms_phone_number,
:sms_blocked,
:sms_confirmation_code,
:sms_confirmation_attempted,
:sms_confirmed_phone_number ]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(model) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/contactable.rb', line 10

def self.included(model)
  gem 'haml'
  require 'haml'
  require 'net/http'

  Attributes.each do |attribute|
    # add a method in the class for setting or retrieving
    # which column should be used for which attribute
    # 
    # :sms_phone_number_column defaults to :sms_phone_number, etc.
    model.instance_eval "
      def #{attribute}_column(value = nil)
        @#{attribute}_column ||= :#{attribute}
        @#{attribute}_column = value if value
        @#{attribute}_column
      end
    "
    # provide helper methods to access the right value
    # no matter which column it's stored in.
    #
    # e.g.: @user.txter_sms_confirmation_code
    #       == @user.send(User.sms_confirmation_code_column)
    model.class_eval "
      def txter_#{attribute}
        send self.class.#{attribute}_column
      end
      alias_method :txter_#{attribute}?, :txter_#{attribute}
      def txter_#{attribute}=(value)
        send self.class.#{attribute}_column.to_s+'=', value
      end
    "
  end

  # normalize the phone number before it's saved in the database
  # (only for model classes using callbacks a la ActiveRecord,
  #  other folks will have to do this by hand)
  if model.respond_to?(:before_save)
    model.before_save :normalize_sms_phone_number
    model.class_eval do
      def normalize_sms_phone_number
        self.txter_sms_phone_number = Txter.numerize(txter_sms_phone_number)
      end
    end
  end
end

Instance Method Details

#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.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/contactable.rb', line 61

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? || txter_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 Txter.deliver(text, txter_sms_phone_number).success?
      text.size
    else
      false
    end
  end
end

#send_sms_confirmation!Object

Sends an SMS validation request through the gateway



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/contactable.rb', line 79

def send_sms_confirmation!
  return false if txter_sms_blocked?
  return true  if sms_confirmed?
  return false if txter_sms_phone_number.blank?

  confirmation_code = Txter.generate_confirmation_code

  # Use this class' confirmation_message method if it
  # exists, otherwise use the generic message
  message = (self.class.respond_to?(:confirmation_message) ?
               self.class :
               Txter).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 = Txter.deliver(message, txter_sms_phone_number)

  if response.success?
    update_txter_sms_confirmation confirmation_code
  else
    false
  end
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.



124
125
126
127
128
129
130
131
132
# File 'lib/contactable.rb', line 124

def sms_confirm_with(code)
  if txter_sms_confirmation_code.to_s.downcase == code.downcase
    # save the phone number into the 'confirmed phone number' attribute
    self.txter_sms_confirmed_phone_number = txter_sms_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)


136
137
138
139
# File 'lib/contactable.rb', line 136

def sms_confirmed?
  return false if txter_sms_confirmed_phone_number.blank?
  txter_sms_confirmed_phone_number == txter_sms_phone_number
end

#unblock_sms!Object

Sends an unblock request via xml to the 4info gateway. If request succeeds, changes the contactable record’s sms_blocked_column to false.



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/contactable.rb', line 109

def unblock_sms!
  return false unless txter_sms_blocked?

  response = Txter.unblock(txter_sms_phone_number)
  if response.success?
    self.txter_sms_blocked = 'false'
    save
  else
    false
  end
end