twilio-rails 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +23 -17
  3. data/app/controllers/twilio/rails/phone_controller.rb +6 -2
  4. data/app/controllers/twilio/rails/sms_controller.rb +6 -5
  5. data/app/jobs/twilio/rails/phone/attach_recording_job.rb +1 -0
  6. data/app/jobs/twilio/rails/phone/finished_call_job.rb +1 -0
  7. data/app/jobs/twilio/rails/phone/unanswered_call_job.rb +1 -0
  8. data/app/operations/twilio/rails/application_operation.rb +2 -1
  9. data/app/operations/twilio/rails/find_or_create_phone_caller_operation.rb +2 -1
  10. data/app/operations/twilio/rails/phone/attach_recording_operation.rb +3 -2
  11. data/app/operations/twilio/rails/phone/base_operation.rb +1 -0
  12. data/app/operations/twilio/rails/phone/create_operation.rb +11 -8
  13. data/app/operations/twilio/rails/phone/find_operation.rb +1 -0
  14. data/app/operations/twilio/rails/phone/finished_call_operation.rb +2 -1
  15. data/app/operations/twilio/rails/phone/receive_recording_operation.rb +3 -2
  16. data/app/operations/twilio/rails/phone/start_call_operation.rb +15 -13
  17. data/app/operations/twilio/rails/phone/twiml/after_operation.rb +2 -1
  18. data/app/operations/twilio/rails/phone/twiml/base_operation.rb +11 -5
  19. data/app/operations/twilio/rails/phone/twiml/error_operation.rb +2 -1
  20. data/app/operations/twilio/rails/phone/twiml/greeting_operation.rb +3 -2
  21. data/app/operations/twilio/rails/phone/twiml/invalid_phone_number_operation.rb +25 -0
  22. data/app/operations/twilio/rails/phone/twiml/prompt_operation.rb +6 -6
  23. data/app/operations/twilio/rails/phone/twiml/prompt_response_operation.rb +2 -1
  24. data/app/operations/twilio/rails/phone/twiml/request_validation_failure_operation.rb +1 -0
  25. data/app/operations/twilio/rails/phone/twiml/timeout_operation.rb +5 -4
  26. data/app/operations/twilio/rails/phone/unanswered_call_operation.rb +2 -1
  27. data/app/operations/twilio/rails/phone/update_operation.rb +1 -0
  28. data/app/operations/twilio/rails/phone/update_response_operation.rb +1 -0
  29. data/app/operations/twilio/rails/sms/base_operation.rb +1 -0
  30. data/app/operations/twilio/rails/sms/create_operation.rb +2 -1
  31. data/app/operations/twilio/rails/sms/find_message_operation.rb +1 -0
  32. data/app/operations/twilio/rails/sms/find_operation.rb +1 -0
  33. data/app/operations/twilio/rails/sms/send_operation.rb +12 -12
  34. data/app/operations/twilio/rails/sms/twiml/base_operation.rb +1 -0
  35. data/app/operations/twilio/rails/sms/twiml/error_operation.rb +1 -0
  36. data/app/operations/twilio/rails/sms/twiml/message_operation.rb +4 -3
  37. data/app/operations/twilio/rails/sms/update_message_operation.rb +1 -0
  38. data/lib/generators/twilio/rails/install/install_generator.rb +1 -0
  39. data/lib/generators/twilio/rails/install/templates/initializer.rb +5 -8
  40. data/lib/generators/twilio/rails/install/templates/message.rb +1 -0
  41. data/lib/generators/twilio/rails/install/templates/phone_call.rb +1 -0
  42. data/lib/generators/twilio/rails/install/templates/phone_caller.rb +1 -0
  43. data/lib/generators/twilio/rails/install/templates/recording.rb +1 -0
  44. data/lib/generators/twilio/rails/install/templates/response.rb +1 -0
  45. data/lib/generators/twilio/rails/install/templates/sms_conversation.rb +1 -0
  46. data/lib/generators/twilio/rails/phone_tree/phone_tree_generator.rb +1 -0
  47. data/lib/generators/twilio/rails/sms_responder/sms_responder_generator.rb +1 -0
  48. data/lib/generators/twilio/rails/sms_responder/templates/responder.rb.erb +2 -2
  49. data/lib/tasks/rails_tasks.rake +6 -5
  50. data/lib/twilio/rails/client.rb +9 -8
  51. data/lib/twilio/rails/concerns/has_direction.rb +2 -1
  52. data/lib/twilio/rails/concerns/has_phone_number.rb +13 -4
  53. data/lib/twilio/rails/concerns/has_time_scopes.rb +1 -0
  54. data/lib/twilio/rails/configuration.rb +46 -42
  55. data/lib/twilio/rails/formatter.rb +35 -29
  56. data/lib/twilio/rails/models/message.rb +1 -0
  57. data/lib/twilio/rails/models/phone_call.rb +1 -0
  58. data/lib/twilio/rails/models/phone_caller.rb +4 -3
  59. data/lib/twilio/rails/models/recording.rb +1 -0
  60. data/lib/twilio/rails/models/response.rb +7 -6
  61. data/lib/twilio/rails/models/sms_conversation.rb +1 -0
  62. data/lib/twilio/rails/phone/base_tree.rb +8 -8
  63. data/lib/twilio/rails/phone/tree.rb +8 -8
  64. data/lib/twilio/rails/phone/tree_macros.rb +27 -8
  65. data/lib/twilio/rails/phone.rb +3 -2
  66. data/lib/twilio/rails/phone_number.rb +6 -5
  67. data/lib/twilio/rails/phone_number_formatter/north_america.rb +52 -0
  68. data/lib/twilio/rails/phone_number_formatter.rb +20 -0
  69. data/lib/twilio/rails/railtie.rb +6 -1
  70. data/lib/twilio/rails/sms/delegated_responder.rb +6 -5
  71. data/lib/twilio/rails/sms/responder.rb +3 -2
  72. data/lib/twilio/rails/sms.rb +3 -2
  73. data/lib/twilio/rails/version.rb +1 -1
  74. data/lib/twilio/rails.rb +12 -26
  75. metadata +22 -6
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module Phone
@@ -20,12 +21,12 @@ module Twilio
20
21
  twiml.hangup
