telnyx 2.2.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/scripts/before_install.sh +9 -0
  3. data/.github/workflows/ruby.yml +39 -0
  4. data/.gitignore +3 -0
  5. data/.rubocop.yml +6 -36
  6. data/.rubocop_todo.yml +300 -0
  7. data/.travis.yml.bak +48 -0
  8. data/Gemfile +10 -6
  9. data/README.md +1 -1
  10. data/VERSION +1 -1
  11. data/bin/telnyx-console +5 -0
  12. data/examples/2 factor authentication/Gemfile +7 -0
  13. data/examples/2 factor authentication/main.rb +67 -0
  14. data/examples/2 factor authentication/readme.md +5 -0
  15. data/examples/fax/Gemfile +7 -0
  16. data/examples/fax/config.yaml +4 -0
  17. data/examples/fax/fax.rb +42 -0
  18. data/examples/fax/options.rb +41 -0
  19. data/examples/fax/readme.md +18 -0
  20. data/lib/telnyx.rb +5 -1
  21. data/lib/telnyx/api_operations/create.rb +6 -1
  22. data/lib/telnyx/api_operations/save.rb +1 -1
  23. data/lib/telnyx/api_resource.rb +24 -3
  24. data/lib/telnyx/call.rb +3 -1
  25. data/lib/telnyx/conference.rb +17 -1
  26. data/lib/telnyx/fax.rb +13 -0
  27. data/lib/telnyx/fax_application.rb +12 -0
  28. data/lib/telnyx/messaging_phone_number.rb +4 -0
  29. data/lib/telnyx/phone_number.rb +7 -3
  30. data/lib/telnyx/phone_number_regulatory_requirement.rb +1 -0
  31. data/lib/telnyx/sim_card.rb +12 -1
  32. data/lib/telnyx/telnyx_client.rb +16 -25
  33. data/lib/telnyx/util.rb +12 -34
  34. data/lib/telnyx/verification.rb +36 -0
  35. data/lib/telnyx/verify_profile.rb +11 -0
  36. data/lib/telnyx/version.rb +1 -1
  37. data/telnyx.gemspec +2 -2
  38. data/test/telnyx/alphanumeric_sender_id_test.rb +1 -1
  39. data/test/telnyx/api_operations_test.rb +1 -1
  40. data/test/telnyx/api_resource_test.rb +1 -1
  41. data/test/telnyx/available_phone_number_test.rb +1 -1
  42. data/test/telnyx/call_control_test.rb +50 -47
  43. data/test/telnyx/conference_test.rb +57 -20
  44. data/test/telnyx/credential_connection_test.rb +5 -1
  45. data/test/telnyx/errors_test.rb +1 -1
  46. data/test/telnyx/fax_application_test.rb +32 -0
  47. data/test/telnyx/fax_test.rb +33 -0
  48. data/test/telnyx/fqdn_connection_test.rb +1 -1
  49. data/test/telnyx/fqdn_test.rb +1 -1
  50. data/test/telnyx/list_object_test.rb +1 -1
  51. data/test/telnyx/message_test.rb +1 -1
  52. data/test/telnyx/messaging_phone_number_test.rb +9 -5
  53. data/test/telnyx/messaging_profile_test.rb +2 -2
  54. data/test/telnyx/number_reservation_test.rb +2 -0
  55. data/test/telnyx/phone_number_regulatory_requirement_test.rb +1 -1
  56. data/test/telnyx/phone_number_test.rb +9 -21
  57. data/test/telnyx/public_key_test.rb +1 -1
  58. data/test/telnyx/sim_card_test.rb +6 -6
  59. data/test/telnyx/telnyx_client_test.rb +43 -49
  60. data/test/telnyx/telnyx_object_test.rb +17 -19
  61. data/test/telnyx/telnyx_response_test.rb +1 -1
  62. data/test/telnyx/util_test.rb +1 -1
  63. data/test/telnyx/verification_test.rb +24 -0
  64. data/test/telnyx/verify_profile_test.rb +33 -0
  65. data/test/telnyx/webhook_test.rb +1 -1
  66. data/test/telnyx/wireless_detail_records_report_test.rb +1 -0
  67. data/test/telnyx_test.rb +20 -24
  68. data/test/test_helper.rb +1 -1
  69. metadata +52 -11
  70. data/.travis.yml +0 -51
