twilio-ruby 3.11.5 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +13 -5
  2. data/.gitignore +1 -1
  3. data/.travis.yml +20 -9
  4. data/AUTHORS.md +32 -25
  5. data/CHANGES.md +203 -0
  6. data/Gemfile +8 -1
  7. data/{LICENSE → LICENSE.md} +4 -2
  8. data/Makefile +1 -2
  9. data/README.md +70 -39
  10. data/Rakefile +8 -10
  11. data/docs/faq.rst +3 -3
  12. data/docs/getting-started.rst +17 -12
  13. data/docs/index.rst +15 -0
  14. data/docs/usage/accounts.rst +6 -6
  15. data/docs/usage/addresses.rst +101 -0
  16. data/docs/usage/applications.rst +10 -10
  17. data/docs/usage/basics.rst +17 -4
  18. data/docs/usage/caller-ids.rst +4 -2
  19. data/docs/usage/conferences.rst +11 -11
  20. data/docs/usage/errors.rst +7 -7
  21. data/docs/usage/messages.rst +48 -20
  22. data/docs/usage/notifications.rst +6 -4
  23. data/docs/usage/phone-calls.rst +33 -14
  24. data/docs/usage/phone-numbers.rst +45 -31
  25. data/docs/usage/queues.rst +8 -8
  26. data/docs/usage/recordings.rst +12 -10
  27. data/docs/usage/sip.rst +15 -14
  28. data/docs/usage/taskrouter-tokens.rst +98 -0
  29. data/docs/usage/taskrouter.rst +226 -0
  30. data/docs/usage/token-generation.rst +19 -4
  31. data/docs/usage/transcriptions.rst +3 -2
  32. data/docs/usage/twiml.rst +7 -7
  33. data/docs/usage/validation.rst +39 -3
  34. data/examples/examples.rb +44 -20
  35. data/examples/print-call-log.rb +1 -1
  36. data/lib/rack/twilio_webhook_authentication.rb +47 -0
  37. data/lib/twilio-ruby/rest/accounts.rb +2 -1
  38. data/lib/twilio-ruby/rest/addresses/dependent_phone_numbers.rb +6 -0
  39. data/lib/twilio-ruby/rest/addresses.rb +12 -0
  40. data/lib/twilio-ruby/rest/base_client.rb +127 -0
  41. data/lib/twilio-ruby/rest/call_feedback.rb +28 -0
  42. data/lib/twilio-ruby/rest/call_feedback_summary.rb +13 -0
  43. data/lib/twilio-ruby/rest/calls.rb +10 -5
  44. data/lib/twilio-ruby/rest/client.rb +44 -109
  45. data/lib/twilio-ruby/rest/conferences/participants.rb +2 -2
  46. data/lib/twilio-ruby/rest/incoming_phone_numbers.rb +1 -1
  47. data/lib/twilio-ruby/rest/instance_resource.rb +2 -16
  48. data/lib/twilio-ruby/rest/list_resource.rb +20 -30
  49. data/lib/twilio-ruby/rest/lookups/phone_numbers.rb +17 -0
  50. data/lib/twilio-ruby/rest/lookups_client.rb +99 -0
  51. data/lib/twilio-ruby/rest/messages.rb +5 -0
  52. data/lib/twilio-ruby/rest/next_gen_list_resource.rb +36 -0
  53. data/lib/twilio-ruby/rest/outgoing_caller_ids.rb +1 -1
  54. data/lib/twilio-ruby/rest/queues/members.rb +1 -1
  55. data/lib/twilio-ruby/rest/sip.rb +1 -3
  56. data/lib/twilio-ruby/rest/sms/messages.rb +23 -0
  57. data/lib/twilio-ruby/rest/task_router/activities.rb +8 -0
  58. data/lib/twilio-ruby/rest/task_router/events.rb +8 -0
  59. data/lib/twilio-ruby/rest/task_router/reservations.rb +8 -0
  60. data/lib/twilio-ruby/rest/task_router/statistics.rb +26 -0
  61. data/lib/twilio-ruby/rest/task_router/task_queues.rb +17 -0
  62. data/lib/twilio-ruby/rest/task_router/task_queues_statistics.rb +15 -0
  63. data/lib/twilio-ruby/rest/task_router/tasks.rb +15 -0
  64. data/lib/twilio-ruby/rest/task_router/workers.rb +13 -0
  65. data/lib/twilio-ruby/rest/task_router/workers_statistics.rb +8 -0
  66. data/lib/twilio-ruby/rest/task_router/workflow_statistics.rb +7 -0
  67. data/lib/twilio-ruby/rest/task_router/workflows.rb +11 -0
  68. data/lib/twilio-ruby/rest/task_router/workspace_statistics.rb +7 -0
  69. data/lib/twilio-ruby/rest/task_router/workspaces.rb +17 -0
  70. data/lib/twilio-ruby/rest/task_router_client.rb +176 -0
  71. data/lib/twilio-ruby/rest/tokens.rb +7 -0
  72. data/lib/twilio-ruby/rest/usage/records.rb +2 -2
  73. data/lib/twilio-ruby/rest/utils.rb +35 -11
  74. data/lib/twilio-ruby/task_router/capability.rb +87 -0
  75. data/lib/twilio-ruby/task_router.rb +0 -0
  76. data/lib/twilio-ruby/twiml/response.rb +1 -0
  77. data/lib/twilio-ruby/util/capability.rb +10 -7
  78. data/lib/twilio-ruby/util/client_config.rb +29 -0
  79. data/lib/twilio-ruby/util/configuration.rb +7 -0
  80. data/lib/twilio-ruby/util/request_validator.rb +18 -3
  81. data/lib/twilio-ruby/version.rb +1 -1
  82. data/lib/twilio-ruby.rb +48 -0
  83. data/spec/rack/twilio_webhook_authentication_spec.rb +110 -0
  84. data/spec/rest/account_spec.rb +51 -20
  85. data/spec/rest/address_spec.rb +11 -0
  86. data/spec/rest/call_feedback_spec.rb +12 -0
  87. data/spec/rest/call_feedback_summary_spec.rb +9 -0
  88. data/spec/rest/call_spec.rb +8 -4
  89. data/spec/rest/client_spec.rb +209 -51
  90. data/spec/rest/conference_spec.rb +4 -2
  91. data/spec/rest/instance_resource_spec.rb +4 -4
  92. data/spec/rest/lookups/phone_number_spec.rb +8 -0
  93. data/spec/rest/message_spec.rb +2 -2
  94. data/spec/rest/numbers_spec.rb +25 -13
  95. data/spec/rest/queue_spec.rb +4 -2
  96. data/spec/rest/recording_spec.rb +4 -2
  97. data/spec/rest/sms/message_spec.rb +37 -0
  98. data/spec/rest/sms/messages_spec.rb +31 -0
  99. data/spec/rest/task_router/reservation_spec.rb +9 -0
  100. data/spec/rest/task_router/task_queue_spec.rb +9 -0
  101. data/spec/rest/token_spec.rb +7 -0
  102. data/spec/rest/utils_spec.rb +45 -0
  103. data/spec/spec_helper.rb +12 -3
  104. data/spec/support/fakeweb.rb +2 -0
  105. data/spec/task_router_spec.rb +114 -0
  106. data/spec/twilio_spec.rb +15 -0
  107. data/spec/util/capability_spec.rb +167 -118
  108. data/spec/util/client_config_spec.rb +21 -0
  109. data/spec/util/configuration_spec.rb +15 -0
  110. data/spec/util/request_validator_spec.rb +31 -3
  111. data/spec/util/url_encode_spec.rb +2 -2
  112. data/twilio-ruby.gemspec +28 -27
  113. metadata +93 -71
  114. data/CHANGES +0 -47