21
22
  end
22
23
 
23
- Twilio::Rails.config.logger.info("final timeout on phone_call##{ phone_call.id }")
24
- Twilio::Rails.config.logger.info("timeout_twiml: #{twiml_response.to_s}")
24
+ Twilio::Rails.config.logger.info("final timeout on phone_call##{phone_call.id}")
25
+ Twilio::Rails.config.logger.info("timeout_twiml: #{twiml_response}")
25
26
  twiml_response.to_s
26
27
  else
27
28
  prompt = tree.prompts[response.prompt_handle]
28
- raise Twilio::Rails::Phone::InvalidTreeError, "cannot find #{ response.prompt_handle } in #{ tree.name }" unless prompt
29
+ raise Twilio::Rails::Phone::InvalidTreeError, "cannot find #{response.prompt_handle} in #{tree.name}" unless prompt
29
30
 
30
31
  after = prompt.after
31
32
  after = Twilio::Rails::Phone::Tree::After.new(after.proc.call(response)) if after.proc
@@ -36,7 +37,7 @@ module Twilio
36
37
 
37
38
  private
38
39
 
39
- def final_timeout?(last_response, count: )
40
+ def final_timeout?(last_response, count:)
40
41
  responses = phone_call.responses.final_timeout_check(count: count, prompt_handle: last_response.prompt_handle)
41
42
 
42
43
  responses.count == count && responses.all? { |r| r.timeout? }
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module Phone
@@ -13,7 +14,7 @@ module Twilio
13
14
  Twilio::Rails.config.logger.tagged(self.class) { |l| l.warn("Skipping duplicate unanswered call job") }
14
15
  else
15
16
  phone_call.update!(unanswered: true)
16
- phone_call.tree.unanswered_call.call(phone_call) if phone_call.tree.unanswered_call
17
+ phone_call.tree.unanswered_call&.call(phone_call)
17
18
  end
18
19
  end
19
20
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module Phone
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module Phone
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module SMS
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module SMS
@@ -12,7 +13,7 @@ module Twilio
12
13
  from_number: params["From"].presence,