@@ -6,5 +6,9 @@ module Telnyx
6
6
  extend Telnyx::APIOperations::List
7
7
 
8
8
  OBJECT_NAME = "messaging_phone_number".freeze
9
+ def self.resource_path(id = nil)
10
+ return "phone_numbers/#{CGI.escape(id)}/messaging" if id
11
+ "phone_numbers/messaging"
12
+ end
9
13
  end
10
14
  end
@@ -13,7 +13,7 @@ module Telnyx
13
13
  instance_methods: { list: "voice" }
14
14
  nested_resource_class_methods "messaging",
15
15
  path: ["messaging"],
16
- operations: %i[update list],
16
+ operations: %i[update list retrieve],
17
17
  instance_methods: { list: "messaging" }
18
18
  nested_resource_class_methods "inbound_channel",
19
19
  path: ["inbound_channels"],
@@ -35,8 +35,12 @@ module Telnyx
35
35
  self.class.list_inbound_channels(nil).channels
36
36
  end
37
37
 
38
- def self.list_voice
39
- list_voices nil
38
+ def self.list_voice(*args, **kwargs)
39
+ list_voices(nil, *args, **kwargs)
40
+ end
41
+
42
+ def self.messaging
43
+ list_messagings(nil)
40
44
  end
41
45
 
42
46
  OBJECT_NAME = "phone_number".freeze
@@ -5,5 +5,6 @@ module Telnyx
5
5
  extend APIOperations::List
6
6
 
7
7
  OBJECT_NAME = "phone_number_regulatory_requirement".freeze
8
+ RESOURCE_PATH = "phone_numbers_regulatory_requirements".freeze
8
9
  end
9
10
  end
@@ -6,7 +6,7 @@ module Telnyx
6
6
  extend APIOperations::NestedResource
7
7
  extend APIOperations::List
8
8
 
9
- ACTIONS = %w[deactivate activate].freeze
9
+ ACTIONS = %w[enable disable].freeze
10
10
  ACTIONS.each do |action|
11
11
  nested_resource_class_methods action,
12
12
  path: %W[actions #{action}],
@@ -20,5 +20,16 @@ module Telnyx
20
20
  end
21
21
 
22
22
  OBJECT_NAME = "sim_card".freeze
23
+
24
+ # depreciated api
25
+ def activate
26
+ warn "[DEPRECATION] SimCard#activate is deprecated, use enable instead."
27
+ enable
28
+ end
29
+
30
+ def deactivate
31
+ warn "[DEPRECATION] SimCard#deactivate is deprecated, use enable instead."
32
+ disable
33
+ end
23
34
  end
24
35
  end
@@ -240,7 +240,7 @@ module Telnyx
240
240
  end
241
241
 
242
242
  case e
243
- when Faraday::ClientError
243
+ when Faraday::Error
244
244
  if e.response
245
245
  handle_error_response(e.response, error_context)
246
246
  else
@@ -310,30 +310,21 @@ module Telnyx
310
310
  json_body: resp.data,
311
311
  }
312
312
 