data/lib/twilio-ruby.rb CHANGED
@@ -5,20 +5,28 @@ require 'multi_json'
5
5
  require 'cgi'
6
6
  require 'openssl'
7
7
  require 'base64'
8
+ require 'forwardable'
8
9
  require 'jwt'
9
10
 
10
11
  require 'twilio-ruby/version' unless defined?(Twilio::VERSION)
11
12
  require 'twilio-ruby/util'
13
+ require 'twilio-ruby/util/client_config'
14
+ require 'twilio-ruby/util/configuration'
12
15
  require 'twilio-ruby/util/request_validator'
13
16
  require 'twilio-ruby/util/capability'
14
17
  require 'twilio-ruby/twiml/response'
18
+ require 'twilio-ruby/task_router'
19
+ require 'twilio-ruby/task_router/capability'
15
20
  require 'twilio-ruby/rest/errors'
16
21
  require 'twilio-ruby/rest/utils'
17
22
  require 'twilio-ruby/rest/list_resource'
23
+ require 'twilio-ruby/rest/next_gen_list_resource'
18
24
  require 'twilio-ruby/rest/instance_resource'
19
25
  require 'twilio-ruby/rest/sandbox'
20
26
  require 'twilio-ruby/rest/accounts'
21
27
  require 'twilio-ruby/rest/calls'