13
14
  from_city: params["FromCity"].presence,
14
15
  from_province: params["FromState"].presence,
15
- from_country: params["FromCountry"].presence,
16
+ from_country: params["FromCountry"].presence
16
17
  )
17
18
  conversation.save!
18
19
  conversation
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module SMS
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module SMS
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module SMS
@@ -19,7 +20,7 @@ module Twilio
19
20
  input :messages, accepts: Array, type: :keyword, required: true
20
21
  input :from_number, accepts: [String, Twilio::Rails::PhoneNumber], type: :keyword, required: false
21
22
 
22
- TWILIO_UNSUBSCRIBED_ERROR_CODES = [ 21610 ].freeze
23
+ TWILIO_UNSUBSCRIBED_ERROR_CODES = [21610].freeze
23
24
 
24
25
  # @param phone_caller_id [Integer] the id of the phone caller to send the message to.
25
26
  # @param messages [Array<String>] the messages to send to the phone caller. It may be empty.
@@ -29,14 +30,14 @@ module Twilio
29
30
  # @return [Twilio::Rails::Models::SMSConversation] the SMS conversation that was created and sent.
30
31
  def execute
31
32
  return nil if messages.blank?
32
- 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)
33
+ raise Twilio::Rails::SMS::Error, "from_number=#{from_number} is not a valid phone number" if from_number.present? && !Twilio::Rails::PhoneNumberFormatter.coerce(from_number)
33
34
 
34
35
  conversation = ::Twilio::Rails.config.sms_conversation_class.new(
35
36
  number: calculated_from_number,
36
37
  from_number: calculated_to_number,
37
38
  from_city: phone_call&.from_city,
38
39
  from_province: phone_call&.from_province,
39
- from_country: phone_call&.from_country,
40
+ from_country: phone_call&.from_country
40
41
  )
41
42
  conversation.save!
42
43
 
@@ -46,21 +47,20 @@ module Twilio
46
47
  sid = Twilio::Rails::Client.send_message(
47
48
  message: body,
48
49
  to: calculated_to_number,
49
- from: calculated_from_number,
50
+ from: calculated_from_number
50
51
  )
51
52
  rescue Twilio::REST::RestError => e
52
53
  if TWILIO_UNSUBSCRIBED_ERROR_CODES.include?(e.code)
53
- 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 }") }
54
+ 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}") }
54
55
  else
55
- Twilio::Rails.notify_exception(e,
56
- message: "Failed to send Twilio message. Got REST error response.",
56
+ ::Rails.error.report(e,
57
+ handled: false,
57
58
  context: {
59
+ message: "Failed to send Twilio message. Got REST error response.",
58
60
  to: calculated_to_number,
59
61
  from: calculated_from_number,
60
- phone_call_id: phone_call&.id,
61
- },
62
- exception_binding: binding
63
- )
62
+ phone_call_id: phone_call&.id
63
+ })
64
64
  raise
65
65
  end
66
66
  end
@@ -85,7 +85,7 @@ module Twilio
85
85
 
86
86
  def calculated_from_number
87
87
  if from_number.present?
88
- Twilio::Rails::Formatter.coerce_to_valid_phone_number(from_number)
88
+ Twilio::Rails::PhoneNumberFormatter.coerce(from_number)
89
89
  elsif phone_call
90
90
  phone_call.number
91
91
  else
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module SMS
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module SMS
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module SMS
@@ -20,7 +21,7 @@ module Twilio
20
21
  if body.present?
21
22
  message = conversation.messages.build(
22
23
  direction: "outbound",
23
- body: body,
24
+ body: body
24
25
  )
25
26
 
26
27
  message.save!
@@ -32,11 +33,11 @@ module Twilio
32
33
  )
33
34
  end
34
35
 
35
- Twilio::Rails.config.logger.info("message_twiml: #{twiml_response.to_s}")
36
+ Twilio::Rails.config.logger.info("message_twiml: #{twiml_response}")
36
37
  twiml_response.to_s
37
38
  else
38
39
  Twilio::Rails.config.logger.info("resply is blank, not sending message in response")
39
- Twilio::Rails.config.logger.info("message_twiml: #{twiml_response.to_s}")
40
+ Twilio::Rails.config.logger.info("message_twiml: #{twiml_response}")
40
41
 
