twilio-ruby 3.11.5 → 3.12.3
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.
- checksums.yaml +13 -5
- data/.gitignore +1 -1
- data/.travis.yml +20 -8
- data/AUTHORS.md +29 -25
- data/{CHANGES → CHANGES.md} +45 -1
- data/Gemfile +8 -1
- data/{LICENSE → LICENSE.md} +1 -1
- data/Makefile +1 -2
- data/README.md +57 -26
- data/Rakefile +8 -10
- data/docs/getting-started.rst +3 -3
- data/docs/usage/applications.rst +5 -5
- data/docs/usage/basics.rst +17 -4
- data/docs/usage/caller-ids.rst +2 -2
- data/docs/usage/conferences.rst +5 -5
- data/docs/usage/errors.rst +1 -1
- data/docs/usage/messages.rst +6 -6
- data/docs/usage/notifications.rst +2 -2
- data/docs/usage/phone-calls.rst +7 -7
- data/docs/usage/phone-numbers.rst +12 -12
- data/docs/usage/queues.rst +6 -6
- data/docs/usage/recordings.rst +5 -5
- data/docs/usage/sip.rst +5 -5
- data/docs/usage/token-generation.rst +18 -3
- data/docs/usage/transcriptions.rst +1 -1
- data/docs/usage/twiml.rst +1 -1
- data/docs/usage/validation.rst +27 -1
- data/examples/print-call-log.rb +1 -1
- data/lib/rack/twilio_webhook_authentication.rb +40 -0
- data/lib/twilio-ruby/rest/call_feedback.rb +28 -0
- data/lib/twilio-ruby/rest/call_feedback_summary.rb +13 -0
- data/lib/twilio-ruby/rest/calls.rb +6 -1
- data/lib/twilio-ruby/rest/client.rb +43 -5
- data/lib/twilio-ruby/rest/list_resource.rb +10 -4
- data/lib/twilio-ruby/rest/usage/records.rb +2 -2
- data/lib/twilio-ruby/twiml/response.rb +1 -0
- data/lib/twilio-ruby/util/capability.rb +6 -3
- data/lib/twilio-ruby/util/configuration.rb +7 -0
- data/lib/twilio-ruby/util/request_validator.rb +3 -2
- data/lib/twilio-ruby/version.rb +1 -1
- data/lib/twilio-ruby.rb +25 -0
- data/spec/rack/twilio_webhook_authentication_spec.rb +76 -0
- data/spec/rest/account_spec.rb +20 -20
- data/spec/rest/call_feedback_spec.rb +12 -0
- data/spec/rest/call_feedback_summary_spec.rb +9 -0
- data/spec/rest/call_spec.rb +4 -4
- data/spec/rest/client_spec.rb +114 -38
- data/spec/rest/conference_spec.rb +2 -2
- data/spec/rest/instance_resource_spec.rb +3 -3
- data/spec/rest/message_spec.rb +2 -2
- data/spec/rest/numbers_spec.rb +12 -12
- data/spec/rest/queue_spec.rb +2 -2
- data/spec/rest/recording_spec.rb +2 -2
- data/spec/spec_helper.rb +12 -3
- data/spec/support/fakeweb.rb +2 -0
- data/spec/twilio_spec.rb +15 -0
- data/spec/util/capability_spec.rb +167 -118
- data/spec/util/configuration_spec.rb +13 -0
- data/spec/util/request_validator_spec.rb +31 -3
- data/spec/util/url_encode_spec.rb +1 -1
- data/twilio-ruby.gemspec +28 -27
- metadata +46 -71
data/docs/usage/phone-calls.rst
CHANGED
@@ -25,7 +25,7 @@ outputs valid `TwiML <http://www.twilio.com/docs/api/twiml/>`_.
|
|
25
25
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
26
26
|
|
27
27
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
28
|
-
@call = @client.
|
28
|
+
@call = @client.calls.create({:to => "9991231234",
|
29
29
|
:from => "9991231234",
|
30
30
|
:url => "http://foo.com/call.xml"})
|
31
31
|
puts @call.length
|
@@ -48,7 +48,7 @@ you can use the client to retrieve that record.
|
|
48
48
|
|
49
49
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
50
50
|
sid = "CA12341234"
|
51
|
-
@call = @client.
|
51
|
+
@call = @client.calls.get(sid)
|
52
52
|
|
53
53
|
|
54
54
|
Accessing Specific Call Resources
|
@@ -69,7 +69,7 @@ just like the :class:`Calls` resource itself.
|
|
69
69
|
|
70
70
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
71
71
|
sid = "CA12341234"
|
72
|
-
@call = @client.
|
72
|
+
@call = @client.calls.get(sid)
|
73
73
|
|
74
74
|
puts @call.notifications.list()
|
75
75
|
puts @call.recordings.list()
|
@@ -109,7 +109,7 @@ redirect them as necessary
|
|
109
109
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
110
110
|
|
111
111
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
112
|
-
@calls = @client.
|
112
|
+
@calls = @client.calls.list({:status => "in-progress"})
|
113
113
|
|
114
114
|
@calls.each do |call|
|
115
115
|
call.redirect_to("http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient")
|
@@ -127,7 +127,7 @@ Ending all live calls is also possible
|
|
127
127
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
128
128
|
|
129
129
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
130
|
-
@calls = @client.
|
130
|
+
@calls = @client.calls.list({:status => "in-progress"})
|
131
131
|
|
132
132
|
@calls.each do |call|
|
133
133
|
call.hangup()
|
@@ -148,7 +148,7 @@ resource to update the record without having to use :meth:`get` first.
|
|
148
148
|
|
149
149
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
150
150
|
sid = "CA12341234"
|
151
|
-
@client.
|
151
|
+
@client.calls.get(sid).redirect_to("http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient")
|
152
152
|
|
153
153
|
Hanging up the call also works.
|
154
154
|
|
@@ -162,5 +162,5 @@ Hanging up the call also works.
|
|
162
162
|
|
163
163
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
164
164
|
sid = "CA12341234"
|
165
|
-
@client.
|
165
|
+
@client.calls.get(sid).hangup()
|
166
166
|
|
@@ -27,7 +27,7 @@ Once we find one, we'll purchase it for our account.
|
|
27
27
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
28
28
|
|
29
29
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
30
|
-
numbers = @client.
|
30
|
+
numbers = @client.available_phone_numbers.list(:area_code=>"530")
|
31
31
|
|
32
32
|
if numbers:
|
33
33
|
numbers[0].purchase()
|
@@ -51,13 +51,13 @@ You can search for numbers for a given type.
|
|
51
51
|
.. code-block:: ruby
|
52
52
|
|
53
53
|
# local
|
54
|
-
numbers = @client.
|
54
|
+
numbers = @client.available_phone_numbers.local.list()
|
55
55
|
|
56
56
|
# toll free
|
57
|
-
numbers = @client.
|
57
|
+
numbers = @client.available_phone_numbers.toll_free.list()
|
58
58
|
|
59
59
|
# mobile
|
60
|
-
numbers = @client.
|
60
|
+
numbers = @client.available_phone_numbers.mobile.list()
|
61
61
|
|
62
62
|
Numbers Containing Words
|
63
63
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@@ -67,13 +67,13 @@ The following example will find any phone number with "FOO" in it.
|
|
67
67
|
|
68
68
|
.. code-block:: ruby
|
69
69
|
|
70
|
-
numbers = @client.
|
70
|
+
numbers = @client.available_phone_numbers.list(:contains=>"FOO")
|
71
71
|
|
72
72
|
You can use the ''*'' wildcard to match any character. The following example finds any phone number that matches the pattern ''D*D''.
|
73
73
|
|
74
74
|
.. code-block:: ruby
|
75
75
|
|
76
|
-
numbers = @client.
|
76
|
+
numbers = @client.available_phone_numbers.list(:contains=>"D*D")
|
77
77
|
|
78
78
|
|
79
79
|
International Numbers
|
@@ -85,7 +85,7 @@ international numbers.
|
|
85
85
|
|
86
86
|
.. code-block:: ruby
|
87
87
|
|
88
|
-
numbers = @client.
|
88
|
+
numbers = @client.available_phone_numbers.list(:country=>"FR")
|
89
89
|
|
90
90
|
|
91
91
|
:meth:`PhoneNumbers.search` method has plenty of other options to augment your search :
|
@@ -115,7 +115,7 @@ If you've found a phone number you want, you can purchase the number.
|
|
115
115
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
116
116
|
|
117
117
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
118
|
-
@number = @client.
|
118
|
+
@number = @client.available_phone_numbers.purchase({:phone_number => "+15305431234"})
|
119
119
|
|
120
120
|
However, it's easier to purchase numbers after finding them using search (as
|
121
121
|
shown in the first example).
|
@@ -138,9 +138,9 @@ listed in the `IncomingPhoneNumbers Resource documentation
|
|
138
138
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
139
139
|
|
140
140
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
141
|
-
@client.
|
142
|
-
number.update({:voice_url => "http://twimlets.com/holdmusic?" +
|
143
|
-
"Bucket=com.twilio.music.ambient",
|
141
|
+
@client.available_phone_numbers.list(api_version="2010-04-01").each do |number|
|
142
|
+
number.update({:voice_url => "http://twimlets.com/holdmusic?" +
|
143
|
+
"Bucket=com.twilio.music.ambient",
|
144
144
|
:status_callback => "http://example.com/callback"})
|
145
145
|
|
146
146
|
|
@@ -161,7 +161,7 @@ An :class:`Application` encapsulates all necessary URLs for use with phone numbe
|
|
161
161
|
|
162
162
|
phone_sid = "PNXXXXXXXXXXXXXXXXX"
|
163
163
|
|
164
|
-
@number = @client.
|
164
|
+
@number = @client.available_phone_numbers.get(phone_sid)
|
165
165
|
@number.update(:sms_application_sid => "APXXXXXXXXXXXXXXXXXX")
|
166
166
|
|
167
167
|
See :doc:`/usage/applications` for instructions on updating and maintaining Applications.
|
data/docs/usage/queues.rst
CHANGED
@@ -22,8 +22,8 @@ Listing Queues
|
|
22
22
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
23
23
|
|
24
24
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
25
|
-
@queues = @client.
|
26
|
-
|
25
|
+
@queues = @client.queues.list()
|
26
|
+
|
27
27
|
@queues.each do |queue|
|
28
28
|
puts queue.sid
|
29
29
|
end
|
@@ -44,7 +44,7 @@ represents all current calls in the queue.
|
|
44
44
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
45
45
|
|
46
46
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
47
|
-
@queue = @client.
|
47
|
+
@queue = @client.queues.get("QU123")
|
48
48
|
|
49
49
|
@queue.members.list().each do |member|
|
50
50
|
print member.call_sid
|
@@ -74,8 +74,8 @@ first call in the queue.
|
|
74
74
|
|
75
75
|
queue_sid = "QUAAAAAAAAAAAAA"
|
76
76
|
call_sid = "CAXXXXXXXXXXXXXX"
|
77
|
-
|
78
|
-
@members = @client.
|
77
|
+
|
78
|
+
@members = @client.queues.get(queue_sid).members
|
79
79
|
|
80
80
|
# Get the first call in the queue
|
81
81
|
puts members.front.date_enqueued
|
@@ -106,7 +106,7 @@ default values are 'Front' and 'GET'
|
|
106
106
|
|
107
107
|
queue_sid = "QUAAAAAAAAAAAAA"
|
108
108
|
|
109
|
-
@members = @client.
|
109
|
+
@members = @client.queues.get(queue_sid).members
|
110
110
|
|
111
111
|
# Dequeue the first call in the queue
|
112
112
|
puts @members.dequeue('http://www.twilio.com/welcome/call')
|
data/docs/usage/recordings.rst
CHANGED
@@ -14,7 +14,7 @@ Audio Formats
|
|
14
14
|
|
15
15
|
Each :class:`Recording` has a few special methods. To get the url
|
16
16
|
for the wav format of this recording, use :meth:`Recording.wav`. For the
|
17
|
-
mp3 format, use :meth:`Recording.mp3`. To make requests for either of
|
17
|
+
mp3 format, use :meth:`Recording.mp3`. To make requests for either of
|
18
18
|
these formats use the same method with a '!' appended. These methods
|
19
19
|
both take a block to be executed as soon as the response returns.
|
20
20
|
|
@@ -35,7 +35,7 @@ for each :class:`Recording`.
|
|
35
35
|
|
36
36
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
37
37
|
|
38
|
-
@client.
|
38
|
+
@client.recordings.list().each do |recording|
|
39
39
|
puts recording.duration
|
40
40
|
|
41
41
|
You can filter recordings by CallSid by passing the Sid as :attr:`call`.
|
@@ -52,7 +52,7 @@ The following will only show recordings made before January 1, 2011.
|
|
52
52
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
53
53
|
|
54
54
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
55
|
-
@client.
|
55
|
+
@client.recordings.list(before=date(2011,1,1)).each do |recording|:
|
56
56
|
puts recording.duration
|
57
57
|
|
58
58
|
|
@@ -70,7 +70,7 @@ The :class:`Recordings` resource allows you to delete unnecessary recordings.
|
|
70
70
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
71
71
|
|
72
72
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
73
|
-
@client.
|
73
|
+
@client.recordings.get("RC123").delete()
|
74
74
|
|
75
75
|
|
76
76
|
Accessing Related Transcptions
|
@@ -89,7 +89,7 @@ with this recording.
|
|
89
89
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
90
90
|
|
91
91
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
92
|
-
@recording = @client.
|
92
|
+
@recording = @client.recordings.get("RC123")
|
93
93
|
|
94
94
|
@recording.transcriptions.list().each do |transcription|
|
95
95
|
puts transcription.transcription_text
|
data/docs/usage/sip.rst
CHANGED
@@ -26,7 +26,7 @@ under sip.twilio.com.
|
|
26
26
|
|
27
27
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
28
28
|
|
29
|
-
@domain = @client.
|
29
|
+
@domain = @client.sip.domains.create(
|
30
30
|
{:friendly_name => "The Office Domain",
|
31
31
|
:voice_url => "http://example.com/voice",
|
32
32
|
:domain_name => "dunder-mifflin-scranton.sip.twilio.com",}
|
@@ -38,7 +38,7 @@ Creating a new IpAccessControlList
|
|
38
38
|
|
39
39
|
To control access to your new domain, you'll need to explicitly grant access
|
40
40
|
to individual ip addresses. To do this, you'll first need to create an
|
41
|
-
:class:`IpAccessControlList` to hold the ip addresses you wish to allow.
|
41
|
+
:class:`IpAccessControlList` to hold the ip addresses you wish to allow.
|
42
42
|
|
43
43
|
.. code-block:: ruby
|
44
44
|
|
@@ -50,7 +50,7 @@ to individual ip addresses. To do this, you'll first need to create an
|
|
50
50
|
|
51
51
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
52
52
|
|
53
|
-
@ip_acl = @client.
|
53
|
+
@ip_acl = @client.sip.ip_access_control_lists.create(
|
54
54
|
{:friendly_name => "The Office IpAccessControlList",}
|
55
55
|
)
|
56
56
|
puts @ip_acl.sid
|
@@ -70,7 +70,7 @@ Now it's time to add an :class:`IpAddress` to your new :class:`IpAccessControlLi
|
|
70
70
|
|
71
71
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
72
72
|
|
73
|
-
@ip_address = @client.
|
73
|
+
@ip_address = @client.sip.ip_access_control_lists.get(
|
74
74
|
"AL456", # IpAccessControlList sid
|
75
75
|
).ip_addresses.create(
|
76
76
|
{:friendly_name => "Dwights's Computer",
|
@@ -94,7 +94,7 @@ associate them. To do this, create an :class:`IpAccessControlListMapping`.
|
|
94
94
|
|
95
95
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
96
96
|
|
97
|
-
@ip_acl_mapping = @client.
|
97
|
+
@ip_acl_mapping = @client.sip.domains.get(
|
98
98
|
"SD456", # SIP Domain sid
|
99
99
|
).ip_access_control_list_mappings.create(
|
100
100
|
{:ip_access_control_list_sid => "AL789"})
|
@@ -17,11 +17,11 @@ security and authorization. The `Capability Token documentation
|
|
17
17
|
<http://www.twilio.com/docs/tokens>`_ explains in depth the purpose and
|
18
18
|
features of these tokens.
|
19
19
|
|
20
|
-
:class:`
|
21
|
-
tokens. You'll need your Twilio AccountSid and AuthToken.
|
20
|
+
:class:`Twilio::Util::Capability` is responsible for the creation of these
|
21
|
+
capability tokens. You'll need your Twilio AccountSid and AuthToken.
|
22
22
|
|
23
23
|
.. code-block:: ruby
|
24
|
-
|
24
|
+
|
25
25
|
require 'twilio-ruby'
|
26
26
|
|
27
27
|
# Find these values at twilio.com/user/account
|
@@ -30,6 +30,21 @@ tokens. You'll need your Twilio AccountSid and AuthToken.
|
|
30
30
|
|
31
31
|
@capability = Twilio::Util::Capability.new account_sid, auth_token
|
32
32
|
|
33
|
+
You can also configure capability tokens using the top level configure method,
|
34
|
+
like so:
|
35
|
+
|
36
|
+
.. code-block:: ruby
|
37
|
+
|
38
|
+
require 'twilio-ruby'
|
39
|
+
|
40
|
+
Twilio.configure do |config|
|
41
|
+
config.account_sid = "ACXXXXXXXXXXXXXXXXX"
|
42
|
+
config.auth_token = "YYYYYYYYYYYYYYYYYY"
|
43
|
+
end
|
44
|
+
|
45
|
+
@capability = Twilio::Util::Capability.new
|
46
|
+
|
47
|
+
|
33
48
|
|
34
49
|
Allow Incoming Connections
|
35
50
|
==============================
|
@@ -26,6 +26,6 @@ The following code will print out the length of each :class:`Transcription`.
|
|
26
26
|
auth_token = "YYYYYYYYYYYYYYYYYY"
|
27
27
|
|
28
28
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
29
|
-
@client.
|
29
|
+
@client.transcriptions.list().each do |transcription|
|
30
30
|
puts transcription.duration
|
31
31
|
|
data/docs/usage/twiml.rst
CHANGED
data/docs/usage/validation.rst
CHANGED
@@ -53,7 +53,6 @@ actually from Twilio.
|
|
53
53
|
puts "NOT VALID. It might have been spoofed!"
|
54
54
|
end
|
55
55
|
|
56
|
-
|
57
56
|
Trailing Slashes
|
58
57
|
==================
|
59
58
|
|
@@ -69,3 +68,30 @@ https://mycompany.com/twilio and you may have built the hash using
|
|
69
68
|
https://mycompany.com/twilio/. More information can be found in our
|
70
69
|
documentation on validating requests.
|
71
70
|
|
71
|
+
Rack Middleware
|
72
|
+
===============
|
73
|
+
|
74
|
+
If you are serving up your site using a Rack based framework, such as Sinatra or
|
75
|
+
Rails, you can use the Rack middleware that is included in the gem to protect
|
76
|
+
from spoofing attempts.
|
77
|
+
|
78
|
+
To use the middleware, you need to set it up with your Twilio Auth Token and a
|
79
|
+
set of paths to watch. For example, here is how you would use the middleware in
|
80
|
+
a Sinatra application:
|
81
|
+
|
82
|
+
.. code-block:: ruby
|
83
|
+
|
84
|
+
require 'sinatra'
|
85
|
+
require 'twilio-ruby'
|
86
|
+
|
87
|
+
auth_token = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'
|
88
|
+
|
89
|
+
use Rack::TwilioWebhookAuthentication, auth_token, /\/messages/
|
90
|
+
|
91
|
+
post '/messages' do
|
92
|
+
# response with TwiML
|
93
|
+
end
|
94
|
+
|
95
|
+
Now, any POST request to /messages in your application that doesn't validate as
|
96
|
+
a Twilio request, will automatically respond with a 403 status code and your
|
97
|
+
action will not be hit.
|
data/examples/print-call-log.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Rack
|
2
|
+
# Middleware that authenticates webhooks from Twilio using the request
|
3
|
+
# validator.
|
4
|
+
#
|
5
|
+
# The middleware takes an auth token with which to set up the request
|
6
|
+
# validator and any number of paths. When a path matches the incoming request
|
7
|
+
# path, the request will be checked for authentication.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
#
|
11
|
+
# require 'rack'
|
12
|
+
# use Rack::TwilioWebhookAuthentication, ENV['AUTH_TOKEN'], /\/messages/
|
13
|
+
#
|
14
|
+
# The above appends this middleware to the stack, using an auth token saved in
|
15
|
+
# the ENV and only against paths that match /\/messages/. If the request
|
16
|
+
# validates then it gets passed on to the action as normal. If the request
|
17
|
+
# doesn't validate then the middleware responds immediately with a 403 status.
|
18
|
+
|
19
|
+
class TwilioWebhookAuthentication
|
20
|
+
def initialize(app, auth_token, *paths)
|
21
|
+
@app = app
|
22
|
+
@auth_token = auth_token
|
23
|
+
@path_regex = Regexp.union(paths)
|
24
|
+
end
|
25
|
+
|
26
|
+
def call(env)
|
27
|
+
return @app.call(env) unless env["PATH_INFO"].match(@path_regex)
|
28
|
+
validator = Twilio::Util::RequestValidator.new(@auth_token)
|
29
|
+
request = Rack::Request.new(env)
|
30
|
+
original_url = request.url
|
31
|
+
params = request.post? ? request.POST : {}
|
32
|
+
signature = env['HTTP_X_TWILIO_SIGNATURE']
|
33
|
+
if validator.validate(original_url, params, signature)
|
34
|
+
@app.call(env)
|
35
|
+
else
|
36
|
+
[403, {'Content-Type' => 'text/plain'}, ["Twilio Request Validation Failed."]]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Twilio
|
2
|
+
module REST
|
3
|
+
class Feedback < ListResource;
|
4
|
+
|
5
|
+
##
|
6
|
+
# Get this feedback object.
|
7
|
+
#
|
8
|
+
# Overridden because GETS to /Feedback
|
9
|
+
# returns an instance, not a list.
|
10
|
+
def get(params={}, full_path=false)
|
11
|
+
raise "Can't fetch feedback without a REST Client" unless @client
|
12
|
+
response = @client.get @path, params, full_path
|
13
|
+
path = full_path ? @path.split('.')[0] : @path
|
14
|
+
@instance_class.new path, @client, response
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Creates a new Feedback object.
|
19
|
+
def create(params={})
|
20
|
+
raise "Can't create feedback without a REST Client" unless @client
|
21
|
+
response = @client.post @path, params
|
22
|
+
@instance_class.new @path, @client, response
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class FeedbackInstance < InstanceResource; end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Twilio
|
2
|
+
module REST
|
3
|
+
class FeedbackSummary < ListResource
|
4
|
+
def initialize(path, client)
|
5
|
+
@path, @client = path, client
|
6
|
+
@instance_class = Twilio::REST::FeedbackSummaryInstance
|
7
|
+
@list_key, @instance_id_key = 'feedback_summary', 'sid'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class FeedbackSummaryInstance < InstanceResource; end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module Twilio
|
2
2
|
module REST
|
3
3
|
class Calls < ListResource
|
4
|
+
def initialize(path, client)
|
5
|
+
super
|
6
|
+
resource :feedback_summary
|
7
|
+
end
|
8
|
+
|
4
9
|
def make(from, to, url)
|
5
10
|
create :from => from, :to => to, :url => url
|
6
11
|
end
|
@@ -9,7 +14,7 @@ module Twilio
|
|
9
14
|
class Call < InstanceResource
|
10
15
|
def initialize(path, client, params={})
|
11
16
|
super path, client, params
|
12
|
-
resource :recordings, :notifications
|
17
|
+
resource :recordings, :notifications, :feedback
|
13
18
|
end
|
14
19
|
|
15
20
|
def redirect_to(url)
|
@@ -28,6 +28,12 @@ module Twilio
|
|
28
28
|
#
|
29
29
|
# @client.account.calls
|
30
30
|
#
|
31
|
+
# For convenience, the resources of the default account are also available
|
32
|
+
# on the client object. So the following call is equivalent to the example
|
33
|
+
# above
|
34
|
+
#
|
35
|
+
# @client.calls
|
36
|
+
#
|
31
37
|
# represents an account's call list.
|
32
38
|
#
|
33
39
|
# ==== @client.accounts
|
@@ -48,7 +54,11 @@ module Twilio
|
|
48
54
|
API_VERSION = '2010-04-01'
|
49
55
|
|
50
56
|
# 1.8.7 doesn't have the RUBY_ENGINE constant.
|
51
|
-
|
57
|
+
if defined?(RUBY_ENGINE)
|
58
|
+
engine = RUBY_ENGINE
|
59
|
+
else
|
60
|
+
engine = 'ruby'
|
61
|
+
end
|
52
62
|
|
53
63
|
HTTP_HEADERS = {
|
54
64
|
'Accept' => 'application/json',
|
@@ -75,7 +85,8 @@ module Twilio
|
|
75
85
|
|
76
86
|
##
|
77
87
|
# Instantiate a new HTTP client to talk to Twilio. The parameters
|
78
|
-
# +account_sid+ and +auth_token+ are required
|
88
|
+
# +account_sid+ and +auth_token+ are required, unless you have configured
|
89
|
+
# them already using the block configure syntax, and used to generate the
|
79
90
|
# HTTP basic auth header in each request. The +options+ parameter is a
|
80
91
|
# hash of connection configuration options. the following keys are
|
81
92
|
# supported:
|
@@ -138,9 +149,16 @@ module Twilio
|
|
138
149
|
#
|
139
150
|
# The number of times to retry a request that has failed before throwing
|
140
151
|
# an exception. Defaults to one.
|
141
|
-
def initialize(
|
142
|
-
|
152
|
+
def initialize(*args)
|
153
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
143
154
|
@config = DEFAULTS.merge! options
|
155
|
+
|
156
|
+
@account_sid = args[0] || Twilio.account_sid
|
157
|
+
@auth_token = args[1] || Twilio.auth_token
|
158
|
+
if @account_sid.nil? || @auth_token.nil?
|
159
|
+
raise ArgumentError, 'Account SID and auth token are required'
|
160
|
+
end
|
161
|
+
|
144
162
|
set_up_connection
|
145
163
|
set_up_subresources
|
146
164
|
end
|
@@ -169,6 +187,26 @@ module Twilio
|
|
169
187
|
end
|
170
188
|
end
|
171
189
|
|
190
|
+
##
|
191
|
+
# Delegate account methods from the client. This saves having to call
|
192
|
+
# <tt>client.account</tt> every time for resources on the default
|
193
|
+
# account.
|
194
|
+
def method_missing(method_name, *args, &block)
|
195
|
+
if account.respond_to?(method_name)
|
196
|
+
account.send(method_name, *args, &block)
|
197
|
+
else
|
198
|
+
super
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def respond_to?(method_name, include_private=false)
|
203
|
+
if account.respond_to?(method_name, include_private)
|
204
|
+
true
|
205
|
+
else
|
206
|
+
super
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
172
210
|
private
|
173
211
|
|
174
212
|
##
|
@@ -182,7 +220,7 @@ module Twilio
|
|
182
220
|
@connection.open_timeout = @config[:timeout]
|
183
221
|
@connection.read_timeout = @config[:timeout]
|
184
222
|
end
|
185
|
-
|
223
|
+
|
186
224
|
##
|
187
225
|
# Set up the ssl properties of the <tt>@connection</tt> Net::HTTP object.
|
188
226
|
# This is a private method documented for completeness.
|
@@ -3,9 +3,12 @@ module Twilio
|
|
3
3
|
class ListResource
|
4
4
|
include Utils
|
5
5
|
|
6
|
-
|
7
6
|
def initialize(path, client)
|
8
|
-
custom_names = {
|
7
|
+
custom_names = {
|
8
|
+
'Media' => 'MediaInstance',
|
9
|
+
'IpAddresses' => 'IpAddress',
|
10
|
+
'Feedback' => 'FeedbackInstance',
|
11
|
+
}
|
9
12
|
@path, @client = path, client
|
10
13
|
resource_name = self.class.name.split('::')[-1]
|
11
14
|
instance_name = custom_names.fetch(resource_name, resource_name.chop)
|
@@ -13,7 +16,7 @@ module Twilio
|
|
13
16
|
# The next line grabs the enclosing module. Necessary for resources
|
14
17
|
# contained in their own submodule like /SMS/Messages
|
15
18
|
parent_module = self.class.to_s.split('::')[-2]
|
16
|
-
full_module_path = parent_module ==
|
19
|
+
full_module_path = parent_module == 'REST' ? (Twilio::REST) : (Twilio::REST.const_get parent_module)
|
17
20
|
|
18
21
|
@instance_class = full_module_path.const_get instance_name
|
19
22
|
@list_key, @instance_id_key = detwilify(resource_name), 'sid'
|
@@ -94,7 +97,10 @@ module Twilio
|
|
94
97
|
end
|
95
98
|
|
96
99
|
def resource(*resources)
|
97
|
-
custom_resource_names = {
|
100
|
+
custom_resource_names = {
|
101
|
+
:sms => 'SMS',
|
102
|
+
:sip => 'SIP',
|
103
|
+
}
|
98
104
|
resources.each do |r|
|
99
105
|
resource = twilify r
|
100
106
|
relative_path = custom_resource_names.fetch(r, resource)
|
@@ -2,8 +2,8 @@ module Twilio
|
|
2
2
|
module REST
|
3
3
|
class Records < ListResource
|
4
4
|
|
5
|
-
SUBRESOURCES = [:daily, :monthly, :yearly, :all_time, :today,
|
6
|
-
|
5
|
+
SUBRESOURCES = [:daily, :monthly, :yearly, :all_time, :today,
|
6
|
+
:yesterday, :this_month, :last_month]
|
7
7
|
|
8
8
|
def initialize(path, client)
|
9
9
|
super
|
@@ -4,9 +4,12 @@ module Twilio
|
|
4
4
|
|
5
5
|
include Twilio::Util
|
6
6
|
|
7
|
-
def initialize(account_sid, auth_token)
|
8
|
-
@account_sid = account_sid
|
9
|
-
@auth_token = auth_token
|
7
|
+
def initialize(account_sid = nil, auth_token = nil)
|
8
|
+
@account_sid = account_sid || Twilio.account_sid
|
9
|
+
@auth_token = auth_token || Twilio.auth_token
|
10
|
+
if @account_sid.nil? || @auth_token.nil?
|
11
|
+
raise ArgumentError, 'Account SID and auth token are required'
|
12
|
+
end
|
10
13
|
@capabilities = []
|
11
14
|
end
|
12
15
|
|
@@ -2,8 +2,9 @@ module Twilio
|
|
2
2
|
module Util
|
3
3
|
class RequestValidator
|
4
4
|
|
5
|
-
def initialize(auth_token)
|
6
|
-
@auth_token = auth_token
|
5
|
+
def initialize(auth_token = nil)
|
6
|
+
@auth_token = auth_token || Twilio.auth_token
|
7
|
+
raise ArgumentError, 'Auth token is required' if @auth_token.nil?
|
7
8
|
end
|
8
9
|
|
9
10
|
def validate(url, params, signature)
|
data/lib/twilio-ruby/version.rb
CHANGED