28
+ require 'twilio-ruby/rest/call_feedback'
29
+ require 'twilio-ruby/rest/call_feedback_summary'
22
30
  require 'twilio-ruby/rest/sms'
23
31
  require 'twilio-ruby/rest/sms/short_codes'
24
32
  require 'twilio-ruby/rest/sms/messages'
@@ -30,6 +38,20 @@ require 'twilio-ruby/rest/sip/credential_lists'
30
38
  require 'twilio-ruby/rest/sip/credential_lists/credentials'
31
39
  require 'twilio-ruby/rest/sip/ip_access_control_lists'
32
40
  require 'twilio-ruby/rest/sip/ip_access_control_lists/ip_addresses'
41
+ require 'twilio-ruby/rest/task_router/statistics'
42
+ require 'twilio-ruby/rest/task_router/activities'
43
+ require 'twilio-ruby/rest/task_router/events'
44
+ require 'twilio-ruby/rest/task_router/reservations'
45
+ require 'twilio-ruby/rest/task_router/task_queues'
46
+ require 'twilio-ruby/rest/task_router/task_queues_statistics'
47
+ require 'twilio-ruby/rest/task_router/tasks'
48
+ require 'twilio-ruby/rest/task_router/workers'
49
+ require 'twilio-ruby/rest/task_router/workers_statistics'
50
+ require 'twilio-ruby/rest/task_router/workflow_statistics'
51
+ require 'twilio-ruby/rest/task_router/workflows'
52
+ require 'twilio-ruby/rest/task_router/workspaces'
53
+ require 'twilio-ruby/rest/task_router/workspace_statistics'
54
+ require 'twilio-ruby/rest/lookups/phone_numbers'
33
55
  require 'twilio-ruby/rest/media'
34
56
  require 'twilio-ruby/rest/messages'
35
57
  require 'twilio-ruby/rest/applications'
@@ -54,5 +76,31 @@ require 'twilio-ruby/rest/usage/records'
54
76
  require 'twilio-ruby/rest/usage/triggers'
55
77
  require 'twilio-ruby/rest/recordings'
56
78
  require 'twilio-ruby/rest/transcriptions'
79
+ require 'twilio-ruby/rest/tokens'
57
80
  require 'twilio-ruby/rest/notifications'
81
+ require 'twilio-ruby/rest/addresses'
82
+ require 'twilio-ruby/rest/addresses/dependent_phone_numbers'
58
83
  require 'twilio-ruby/rest/client'