41
42
  twiml = Twilio::TwiML::MessagingResponse.new
42
43
  twiml.to_s
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  module SMS
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Twilio::Rails::InstallGenerator < Rails::Generators::Base
3
4
  source_root File.expand_path("templates", __dir__)
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Twilio::Rails.setup do |config|
3
4
  # These are the Twilio account credentials used to access the Twilio API. These should likely be configured in the
4
5
  # encrypted Rails credentials or loaded from an ENV variable.
@@ -45,14 +46,6 @@ Twilio::Rails.setup do |config|
45
46
  # [ "Bad text" ].any? { |regex| regex.match?(params["Body"]) }
46
47
  # }
47
48
 
48
- # A proc that will be called when an exception is raised in certain key points in the framework. This will never
49
- # capture the exception, it will raise regardless, but it is a good spot to send an email or notify in chat
50
- # if desired. The proc needs to accept `(exception, message, context, exception_binding)` as arguments. The
51
- # default is `nil`, which means no action will be taken.
52
- # config.exception_notifier = ->(exception, message, context, exception_binding) {
53
- # MyChatClient.send_message("Error: #{ message } #{ exception.message } #{ context }")
54
- # }
55
-
56
49
  # Controls if recordings will be downloaded and attached to the `Recording` model in an ActiveStorage attachment.
57
50
  # This is `true` by default, but can be set to `false` to disable all downloads. It can also be set to a `Proc` or
58
51
  # callable that will receive the `Recording` instance and return a boolean for this specific instance. if reordings will be downloaded.
@@ -66,6 +59,10 @@ Twilio::Rails.setup do |config|
66
59
  # the phone macros. Defaults to a list of common responses.
67
60
  # config.no_responses = ["no"]
68
61
 
62
+ # An instance of class that will be used to format phone numbers. Defaults to `Twilio::Rails::PhoneNumberFormatter::NorthAmerica`
63
+ # for now but in the next major version it will be set to a formatter that can handle all countries.
64
+ # config.phone_number_formatter = Twilio::Rails::PhoneNumberFormatter::NorthAmerica.new
65
+
69
66
  # The name of the model classes, as strings, that this application uses to represent the concepts stored in the DB.
70
67
  # The generators will generate the models with the default names below, but they can be changed as the application
71
68
  # may need.
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Message < ApplicationRecord
3
4
  include Twilio::Rails::Models::Message
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class PhoneCall < ApplicationRecord
3
4
  include Twilio::Rails::Models::PhoneCall
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class PhoneCaller < ApplicationRecord
3
4
  include Twilio::Rails::Models::PhoneCaller
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Recording < ApplicationRecord
3
4
  include Twilio::Rails::Models::Recording
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Response < ApplicationRecord
3
4
  include Twilio::Rails::Models::Response
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class SMSConversation < ApplicationRecord
3
4
  include Twilio::Rails::Models::SMSConversation
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Twilio::Rails::PhoneTreeGenerator < Rails::Generators::NamedBase
3
4
  source_root File.expand_path("templates", __dir__)
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Twilio::Rails::SmsResponderGenerator < Rails::Generators::NamedBase
3
4
  source_root File.expand_path("templates", __dir__)
4
5
 
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
  class <%= class_name %>Responder < Twilio::Rails::SMS::DelegatedResponder
3
3
  def handle?
4
- raise NotImplementedError, "Implement #{ self.class }#handle?"
4
+ raise NoMethodError, "#{ self.class }#handle? must be implemented."
5
5
  end
6
6
 
7
7
  def reply
8
- raise NotImplementedError, "Implement #{ self.class }#reply"
8
+ raise NoMethodError, "#{ self.class }#reply must be implemented."
9
9
  end
10
10
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  namespace :twilio do
3
4
  namespace :rails do
4
5
  desc "Show the available values to config in Twilio"
@@ -9,7 +10,7 @@ namespace :twilio do
9
10
  puts "Twilio::Rails.config.host is set to a test value. Set it in the `config/initializers/twilio_rails.rb` file."
10
11
  else
11
12
  http_methods = if Twilio::Rails.config.controller_http_methods.length == 1