313
- case resp.http_status
314
- when 400
315
- InvalidRequestError.new(error_list, opts)
316
- when 401
317
- AuthenticationError.new(error_list, opts)
318
- when 403
319
- PermissionError.new(error_list, opts)
320
- when 404
321
- ResourceNotFoundError.new(error_list, opts)
322
- when 405
323
- MethodNotSupportedError.new(error_list, opts)
324
- when 408
325
- TimeoutError.new(error_list, opts)
326
- when 422
327
- InvalidParametersError.new(error_list, opts)
328
- when 429
329
- RateLimitError.new(error_list, opts)
330
- when 500
331
- APIError.new(error_list, opts)
332
- when 503
333
- ServiceUnavailableError.new(error_list, opts)
334
- else
335
- APIError.new(error_list, opts)
336
- end
313
+ err_class = case resp.http_status
314
+ when 400 then InvalidRequestError
315
+ when 401 then AuthenticationError
316
+ when 403 then PermissionError
317
+ when 404 then ResourceNotFoundError
318
+ when 405 then MethodNotSupportedError
319
+ when 408 then TimeoutError
320
+ when 422 then InvalidParametersError
321
+ when 429 then RateLimitError
322
+ when 500 then APIError
323
+ when 503 then ServiceUnavailableError
324
+ else APIError
325
+ end
326
+
327
+ err_class.new(error_list, **opts)
337
328
  end
338
329
 
339
330
  def handle_network_error(e, context, num_retries, api_base = nil)
data/lib/telnyx/util.rb CHANGED
@@ -37,39 +37,17 @@ module Telnyx
37
37
  end
38
38
 
39
39
  def self.object_classes
40
- @object_classes ||= {
41
- # business objects
42
- Address::OBJECT_NAME => Address,
43
- AlphanumericSenderId::OBJECT_NAME => AlphanumericSenderId,
44
- AvailablePhoneNumber::OBJECT_NAME => AvailablePhoneNumber,
45
- BillingGroup::OBJECT_NAME => BillingGroup,
46
- Call::OBJECT_NAME => Call,
47
- CallControlApplication::OBJECT_NAME => CallControlApplication,
48
- Conferences::OBJECT_NAME => Conferences,
49
- Connection::OBJECT_NAME => Connection,
50
- CredentialConnection::OBJECT_NAME => CredentialConnection,
51
- FQDN::OBJECT_NAME => FQDN,
52
- FQDNConnection::OBJECT_NAME => FQDNConnection,
53
- IP::OBJECT_NAME => IP,
54
- IPConnection::OBJECT_NAME => IPConnection,
55
- Message::OBJECT_NAME => Message,
56
- MessagingPhoneNumber::OBJECT_NAME => MessagingPhoneNumber,
57
- MessagingProfile::OBJECT_NAME => MessagingProfile,
58
- NumberLookup::OBJECT_NAME => NumberLookup,
59
- NumberOrder::OBJECT_NAME => NumberOrder,
60
- NumberOrderDocument::OBJECT_NAME => NumberOrderDocument,
61
- NumberReservation::OBJECT_NAME => NumberReservation,
62
- OutboundVoiceProfile::OBJECT_NAME => OutboundVoiceProfile,
63
- PhoneNumber::OBJECT_NAME => PhoneNumber,
64
- "phone_number_reservation" => NumberReservation,
65
- PhoneNumberRegulatoryRequirement::OBJECT_NAME => PhoneNumberRegulatoryRequirement,
66
- "phone_number_regulatory_group" => PhoneNumberRegulatoryRequirement,
67
- Portout::OBJECT_NAME => Portout,
68
- PublicKey::OBJECT_NAME => PublicKey,
69
- RegulatoryRequirement::OBJECT_NAME => RegulatoryRequirement,
70
- SimCard::OBJECT_NAME => SimCard,
71
- WirelessDetailRecordsReport::OBJECT_NAME => WirelessDetailRecordsReport,
72
- }
40
+ @object_classes ||= APIResource.descendants
41
+ .select { |klass| klass.constants(false).include? :OBJECT_NAME }
42
+ .map { |klass| [klass::OBJECT_NAME, klass] }
43
+ .to_h
44
+ .merge(
45
+ "messaging_settings" => MessagingPhoneNumber,
46
+ "phone_number_regulatory_group" => PhoneNumberRegulatoryRequirement,
47
+ "phone_number_reservation" => NumberReservation,
48
+ "verification_profile" => VerifyProfile,
49
+ "verification" => Verification::Response
50
+ )
73
51
  end