84
+ require 'twilio-ruby/rest/task_router_client'
85
+ require 'twilio-ruby/rest/lookups_client'
86
+ require 'rack/twilio_webhook_authentication'
87
+
88
+ module Twilio
89
+ extend SingleForwardable
90
+
91
+ def_delegators :configuration, :account_sid, :auth_token
92
+
93
+ ##
94
+ # Pre-configure with account SID and auth token so that you don't need to
95
+ # pass them to various initializers each time.
96
+ def self.configure(&block)
97
+ yield configuration
98
+ end
99
+
100
+ ##
101
+ # Returns an existing or instantiates a new configuration object.
102
+ def self.configuration
103
+ @configuration ||= Util::Configuration.new
104
+ end
105
+ private_class_method :configuration
106
+ end
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+ require 'rack/mock'
3
+
4
+ describe Rack::TwilioWebhookAuthentication do
5
+ before do
6
+ @app = lambda {|env| [200, {'Content-Type' => 'text/plain'}, ['Hello']] }
7
+ end
8
+
9
+ describe 'new' do
10
+ it 'should initialize with an app, auth token and a path' do
11
+ expect {
12
+ Rack::TwilioWebhookAuthentication.new(@app, 'ABC', /\/voice/)
13
+ }.not_to raise_error
14
+ end
15
+
16
+ it 'should initialize with an app, auth token and paths' do
17
+ expect {
18
+ Rack::TwilioWebhookAuthentication.new(@app, 'ABC', /\/voice/, /\/sms/)
19
+ }.not_to raise_error
20
+ end
21
+
22
+ it 'should initialize with an app, dynamic token and paths' do
23
+ expect {
24
+ Rack::TwilioWebhookAuthentication.new(@app, nil, /\/voice/, /\/sms/)
25
+ }.not_to raise_error
26
+ end
27
+ end
28
+
29
+ describe 'calling against one path with dynamic auth token' do
30
+ it 'should allow a request through if it validates' do
31
+ auth_token = 'qwerty'
32
+ account_sid = 12345
33
+ expect_any_instance_of(Rack::Request).to receive(:post?).and_return(true)
34
+ expect_any_instance_of(Rack::Request).to receive(:POST).and_return({'AccountSid' => account_sid})
35
+ @middleware = Rack::TwilioWebhookAuthentication.new(@app, nil, /\/voice/) { |asid| auth_token}
36
+ request_validator = double('RequestValidator')
37
+ expect(Twilio::Util::RequestValidator).to receive(:new).with(auth_token).and_return(request_validator)
38
+ expect(request_validator).to receive(:validate).and_return(true)
39
+ request = Rack::MockRequest.env_for('/voice')
40
+ status, headers, body = @middleware.call(request)
41
+ expect(status).to be(200)
42
+ end
43
+ end
44
+
45
+ describe 'calling against one path' do
46
+ before do
47
+ @middleware = Rack::TwilioWebhookAuthentication.new(
48
+ @app, 'ABC', /\/voice/
49
+ )
50
+ end
51
+
52
+ it 'should not intercept when the path doesn\'t match' do
53
+ expect(Twilio::Util::RequestValidator).to_not receive(:validate)
54
+ request = Rack::MockRequest.env_for('/sms')
55
+ status, headers, body = @middleware.call(request)
56
+ expect(status).to be(200)
57
+ end
58
+
59
+ it 'should allow a request through if it validates' do
60
+ expect_any_instance_of(Twilio::Util::RequestValidator).to(
61
+ receive(:validate).and_return(true)
62
+ )
63
+ request = Rack::MockRequest.env_for('/voice')
64
+ status, headers, body = @middleware.call(request)
65
+ expect(status).to be(200)
66
+ end
67
+
68
+ it 'should short circuit a request to 403 if it does not validate' do
69
+ expect_any_instance_of(Twilio::Util::RequestValidator).to(
70
+ receive(:validate).and_return(false)
71
+ )
72
+ request = Rack::MockRequest.env_for('/voice')
73
+ status, headers, body = @middleware.call(request)
74
+ expect(status).to be(403)
75
+ end
76
+ end
77
+
78
+ describe 'calling against many paths' do
79
+ before do
80
+ @middleware = Rack::TwilioWebhookAuthentication.new(
81
+ @app, 'ABC', /\/voice/, /\/sms/
82
+ )
83
+ end
84
+
85
+ it 'should not intercept when the path doesn\'t match' do
86
+ expect(Twilio::Util::RequestValidator).to_not receive(:validate)
87
+ request = Rack::MockRequest.env_for('icesms')
88
+ status, headers, body = @middleware.call(request)
89
+ expect(status).to be(200)
90
+ end
91
+
92
+ it 'shold allow a request through if it validates' do
93
+ expect_any_instance_of(Twilio::Util::RequestValidator).to(
94
+ receive(:validate).and_return(true)
95
+ )
96
+ request = Rack::MockRequest.env_for('/sms')
97
+ status, headers, body = @middleware.call(request)
98
+ expect(status).to be(200)
99
+ end
100
+
101
+ it 'should short circuit a request to 403 if it does not validate' do
102
+ expect_any_instance_of(Twilio::Util::RequestValidator).to(
103
+ receive(:validate).and_return(false)
104
+ )
105
+ request = Rack::MockRequest.env_for('/sms')
106
+ status, headers, body = @middleware.call(request)
107
+ expect(status).to be(403)
108
+ end
109
+ end
110
+ end
@@ -7,52 +7,83 @@ describe Twilio::REST::Account do
7
7
  end