12
- "HTTP #{ Twilio::Rails.config.controller_http_methods.first.to_s.upcase }"
13
+ "HTTP #{Twilio::Rails.config.controller_http_methods.first.to_s.upcase}"
13
14
  else
14
15
  "HTTP POST or HTTP GET"
15
16
  end
@@ -22,18 +23,18 @@ namespace :twilio do
22
23
  puts "You cannot yet configure `Voice & Fax' because There are no phone trees registered in this application."
23
24
  puts "Register them in the `config/initializers/twilio_rails.rb` file if you want to handle phone calls, and run this task again to help configure Twilio."
24
25
  else
25
- puts "Under 'Voice & Fax' set 'A CALL COMES IN' to 'Webhook' with #{ http_methods } and one of the following URLs:"
26
+ puts "Under 'Voice & Fax' set 'A CALL COMES IN' to 'Webhook' with #{http_methods} and one of the following URLs:"
26
27
  Twilio::Rails.config.phone_trees.all.each do |name, tree|
27
28
  puts " #{tree.inbound_url}"
28
29
  end
29
30
  puts ""
30
31
  puts "Under 'Voice & Fax' set 'CALL STATUS CHANGES' to following URL:"
31
- puts " #{ ::Twilio::Rails.config.host }#{ ::Twilio::Rails::Engine.routes.url_helpers.phone_status_path(format: :xml) }"
32
+ puts " #{::Twilio::Rails.config.host}#{::Twilio::Rails::Engine.routes.url_helpers.phone_status_path(format: :xml)}"
32
33
  end
33
34
 
34
35
  puts ""
35
- puts "Under 'Messaging' set 'A MESSAGE COMES IN' to 'Webhook' with #{ http_methods } and the following URL:"
36
- puts " #{ ::Twilio::Rails.config.host }#{ ::Twilio::Rails::Engine.routes.url_helpers.sms_message_path(format: :xml) }"
36
+ puts "Under 'Messaging' set 'A MESSAGE COMES IN' to 'Webhook' with #{http_methods} and the following URL:"
37
+ puts " #{::Twilio::Rails.config.host}#{::Twilio::Rails::Engine.routes.url_helpers.sms_message_path(format: :xml)}"
37
38
 
38
39
  if Twilio::Rails.config.sms_responders.all.length == 0
39
40
  puts "There are no SMS responders registered so they will not be handled."
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  # An abstraction over top of the `Twilio::REST` API client. Used to send SMS messages and start calls, as well as
@@ -10,7 +11,7 @@ module Twilio
10
11
  def client
11
12
  @twilio_client ||= Twilio::REST::Client.new(
12
13
  Twilio::Rails.config.account_sid,
13
- Twilio::Rails.config.auth_token,
14
+ Twilio::Rails.config.auth_token
14
15
  )
15
16
  end
16
17
 
@@ -23,12 +24,12 @@ module Twilio
23
24
  # @param from [String] the phone number to send the message from.
24
25
  # @return [String] the SID returned from Twilio for the sent SMS message.
25
26
  def send_message(message:, to:, from:)
26
- Twilio::Rails.config.logger.tagged(self) { |l| l.info("[send_message] to=#{ to } from=#{ from } body='#{ message }'") }
27
+ Twilio::Rails.config.logger.tagged(self) { |l| l.info("[send_message] to=#{to} from=#{from} body='#{message}'") }
27
28
  client.messages.create(
28
29
  from: from,
29
30
  to: to,
30
31
  body: message,
31
- status_callback: "#{ Twilio::Rails.config.host }#{ ::Twilio::Rails::Engine.routes.url_helpers.sms_status_path(format: :xml) }",
32
+ status_callback: "#{Twilio::Rails.config.host}#{::Twilio::Rails::Engine.routes.url_helpers.sms_status_path(format: :xml)}"
32
33
  ).sid
33
34
  end
34
35
 
@@ -55,18 +56,18 @@ module Twilio
55
56
  # @param answering_machine_detection [true, false] whether or not to enable answering machine detection.
56
57
  # @return [String] the SID returned from Twilio for the started call.
57
58
  def start_call(url:, to:, from:, answering_machine_detection: true)