74
52
 
75
53
  def self.push_object_class(key, klass)
@@ -86,7 +64,7 @@ module Telnyx
86
64
  #
87
65
  # ==== Attributes
88
66
  #
89
- # * +data+ - Hash of fields and values to be converted into a TelnyxObject.
67
+ # * +Data+ - Hash of fields and values to be converted into a TelnyxObject.
90
68
  # * +opts+ - Options for +TelnyxObject+ like an API key that will be reused
91
69
  # on subsequent API calls.
92
70
  def self.convert_to_telnyx_object(data, opts = {})
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Telnyx
4
+ class Verification < APIResource
5
+ # Type for verification responses
6
+ class Response < TelnyxObject; end
7
+
8
+ extend APIOperations::Create
9
+ extend APIOperations::NestedResource
10
+
11
+ class << self
12
+ private :create
13
+ end
14
+
15
+ nested_resource_class_methods "by_telephone",
16
+ path: "by_tn",
17
+ operations: [:retrieve],
18
+ instance_methods: {
19
+ retrieve: "by_telephone",
20
+ }
21
+
22
+ def self.submit_code(phone_number: nil, code: nil)
23
+ url = "#{resource_url}/by_phone_number/#{CGI.escape phone_number}/actions/verify"
24
+ resp, _opts = request(:post, url, code: code)
25
+ Response.construct_from resp.data[:data]
26
+ end
27
+
28
+ # Trigger a call verification
29
+ def self.call(params = {}, opts = {})
30
+ create(params, { **opts, resource_url: "#{resource_url}/call" })
31
+ end
32
+
33
+ OBJECT_NAME = "verify_verification".freeze
34
+ RESOURCE_PATH = "verifications".freeze
35
+ end
36
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Telnyx
4
+ class VerifyProfile < APIResource
5
+ extend APIOperations::List
6
+ extend APIOperations::Create
7
+ include APIOperations::Save
8
+
9
+ OBJECT_NAME = "verify_profile".freeze
10
+ end
11
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Telnyx
4
- VERSION = "2.2.0".freeze
4
+ VERSION = "2.7.0".freeze
5
5
  end
data/telnyx.gemspec CHANGED
@@ -22,8 +22,8 @@ Gem::Specification.new do |s|
22
22
  "source_code_uri" => "https://github.com/team-telnyx/telnyx-ruby",
23
23
  }
24
24
 
25
- s.add_dependency("faraday", "~> 0.13", "!= 0.16.0", "!= 0.16.1", "!= 0.16.2")
26
- s.add_dependency("net-http-persistent", "~> 3.0")
25
+ s.add_dependency("faraday", ">= 0.13", "< 2.0", "!= 0.16.0", "!= 0.16.1", "!= 0.16.2", "!= 0.17.1")
26
+ s.add_dependency("net-http-persistent", ">= 3.0", "< 5.0")
27
27
  s.add_dependency("ed25519", "~> 1")
28
28
 
29
29
  s.files = `git ls-files`.split("\n")
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require ::File.expand_path("../../test_helper", __FILE__)
3
+ require_relative "../test_helper"
4
4
 
5
5
  module Telnyx
6
6
  class AlphanumericSenderIdTest < Test::Unit::TestCase
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # frozen_string_literal: true
3
3
 
4
- require ::File.expand_path("../../test_helper", __FILE__)
4
+ require_relative "../test_helper"
5
5
 
6
6
  module Telnyx
7
7
  class ApiOperationsTest < Test::Unit::TestCase
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # frozen_string_literal: true
3
3
 