8
8
 
9
9
  it 'sets up incoming phone numbers resources object' do
10
- @account.should respond_to(:incoming_phone_numbers)
11
- @account.incoming_phone_numbers.instance_variable_get('@path').should == 'someUri/IncomingPhoneNumbers'
10
+ expect(@account).to respond_to(:incoming_phone_numbers)
11
+ expect(@account.incoming_phone_numbers.instance_variable_get('@path')).to(
12
+ eq('someUri/IncomingPhoneNumbers')
13
+ )
12
14
  end
13
15
 
14
16
  it 'sets up an available phone numbers resources object' do
15
- @account.should respond_to(:available_phone_numbers)
16
- @account.available_phone_numbers.instance_variable_get('@path').should == 'someUri/AvailablePhoneNumbers'
17
+ expect(@account).to respond_to(:available_phone_numbers)
18
+ expect(@account.available_phone_numbers.instance_variable_get('@path')).to(
19
+ eq('someUri/AvailablePhoneNumbers')
20
+ )
17
21
  end
18
22
 
19
23
  it 'sets up an outgoing caller ids resources object' do
20
- @account.should respond_to(:outgoing_caller_ids)
21
- @account.outgoing_caller_ids.instance_variable_get('@path').should == 'someUri/OutgoingCallerIds'
24
+ expect(@account).to respond_to(:outgoing_caller_ids)
25
+ expect(@account.outgoing_caller_ids.instance_variable_get('@path')).to eq(
26
+ 'someUri/OutgoingCallerIds'
27
+ )
22
28
  end
23
29
 
24
30
  it 'sets up a calls resources object' do
25
- @account.should respond_to(:calls)
26
- @account.calls.instance_variable_get('@path').should == 'someUri/Calls'
31
+ expect(@account).to respond_to(:calls)
32
+ expect(@account.calls.instance_variable_get('@path')).to eq('someUri/Calls')
27
33
  end
28
34
 
29
35
  it 'sets up a conferences resources object' do
30
- @account.should respond_to(:conferences)
31
- @account.conferences.instance_variable_get('@path').should == 'someUri/Conferences'
36
+ expect(@account).to respond_to(:conferences)
37
+ expect(@account.conferences.instance_variable_get('@path')).to eq(
38
+ 'someUri/Conferences'
39
+ )
32
40
  end
33
41
 
34
42
  it 'sets up a queues resources object' do
35
- @account.should respond_to(:queues)
36
- @account.queues.instance_variable_get('@path').should == 'someUri/Queues'
43
+ expect(@account).to respond_to(:queues)
44
+ expect(@account.queues.instance_variable_get('@path')).to eq(
45
+ 'someUri/Queues'
46
+ )
37
47
  end
38
48
 
39
49
  it 'sets up a sms resource object' do
40
- @account.should respond_to(:sms)
41
- @account.sms.instance_variable_get('@path').should == 'someUri/SMS'
50
+ expect(@account).to respond_to(:sms)
51
+ expect(@account.sms.instance_variable_get('@path')).to eq('someUri/SMS')
42
52
  end