58
- Twilio::Rails.config.logger.tagged(self) { |l| l.info("[start_call] to=#{ to } from=#{ from } url=#{ url } answering_machine_detection=#{ !!answering_machine_detection }") }
59
+ Twilio::Rails.config.logger.tagged(self) { |l| l.info("[start_call] to=#{to} from=#{from} url=#{url} answering_machine_detection=#{!!answering_machine_detection}") }
59
60
  client.calls.create(
60
61
  from: from,
61
62
  to: to,
62
63
  url: url,
63
- machine_detection: ( answering_machine_detection ? "Enable" : "Disable" ),
64
+ machine_detection: (answering_machine_detection ? "Enable" : "Disable"),
64
65
  async_amd: true,
65
- async_amd_status_callback: "#{ Twilio::Rails.config.host }#{ ::Twilio::Rails::Engine.routes.url_helpers.phone_status_path(format: :xml, async_amd: "true") }",
66
+ async_amd_status_callback: "#{Twilio::Rails.config.host}#{::Twilio::Rails::Engine.routes.url_helpers.phone_status_path(format: :xml, async_amd: "true")}",
66
67
  async_amd_status_callback_method: "POST",
67
- status_callback: "#{ Twilio::Rails.config.host }#{ ::Twilio::Rails::Engine.routes.url_helpers.phone_status_path(format: :xml) }",
68
+ status_callback: "#{Twilio::Rails.config.host}#{::Twilio::Rails::Engine.routes.url_helpers.phone_status_path(format: :xml)}",
68
69
  status_callback_method: "POST",
69
- status_callback_event: ["completed", "no-answer"],
70
+ status_callback_event: ["completed", "no-answer"]
70
71
  # timeout: 30,
71
72
  ).sid
72
73
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  # Provides scopes, validations, and convenience methods for a model that has an attribute `direction` with
@@ -7,7 +8,7 @@ module Twilio
7
8
  extend ActiveSupport::Concern
8
9
 
9
10
  included do
10
- validates :direction, inclusion: { in: ["outbound", "inbound"] }
11
+ validates :direction, inclusion: {in: ["outbound", "inbound"]}
11
12
 
12
13
  scope :outbound, -> { where(direction: "outbound") }
13
14
  scope :inbound, -> { where(direction: "inbound") }
@@ -1,26 +1,35 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  # Provides validations and reformatting on validation for a model that has an attribute `phone_number` that is
5
- # that is unique and that matches {Twilio::Rails::Formatter.coerce_to_valid_phone_number}.
6
+ # that is unique and that matches {Twilio::Rails::PhoneNumberFormatter.coerce}.
6
7
  module HasPhoneNumber
7
8
  extend ActiveSupport::Concern
8
9
 
9
10
  included do
10
- validates :phone_number, uniqueness: { allow_blank: true, message: "already exists" }
11
+ validates :phone_number, uniqueness: {allow_blank: true, message: "already exists"}
11
12
 
12
13
  before_validation :reformat_phone_number
13
14
  end
14
15
 
15
16
  def reformat_phone_number
16
- current = Twilio::Rails::Formatter.coerce_to_valid_phone_number(phone_number)
17
+ current = Twilio::Rails::PhoneNumberFormatter.coerce(phone_number)
17
18
  self.phone_number = current if current
18
19
 
19
20
  true
20
21
  end
21
22
 
22
23
  def valid_north_american_phone_number?
23
- Twilio::Rails::Formatter.valid_north_american_phone_number?(phone_number)
24
+ Twilio::Rails.deprecator.warn(<<~DEPRECATION.strip)
25
+ valid_north_american_phone_number? is deprecated and will be removed in the next major version.
26
+ Use valid_phone_number? instead. The configured phone_number_formatter can manage the region of the phone number.
27
+ DEPRECATION
28
+ Twilio::Rails::PhoneNumberFormatter.valid?(phone_number)
29
+ end
30
+
31
+ def valid_phone_number?
32
+ Twilio::Rails::PhoneNumberFormatter.valid?(phone_number)
24
33
  end
25
34
  end
26
35
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Twilio
3
4
  module Rails
4
5
  # Provides convenience scopes for a model that has a `created_at` attribute.