4
- require ::File.expand_path("../../test_helper", __FILE__)
4
+ require_relative "../test_helper"
5
5
 
6
6
  module Telnyx
7
7
  class ApiResourceTest < Test::Unit::TestCase
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require ::File.expand_path("../../test_helper", __FILE__)
3
+ require_relative "../test_helper"
4
4
 
5
5
  module Telnyx
6
6
  class AvailablePhoneNumberTest < Test::Unit::TestCase
@@ -37,6 +37,8 @@ module Telnyx
37
37
  assert defined? @call.record_stop
38
38
  assert defined? @call.send_dtmf
39
39
  assert defined? @call.transfer
40
+ assert defined? @call.enqueue
41
+ assert defined? @call.leave_queue
40
42
  end
41
43
  end
42
44
 
@@ -62,99 +64,100 @@ module Telnyx
62
64
  assert call.call_leg_id
63
65
  assert call.call_session_id
64
66
  end
65
-
66
- should "send all commands" do
67
- @call = Call.new
68
- @call.id = "1234"
69
- @call.reject
70
- assert_requested :post, format_url(@call, "reject")
71
- @call.answer
72
- assert_requested :post, format_url(@call, "answer")
73
- @call.hangup
74
- assert_requested :post, format_url(@call, "hangup")
75
- @call.bridge call_control_id: SecureRandom.base64(20)
76
- assert_requested :post, format_url(@call, "bridge")
77
- @call.speak language: "en-US", voice: "female", payload: "Telnyx call control test"
78
- assert_requested :post, format_url(@call, "speak")
79
- @call.fork_start call_control_id: SecureRandom.base64(20)
80
- assert_requested :post, format_url(@call, "fork_start")
81
- @call.fork_stop
82
- assert_requested :post, format_url(@call, "fork_stop")
83
- @call.gather_using_audio audio_url: "https://audio.example.com"
84
- assert_requested :post, format_url(@call, "gather_using_audio")
85
- @call.gather_using_speak language: "en-US", voice: "female", payload: "Telnyx call control test"
86
- assert_requested :post, format_url(@call, "gather_using_speak")
87
- @call.playback_start audio_url: "https://audio.example.com"
88
- assert_requested :post, format_url(@call, "playback_start")
89
- @call.playback_stop
90
- assert_requested :post, format_url(@call, "playback_stop")
91
- @call.send_dtmf digits: "1www2WABCDw9"
92
- assert_requested :post, format_url(@call, "send_dtmf")
93
- @call.transfer to: "+15552223333"
94
- assert_requested :post, format_url(@call, "transfer")
95
- end
96
67
  end
97
68
 
98
69
  context "commands" do
99
70
  should "reject" do
100
- @call.reject
101
- assert_requested :post, format_url(@call, "reject")
71
+ @call.reject cause: "CALL_REJECTED"
72
+ assert_requested :post, format_action_url(@call, "reject")
102
73
  end
103
74
  should "answer" do
104
75
  @call.answer
105
- assert_requested :post, format_url(@call, "answer")
76
+ assert_requested :post, format_action_url(@call, "answer")
106
77
  end
107
78
  should "hangup" do
108
79
  @call.hangup
109
- assert_requested :post, format_url(@call, "hangup")
80
+ assert_requested :post, format_action_url(@call, "hangup")
110
81
  end
111
82
  should "bridge" do
112
83
  @call.bridge call_control_id: SecureRandom.base64(20)
113
- assert_requested :post, format_url(@call, "bridge")
84
+ assert_requested :post, format_action_url(@call, "bridge")
114
85
  end
115
86
  should "speak" do
116
87
  @call.speak language: "en-US", voice: "female", payload: "Telnyx call control test"
117
- assert_requested :post, format_url(@call, "speak")
88
+ assert_requested :post, format_action_url(@call, "speak")
118
89
  end
119
90
  should "start fork" do
120
91
  @call.fork_start call_control_id: SecureRandom.base64(20)