43
53
 
44
54
  it 'sets up a recordings resources object' do
45
- @account.should respond_to(:recordings)
46
- @account.recordings.instance_variable_get('@path').should == 'someUri/Recordings'
55
+ expect(@account).to respond_to(:recordings)
56
+ expect(@account.recordings.instance_variable_get('@path')).to eq(
57
+ 'someUri/Recordings'
58
+ )
47
59
  end
48
60
 
49
61
  it 'sets up a transcriptions resources object' do
50
- @account.should respond_to(:transcriptions)
51
- @account.transcriptions.instance_variable_get('@path').should == 'someUri/Transcriptions'
62
+ expect(@account).to respond_to(:transcriptions)
63
+ expect(@account.transcriptions.instance_variable_get('@path')).to eq(
64
+ 'someUri/Transcriptions'
65
+ )
52
66
  end
53
67
 
54
68
  it 'sets up a notifications resources object' do
55
- @account.should respond_to(:notifications)
56
- @account.notifications.instance_variable_get('@path').should == 'someUri/Notifications'
69
+ expect(@account).to respond_to(:notifications)
70
+ expect(@account.notifications.instance_variable_get('@path')).to eq(
71
+ 'someUri/Notifications'
72
+ )
57
73
  end
74
+
75
+ it 'sets up a tokens resources object' do
76
+ expect(@account).to respond_to(:tokens)
77
+ expect(@account.tokens.instance_variable_get('@path')).to eq(
78
+ 'someUri/Tokens'
79
+ )
80
+ end
81
+
82
+ it 'sets up an addresses resources object' do
83
+ expect(@account).to respond_to(:addresses)
84
+ expect(@account.addresses.instance_variable_get('@path')).to eq(
85
+ 'someUri/Addresses'
86
+ )
87
+ end
88
+
58
89
  end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twilio::REST::Address do
4
+ it 'should set up a dependent phone numbers resources object' do
5
+ address = Twilio::REST::Address.new('someUri', 'someClient')
6
+ expect(address).to respond_to(:dependent_phone_numbers)
7
+ expect(address.dependent_phone_numbers.instance_variable_get('@path')).to eq(
8
+ 'someUri/DependentPhoneNumbers'
9
+ )
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twilio::REST::Feedback do
4
+ before do
5
+ @call = Twilio::REST::Call.new('someUri', 'someClient')
6
+ end
7
+
8
+ it 'sets up a feedback resources object' do
9
+ expect(@call).to respond_to(:feedback)
10
+ expect(@call.feedback.instance_variable_get('@path')).to eq('someUri/Feedback')
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twilio::REST::FeedbackSummary do
4
+ it 'creates a feedback summary object' do
5
+ calls = Twilio::REST::Calls.new('someUri', 'someClient')
6
+ expect(calls).to respond_to(:feedback_summary)
7
+ expect(calls.feedback_summary.instance_variable_get('@path')).to eq('someUri/FeedbackSummary')
8
+ end
9
+ end
@@ -7,12 +7,16 @@ describe Twilio::REST::Call do
7
7
  end
8
8
 
9
9
  it 'sets up a recordings resources object' do
10
- @call.should respond_to(:recordings)
11
- @call.recordings.instance_variable_get('@path').should == 'someUri/Recordings'
10
+ expect(@call).to respond_to(:recordings)
11
+ expect(@call.recordings.instance_variable_get('@path')).to eq(
12
+ 'someUri/Recordings'
13
+ )
12
14
  end
13
15
 
14
16
  it 'sets up a notifications resources object' do
15
- @call.should respond_to(:notifications)
16
- @call.notifications.instance_variable_get('@path').should == 'someUri/Notifications'
17
+ expect(@call).to respond_to(:notifications)
18
+ expect(@call.notifications.instance_variable_get('@path')).to eq(
19
+ 'someUri/Notifications'
20
+ )
17
21
  end
18
22
  end