Class: Twilio::Rails::SMS::SendOperation

Inherits:
ApplicationOperation show all
Defined in:
app/operations/twilio/rails/sms/send_operation.rb

Overview

Public entrypoint used to send an SMS message. This operation will create a new conversation to the phone caller and send a series of messages to them. The interaction will be stored in the database and sent via Twilio’s API. The operation will raise if the #from_number is not a valid phone number.

Note: Operations should be called with ‘call(params)` and not by calling `new(params).execute` directly.

Examples:

Twilio::Rails::SMS::SendOperation.call(
  phone_caller_id: a_phone_caller.id,
  messages: ["Hello world!"],
  from_number: "+1234567890"
)

Constant Summary collapse

TWILIO_UNSUBSCRIBED_ERROR_CODES =
[ 21610 ].freeze

Instance Method Summary collapse

Instance Method Details

#executeTwilio::Rails::Models::SMSConversation

number is ‘nil` then it will attempt to extract the phone number from the last phone call. If that is not found then it will raise Error.

Parameters:

  • phone_caller_id (Integer)

    the id of the phone caller to send the message to.

  • messages (Array<String>)

    the messages to send to the phone caller. It may be empty.

  • from_number (String, Twilio::Rails::PhoneNumber)

    the phone number to send the message from. If the

Returns:

Raises:



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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/operations/twilio/rails/sms/send_operation.rb', line 30

def execute
  return nil if messages.blank?
  raise Twilio::Rails::SMS::Error, "from_number=#{ from_number } is not a valid phone number" if from_number.present? && !Twilio::Rails::Formatter.coerce_to_valid_phone_number(from_number)

  conversation = ::Twilio::Rails.config.sms_conversation_class.new(
    number: calculated_from_number,
    from_number: calculated_to_number,
    from_city: phone_call&.from_city,
    from_province: phone_call&.from_province,
    from_country: phone_call&.from_country,
  )
  conversation.save!

  messages.each do |body|
    sid = nil
    begin
      sid = Twilio::Rails::Client.send_message(
        message: body,
        to: calculated_to_number,
        from: calculated_from_number,
      )
    rescue Twilio::REST::RestError => e
      if TWILIO_UNSUBSCRIBED_ERROR_CODES.include?(e.code)
        Twilio::Rails.config.logger.tagged(self.class) { |l| l.warn("tried to send to unsubscribed and got Twilio::REST::RestError code=21610 phone_caller_id=#{ phone_caller.id } phone_number=#{ calculated_to_number } message=#{ body }") }
      else
        Twilio::Rails.notify_exception(e,
          message: "Failed to send Twilio message. Got REST error response.",
          context: {
            to: calculated_to_number,
            from: calculated_from_number,
            phone_call_id: phone_call&.id,
          },
          exception_binding: binding
        )
        raise
      end
    end

    message = conversation.messages.build(body: body, sid: sid, direction: "outbound")

    message.save!
  end

  conversation
end