121
- assert_requested :post, format_url(@call, "fork_start")
92
+ assert_requested :post, format_action_url(@call, "fork_start")
122
93
  end
123
94
  should "stop fork" do
124
95
  @call.fork_stop
125
- assert_requested :post, format_url(@call, "fork_stop")
96
+ assert_requested :post, format_action_url(@call, "fork_stop")
126
97
  end
127
98
  should "gather using audio" do
128
99
  @call.gather_using_audio audio_url: "https://audio.example.com"
129
- assert_requested :post, format_url(@call, "gather_using_audio")
100
+ assert_requested :post, format_action_url(@call, "gather_using_audio")
130
101
  end
131
102
  should "gather using speak" do
132
103
  @call.gather_using_speak language: "en-US", voice: "female", payload: "Telnyx call control test"
133
- assert_requested :post, format_url(@call, "gather_using_speak")
104
+ assert_requested :post, format_action_url(@call, "gather_using_speak")
134
105
  end
135
106
  should "playback start" do
136
107
  @call.playback_start audio_url: "https://audio.example.com"
137
- assert_requested :post, format_url(@call, "playback_start")
108
+ assert_requested :post, format_action_url(@call, "playback_start")
138
109
  end
139
110
  should "playback stop" do
140
111
  @call.playback_stop
141
- assert_requested :post, format_url(@call, "playback_stop")
112
+ assert_requested :post, format_action_url(@call, "playback_stop")
142
113
  end
143
114
  should "send dtmf" do
144
115
  @call.send_dtmf digits: "1www2WABCDw9"
145
- assert_requested :post, format_url(@call, "send_dtmf")
116
+ assert_requested :post, format_action_url(@call, "send_dtmf")
146
117
  end
147
118
  should "transfer" do
148
119
  @call.transfer to: "+15552223333"
149
- assert_requested :post, format_url(@call, "transfer")
120
+ assert_requested :post, format_action_url(@call, "transfer")
121
+ end
122
+ should "start transcription" do
123
+ @call.transcription_start
124
+ assert_requested :post, format_action_url(@call, "transcription_start")
125
+ end
126
+ should "end transcription" do
127
+ @call.transcription_stop
128
+ assert_requested :post, format_action_url(@call, "transcription_stop")
129
+ end
130
+ should "pause recording" do
131
+ @call.record_pause
132
+ assert_requested :post, format_action_url(@call, "record_pause")
133
+ end
134
+ should "resume recording" do
135
+ @call.record_resume
136
+ assert_requested :post, format_action_url(@call, "record_resume")
137
+ end
138
+ should "gather stop" do
139
+ @call.gather_stop
140
+ assert_requested :post, format_action_url(@call, "gather_stop")
141
+ end
142
+ should "refer" do
143
+ @call.refer sip_address: "sip:username@sip.non-telnyx-address.com"
144
+ assert_requested :post, format_action_url(@call, "refer")
145
+ end
146
+ should "enqueue" do
147
+ @call.enqueue call_control_id: SecureRandom.base64(20)
148
+ assert_requested :post, format_action_url(@call, "enqueue")
149
+ end
150
+ should "leave_queue" do
151
+ @call.leave_queue call_control_id: SecureRandom.base64(20)
152
+ assert_requested :post, format_action_url(@call, "leave_queue")
150
153
  end
151
154
  end
152
155
 
153
156
  def create_call
154
- Telnyx::Call.create connection_id: "12345", to: "+15550001111", from: "+15550002222"
157
+ Telnyx::Call.create connection_id: "12345", to: "+15550001111", from: "+15550002222", cause: "test"
155
158
  end
156
159
 
157
- def format_url(call, action)
160
+ def format_action_url(call, action)
158
161
  "#{Telnyx.api_base}/v2/calls/#{call.call_control_id}/actions/#{action}"
159
162
  end
160
163
  end