restcomm-ruby 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS.md +38 -0
- data/CHANGES.md +171 -0
- data/Gemfile +11 -0
- data/LICENSE +662 -0
- data/LICENSE.md +19 -0
- data/Makefile +12 -0
- data/README.md +155 -0
- data/Rakefile +10 -0
- data/conf/cacert.pem +3376 -0
- data/docs/Makefile +130 -0
- data/docs/_themes/LICENSE +45 -0
- data/docs/_themes/README.rst +25 -0
- data/docs/_themes/flask_theme_support.py +86 -0
- data/docs/_themes/kr/layout.html +32 -0
- data/docs/_themes/kr/relations.html +19 -0
- data/docs/_themes/kr/static/flasky.css_t +469 -0
- data/docs/_themes/kr/static/small_flask.css +70 -0
- data/docs/_themes/kr/theme.conf +7 -0
- data/docs/_themes/kr_small/layout.html +22 -0
- data/docs/_themes/kr_small/static/flasky.css_t +287 -0
- data/docs/_themes/kr_small/theme.conf +10 -0
- data/docs/changelog.rst +1 -0
- data/docs/conf.py +266 -0
- data/docs/faq.rst +42 -0
- data/docs/getting-started.rst +100 -0
- data/docs/index.rst +109 -0
- data/docs/make.bat +170 -0
- data/docs/src/pip-delete-this-directory.txt +5 -0
- data/docs/usage/accounts.rst +96 -0
- data/docs/usage/addresses.rst +102 -0
- data/docs/usage/applications.rst +111 -0
- data/docs/usage/basics.rst +120 -0
- data/docs/usage/caller-ids.rst +47 -0
- data/docs/usage/conferences.rst +112 -0
- data/docs/usage/errors.rst +31 -0
- data/docs/usage/messages.rst +142 -0
- data/docs/usage/notifications.rst +72 -0
- data/docs/usage/phone-calls.rst +193 -0
- data/docs/usage/phone-numbers.rst +192 -0
- data/docs/usage/queues.rst +117 -0
- data/docs/usage/recordings.rst +102 -0
- data/docs/usage/sip.rst +108 -0
- data/docs/usage/token-generation.rst +96 -0
- data/docs/usage/transcriptions.rst +34 -0
- data/docs/usage/twiml.rst +69 -0
- data/docs/usage/validation.rst +107 -0
- data/examples/examples.rb +200 -0
- data/examples/print-call-log.rb +25 -0
- data/lib/rack/restcomm_webhook_authentication.rb +47 -0
- data/lib/restcomm-ruby.rb +103 -0
- data/lib/restcomm-ruby/rest/accounts.rb +17 -0
- data/lib/restcomm-ruby/rest/addresses.rb +12 -0
- data/lib/restcomm-ruby/rest/addresses/dependent_phone_numbers.rb +6 -0
- data/lib/restcomm-ruby/rest/applications.rb +6 -0
- data/lib/restcomm-ruby/rest/authorized_connect_apps.rb +6 -0
- data/lib/restcomm-ruby/rest/available_phone_numbers.rb +13 -0
- data/lib/restcomm-ruby/rest/available_phone_numbers/country.rb +10 -0
- data/lib/restcomm-ruby/rest/available_phone_numbers/local.rb +11 -0
- data/lib/restcomm-ruby/rest/available_phone_numbers/mobile.rb +11 -0
- data/lib/restcomm-ruby/rest/available_phone_numbers/toll_free.rb +11 -0
- data/lib/restcomm-ruby/rest/call_feedback.rb +28 -0
- data/lib/restcomm-ruby/rest/call_feedback_summary.rb +13 -0
- data/lib/restcomm-ruby/rest/calls.rb +37 -0
- data/lib/restcomm-ruby/rest/client.rb +555 -0
- data/lib/restcomm-ruby/rest/conferences.rb +12 -0
- data/lib/restcomm-ruby/rest/conferences/participants.rb +23 -0
- data/lib/restcomm-ruby/rest/connect_apps.rb +6 -0
- data/lib/restcomm-ruby/rest/errors.rb +14 -0
- data/lib/restcomm-ruby/rest/incoming_phone_numbers.rb +17 -0
- data/lib/restcomm-ruby/rest/incoming_phone_numbers/local.rb +13 -0
- data/lib/restcomm-ruby/rest/incoming_phone_numbers/mobile.rb +13 -0
- data/lib/restcomm-ruby/rest/incoming_phone_numbers/toll_free.rb +13 -0
- data/lib/restcomm-ruby/rest/instance_resource.rb +88 -0
- data/lib/restcomm-ruby/rest/list_resource.rb +132 -0
- data/lib/restcomm-ruby/rest/media.rb +14 -0
- data/lib/restcomm-ruby/rest/messages.rb +23 -0
- data/lib/restcomm-ruby/rest/next_gen_list_resource.rb +29 -0
- data/lib/restcomm-ruby/rest/notifications.rb +6 -0
- data/lib/restcomm-ruby/rest/outgoing_caller_ids.rb +25 -0
- data/lib/restcomm-ruby/rest/queues.rb +12 -0
- data/lib/restcomm-ruby/rest/queues/members.rb +29 -0
- data/lib/restcomm-ruby/rest/recordings.rb +35 -0
- data/lib/restcomm-ruby/rest/sandbox.rb +5 -0
- data/lib/restcomm-ruby/rest/sip.rb +10 -0
- data/lib/restcomm-ruby/rest/sip/credential_lists.rb +11 -0
- data/lib/restcomm-ruby/rest/sip/credential_lists/credentials.rb +6 -0
- data/lib/restcomm-ruby/rest/sip/domains.rb +12 -0
- data/lib/restcomm-ruby/rest/sip/domains/credential_list_mappings.rb +6 -0
- data/lib/restcomm-ruby/rest/sip/domains/ip_access_control_list_mappings.rb +6 -0
- data/lib/restcomm-ruby/rest/sip/ip_access_control_lists.rb +11 -0
- data/lib/restcomm-ruby/rest/sip/ip_access_control_lists/ip_addresses.rb +6 -0
- data/lib/restcomm-ruby/rest/sms.rb +11 -0
- data/lib/restcomm-ruby/rest/sms/messages.rb +39 -0
- data/lib/restcomm-ruby/rest/sms/short_codes.rb +8 -0
- data/lib/restcomm-ruby/rest/task_router/activities.rb +8 -0
- data/lib/restcomm-ruby/rest/task_router/events.rb +8 -0
- data/lib/restcomm-ruby/rest/task_router/reservations.rb +8 -0
- data/lib/restcomm-ruby/rest/task_router/task_queues.rb +8 -0
- data/lib/restcomm-ruby/rest/task_router/task_queues_statistics.rb +15 -0
- data/lib/restcomm-ruby/rest/task_router/tasks.rb +15 -0
- data/lib/restcomm-ruby/rest/task_router/workers.rb +8 -0
- data/lib/restcomm-ruby/rest/task_router/workers_statistics.rb +8 -0
- data/lib/restcomm-ruby/rest/task_router/workflow_statistics.rb +7 -0
- data/lib/restcomm-ruby/rest/task_router/workflows.rb +8 -0
- data/lib/restcomm-ruby/rest/task_router/workspace_statistics.rb +7 -0
- data/lib/restcomm-ruby/rest/task_router/workspaces.rb +15 -0
- data/lib/restcomm-ruby/rest/tokens.rb +7 -0
- data/lib/restcomm-ruby/rest/transcriptions.rb +6 -0
- data/lib/restcomm-ruby/rest/usage.rb +10 -0
- data/lib/restcomm-ruby/rest/usage/records.rb +21 -0
- data/lib/restcomm-ruby/rest/usage/triggers.rb +12 -0
- data/lib/restcomm-ruby/rest/utils.rb +49 -0
- data/lib/restcomm-ruby/task_router.rb +0 -0
- data/lib/restcomm-ruby/task_router/capability.rb +87 -0
- data/lib/restcomm-ruby/twiml/response.rb +16 -0
- data/lib/restcomm-ruby/util.rb +15 -0
- data/lib/restcomm-ruby/util/capability.rb +64 -0
- data/lib/restcomm-ruby/util/configuration.rb +7 -0
- data/lib/restcomm-ruby/util/request_validator.rb +37 -0
- data/lib/restcomm-ruby/version.rb +3 -0
- data/restcomm-ruby.gemspec +34 -0
- data/spec/rack/twilio_webhook_authentication_spec.rb +110 -0
- data/spec/rest/account_spec.rb +89 -0
- data/spec/rest/address_spec.rb +11 -0
- 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 +22 -0
- data/spec/rest/client_spec.rb +258 -0
- data/spec/rest/conference_spec.rb +11 -0
- data/spec/rest/instance_resource_spec.rb +15 -0
- data/spec/rest/message_spec.rb +12 -0
- data/spec/rest/numbers_spec.rb +58 -0
- data/spec/rest/queue_spec.rb +11 -0
- data/spec/rest/recording_spec.rb +11 -0
- data/spec/rest/sms/message_spec.rb +37 -0
- data/spec/rest/sms/messages_spec.rb +36 -0
- data/spec/rest/task_router/reservation_spec.rb +9 -0
- data/spec/rest/task_router/task_queue_spec.rb +9 -0
- data/spec/rest/token_spec.rb +7 -0
- data/spec/rest/utils_spec.rb +45 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/fakeweb.rb +2 -0
- data/spec/task_router_spec.rb +114 -0
- data/spec/twilio_spec.rb +15 -0
- data/spec/util/capability_spec.rb +186 -0
- data/spec/util/configuration_spec.rb +13 -0
- data/spec/util/request_validator_spec.rb +93 -0
- data/spec/util/url_encode_spec.rb +12 -0
- metadata +298 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
.. _usage-twiml:
|
2
|
+
|
3
|
+
.. module:: restcomm.twiml
|
4
|
+
|
5
|
+
==============
|
6
|
+
RCML Creation
|
7
|
+
==============
|
8
|
+
|
9
|
+
RCML creation begins with the :class:`Response` verb.
|
10
|
+
Each successive verb is created by calling various methods on the response,
|
11
|
+
such as :meth:`say` or :meth:`play`.
|
12
|
+
These methods return the verbs they create to ease creation of nested RCML.
|
13
|
+
To finish, call the :meth:`toxml` method on the :class:`Response`,
|
14
|
+
which returns raw RCML.
|
15
|
+
|
16
|
+
.. code-block:: ruby
|
17
|
+
|
18
|
+
require 'restcomm-ruby'
|
19
|
+
|
20
|
+
Restcomm::RCML::Response.new do |r|
|
21
|
+
r.Say "Hello"
|
22
|
+
end.text
|
23
|
+
|
24
|
+
.. code-block:: xml
|
25
|
+
|
26
|
+
<?xml version="1.0" encoding="utf-8"?>
|
27
|
+
<Response><Say>Hello</Say><Response>
|
28
|
+
|
29
|
+
The verb methods (outlined in the :doc:`complete reference </api/twiml>`)
|
30
|
+
take the body (only text) of the verb as the first argument.
|
31
|
+
All attributes are keyword arguments.
|
32
|
+
|
33
|
+
.. code-block:: ruby
|
34
|
+
|
35
|
+
require 'restcomm-ruby'
|
36
|
+
|
37
|
+
Restcomm::RCML::Response.new do |r|
|
38
|
+
r.Play "https://api.restcomm.com/cowbell.mp3", loop: 5
|
39
|
+
end.text
|
40
|
+
|
41
|
+
.. code-block:: xml
|
42
|
+
|
43
|
+
<?xml version="1.0" encoding="utf-8"?>
|
44
|
+
<Response>
|
45
|
+
<Play loop="3">https://SOME_WEBSITE/cowbell.mp3</Play>
|
46
|
+
<Response>
|
47
|
+
|
48
|
+
Any example of nesting nouns in verbs
|
49
|
+
|
50
|
+
.. code-block:: ruby
|
51
|
+
|
52
|
+
require 'restcomm-ruby'
|
53
|
+
|
54
|
+
Restcomm::RCML::Response.new do |r|
|
55
|
+
r.Say "hello"
|
56
|
+
r.Gather finishOnKey: => 4 do |g|
|
57
|
+
g.Say "world"
|
58
|
+
end
|
59
|
+
end.text
|
60
|
+
|
61
|
+
which returns the following
|
62
|
+
|
63
|
+
.. code-block:: xml
|
64
|
+
|
65
|
+
<?xml version="1.0" encoding="utf-8"?>
|
66
|
+
<Response>
|
67
|
+
<Say>Hello</Say>
|
68
|
+
<Gather finishOnKey="4"><Say>World</Say></Gather>
|
69
|
+
</Response>
|
@@ -0,0 +1,107 @@
|
|
1
|
+
.. module:: restcomm.util
|
2
|
+
|
3
|
+
===========================
|
4
|
+
Validate Incoming Requests
|
5
|
+
===========================
|
6
|
+
|
7
|
+
Restcomm requires that your RCML-serving web server be open to the public. This
|
8
|
+
is necessary so that Restcomm can retrieve RCML from urls and POST data back to
|
9
|
+
your server.
|
10
|
+
|
11
|
+
However, there may be people out there trying to spoof the Restcomm service.
|
12
|
+
Luckily, there's an easy way to validate that incoming requests are from Restcomm
|
13
|
+
and Restcomm alone.
|
14
|
+
|
15
|
+
An in-depth guide to our security features can be `found in our online
|
16
|
+
documentation <http://docs.telestax.com/restcomm-pages/>`_.
|
17
|
+
|
18
|
+
Before you can validate requests, you'll need four pieces of information:
|
19
|
+
|
20
|
+
* your Restcomm Auth Token (found in your `Dashboard
|
21
|
+
<https://www.restcomm.com/user/account>`_)
|
22
|
+
* the POST data for the request
|
23
|
+
* the requested URL
|
24
|
+
* the X-Restcomm-Signature header value
|
25
|
+
|
26
|
+
Obtaining the last three pieces of information depends on the framework you are
|
27
|
+
using to process requests. The below example assumes that you have the POST
|
28
|
+
data as a dictionary and the url and X-Restcomm-Signature as strings.
|
29
|
+
|
30
|
+
The below example will print out a confirmation message if the request is
|
31
|
+
actually from Restcomm.
|
32
|
+
|
33
|
+
.. code-block:: ruby
|
34
|
+
|
35
|
+
require 'restcomm-ruby'
|
36
|
+
|
37
|
+
auth_token = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'
|
38
|
+
|
39
|
+
@validator = Restcomm::Util::RequestValidator.new auth_token
|
40
|
+
|
41
|
+
# the callback URL you provided to Restcomm
|
42
|
+
url = "http://www.example.com/my/callback/url.xml"
|
43
|
+
|
44
|
+
# the POST variables attached to the request (eg "From", "To")
|
45
|
+
post_vars = {}
|
46
|
+
|
47
|
+
# X-Restcomm-Signature header value
|
48
|
+
signature = "HpS7PBa1Agvt4OtO+wZp75IuQa0=" # will look something like that
|
49
|
+
|
50
|
+
if @validator.validate(url, post_vars, signature)
|
51
|
+
puts "Confirmed to have come from Restcomm."
|
52
|
+
else
|
53
|
+
puts "NOT VALID. It might have been spoofed!"
|
54
|
+
end
|
55
|
+
|
56
|
+
Trailing Slashes
|
57
|
+
==================
|
58
|
+
|
59
|
+
If your URL uses an "index" page, such as index.php or index.html to handle
|
60
|
+
the request, such as: https://mycompany.com/restcomm where the real page
|
61
|
+
is served from https://mycompany.com/restcomm/index.php, then Apache or
|
62
|
+
PHP may rewrite that URL a little bit so it's got a trailing slash, such as
|
63
|
+
https://mycompany.com/restcomm/ for example.
|
64
|
+
|
65
|
+
Using the code above, or similar code in another language, you could
|
66
|
+
end up with an incorrect hash because Restcomm built the hash using
|
67
|
+
https://mycompany.com/restcomm and you may have built the hash using
|
68
|
+
https://mycompany.com/restcomm/. More information can be found in our
|
69
|
+
documentation on validating requests.
|
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 Restcomm 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 'restcomm-ruby'
|
86
|
+
|
87
|
+
auth_token = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'
|
88
|
+
|
89
|
+
use Rack::RestcommWebhookAuthentication, auth_token, /\/messages/
|
90
|
+
|
91
|
+
post '/messages' do
|
92
|
+
# response with RCML
|
93
|
+
end
|
94
|
+
|
95
|
+
Now, any POST request to /messages in your application that doesn't validate as
|
96
|
+
a Restcomm request, will automatically respond with a 403 status code and your
|
97
|
+
action will not be hit.
|
98
|
+
|
99
|
+
If you use subaccounts and need to validate with different auth tokens, you can pass a block to the middleware instead of an auth token. The block will be passed the Account Sid making the call.
|
100
|
+
|
101
|
+
.. code-block:: ruby
|
102
|
+
|
103
|
+
use Rack::RestcommWebhookAuthentication, nil, /\/messages/ do |account_sid|
|
104
|
+
# lookup auth_token from account_sid
|
105
|
+
end
|
106
|
+
|
107
|
+
Ensure you pass `nil` for the auth_token when passing a block, otherwise the block will not be called.
|
@@ -0,0 +1,200 @@
|
|
1
|
+
#Welcomme to Restcomm
|
2
|
+
#The examples below will help you get started using Restcomm-ruby wraper
|
3
|
+
# examples version 1.2.0
|
4
|
+
# You must make sure the @account_sid, @auth_token and @host variables are correctly filled
|
5
|
+
#
|
6
|
+
#The @host is the IP address on which Restcomm is running (This could be a local install or a remote)
|
7
|
+
#
|
8
|
+
#
|
9
|
+
#
|
10
|
+
####### Account Settings #########
|
11
|
+
|
12
|
+
require 'restcomm-ruby'
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
@account_sid = 'ACae6e420f425248d6a26948c17a9e2acf'
|
17
|
+
@auth_token = 'YourPassWord' #
|
18
|
+
@host = '192.168.1.3' #IP address of your Restcomm instance
|
19
|
+
# set up a client
|
20
|
+
@client = Restcomm::REST::Client.new(@account_sid, @auth_token, @host)
|
21
|
+
|
22
|
+
################ ACCOUNTS ################
|
23
|
+
|
24
|
+
# shortcut to grab your account object (account_sid is inferred from the client's auth credentials)
|
25
|
+
@account = @client.account
|
26
|
+
|
27
|
+
#list of all accounts and (sub)accounts
|
28
|
+
@client.accounts.list.each do |x|
|
29
|
+
puts "Account name: " + x.friendly_name + " Account Sid: " + x.sid
|
30
|
+
end
|
31
|
+
|
32
|
+
# grab an account instance resource of a given account and display the friendly_name
|
33
|
+
puts @client.accounts.get(@account_sid).friendly_name
|
34
|
+
|
35
|
+
# grab an account instance resource of a given account and display the sid
|
36
|
+
puts @client.accounts.get(@account_sid).sid
|
37
|
+
|
38
|
+
# update an account's friendly name
|
39
|
+
@client.accounts.get(@account_sid).update(friendly_name: 'A Super Cool Name')
|
40
|
+
|
41
|
+
|
42
|
+
################ CALLS ################
|
43
|
+
|
44
|
+
|
45
|
+
# print a list of calls (without parameters)
|
46
|
+
@account.calls.list().each do |x|
|
47
|
+
puts "Call Sid " + x.sid + " Call Status: " + x.status
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
# print a list of calls (with some optional parameters)
|
52
|
+
|
53
|
+
@account.calls.list(page: 0, page_size: 1000,).each do |x|
|
54
|
+
puts x.sid
|
55
|
+
end
|
56
|
+
|
57
|
+
# get a particular call and list its status
|
58
|
+
puts @account.calls.get('CAb358e7b349924ece8a968f7089222039').status
|
59
|
+
|
60
|
+
# get a particular call and list its start time
|
61
|
+
puts @account.calls.get('CAb358e7b349924ece8a968f7089222039').start_time
|
62
|
+
|
63
|
+
# get a particular call and list its recording URI
|
64
|
+
puts @account.calls.get('CAb358e7b349924ece8a968f7089222039').subresource_uris["recordings"]
|
65
|
+
|
66
|
+
#################### RECORDINGS ##################################
|
67
|
+
|
68
|
+
#get a list of recordings linked to the current account and output the call SID and date created
|
69
|
+
@account.recordings.list.each do |x|
|
70
|
+
puts "Recording SID: " + x.call_sid + " **** " + "Date Created: " + x.date_created
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
#get a list of recordings URLs with ext .wav
|
75
|
+
#use ext .mp3 to get the corresponding mp3 list
|
76
|
+
@account.recordings.list.each do |r|
|
77
|
+
puts r.wav
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
#################### MAKING CALLS ##################################
|
83
|
+
|
84
|
+
# make a new outgoing call. returns a call object just like calls.get
|
85
|
+
@call = @account.calls.create(
|
86
|
+
from: 'sip:+32145687',
|
87
|
+
to: 'sip:+1111@192.168.1.3',
|
88
|
+
url: 'http://192.168.1.3:8080/restcomm-rvd/services/apps/test/controller'
|
89
|
+
)
|
90
|
+
|
91
|
+
|
92
|
+
# cancel the call if not already in progress
|
93
|
+
@account.calls.get(@call.sid).update(status: 'canceled')
|
94
|
+
# or equivalently
|
95
|
+
@call.update(status: 'canceled')
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
####### Terminate a call that is currently in-progress ########
|
100
|
+
|
101
|
+
@account.calls.get(@call.sid).update(status: 'completed')
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
# redirect and then terminate a call
|
106
|
+
|
107
|
+
@call.update(url: 'http://192.168.1.3:8080/restcomm/demos/hello-play.xml')
|
108
|
+
@call.update(status: 'completed')
|
109
|
+
# or, use the aliases...
|
110
|
+
@call.redirect_to('http://192.168.1.3:8080/restcomm/demos/hello-play.xml')
|
111
|
+
@call.hangup
|
112
|
+
|
113
|
+
################ SMS MESSAGES ################
|
114
|
+
|
115
|
+
# print a list of messages
|
116
|
+
@account.messages.list(date_sent: '2010-09-01').each do |message|
|
117
|
+
puts message.body
|
118
|
+
end
|
119
|
+
|
120
|
+
# print a particular sms message
|
121
|
+
puts @account.messages.get('SMXXXXXXXX').body
|
122
|
+
|
123
|
+
# send an sms
|
124
|
+
@account.messages.create(
|
125
|
+
from: '+14159341234',
|
126
|
+
to: '+16105557069',
|
127
|
+
body: 'Hey there!'
|
128
|
+
)
|
129
|
+
|
130
|
+
# send an mms the from DID should be a number from your DID provider
|
131
|
+
@account.messages.create(
|
132
|
+
from: '+14159341234',
|
133
|
+
to: '+16105557069',
|
134
|
+
media_urls: 'http://example.com/media.png'
|
135
|
+
)
|
136
|
+
|
137
|
+
################ PHONE NUMBERS ################
|
138
|
+
|
139
|
+
# get a list of supported country codes
|
140
|
+
@account.available_phone_numbers.list
|
141
|
+
|
142
|
+
# print some available numbers
|
143
|
+
@numbers = @account.available_phone_numbers.get('US').local.list(
|
144
|
+
AreaCode: '305'
|
145
|
+
)
|
146
|
+
|
147
|
+
@numbers.each { |num| puts num.phone_number }
|
148
|
+
|
149
|
+
# buy the first one
|
150
|
+
@account.incoming_phone_numbers.create(phone_number: @numbers[0].phone_number)
|
151
|
+
|
152
|
+
# update an existing phone number's voice url
|
153
|
+
number = @account.incoming_phone_numbers.get('PNdba508c5616a7f5e141789f44f022cc3')
|
154
|
+
number.update(voice_url: 'http://example.com/voice')
|
155
|
+
|
156
|
+
# decommission an existing phone number
|
157
|
+
numbers = @account.incoming_phone_numbers.list(
|
158
|
+
friendly_name: 'A Fabulous Friendly Name'
|
159
|
+
)
|
160
|
+
numbers[0].delete
|
161
|
+
################ CONFERENCES ################
|
162
|
+
|
163
|
+
# get a particular conference's participants object and stash it
|
164
|
+
conference = @account.conferences.get('CFbbe46ff1274e283f7e3ac1df0072ab39')
|
165
|
+
@participants = conference.participants
|
166
|
+
|
167
|
+
# list participants
|
168
|
+
@participants.list.each do |p|
|
169
|
+
puts p.sid
|
170
|
+
end
|
171
|
+
|
172
|
+
# update a conference participant
|
173
|
+
@participants.get('CA386025c9bf5d6052a1d1ea42b4d16662').update(muted: 'true')
|
174
|
+
# or an easier way
|
175
|
+
@participants.get('CA386025c9bf5d6052a1d1ea42b4d16662').mute
|
176
|
+
|
177
|
+
# and, since we're lazy loading, this would only incur one http request
|
178
|
+
@account.conferences.get('CFbbe46ff1274e283f7e3ac1df0072ab39').participants
|
179
|
+
.get('CA386025c9bf5d6052a1d1ea42b4d16662').update(muted: 'true')
|
180
|
+
|
181
|
+
################ QUEUES ###################
|
182
|
+
|
183
|
+
# create a new queue
|
184
|
+
@queue = @account.queues.create(friendly_name: 'MyQueue', max_size: 50)
|
185
|
+
|
186
|
+
# get a list of queues for this account
|
187
|
+
@queues = @account.queues.list
|
188
|
+
|
189
|
+
# get a particular queue and its members
|
190
|
+
@queue = @account.queues.get("QQb6765b0458714964970a73dcaf55efd1")
|
191
|
+
@members = @queue.members
|
192
|
+
|
193
|
+
#list members
|
194
|
+
@members.list.each do |m|
|
195
|
+
puts m.wait_time
|
196
|
+
end
|
197
|
+
|
198
|
+
# dequeue a particular user and run twiml at a specific url
|
199
|
+
@member = @members.get('CA386025c9bf5d6052a1d1ea42b4d16662')
|
200
|
+
@member.dequeue('http://myapp.com/deque')
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'restcomm-ruby'
|
3
|
+
|
4
|
+
# print a list of all phone calls, what phone number each was to/from, and how
|
5
|
+
# much each one cost.
|
6
|
+
|
7
|
+
# put your Restcomm credentials here. you can find your AccountSid and AuthToken
|
8
|
+
# at the top of your account dashboard page located at:
|
9
|
+
#
|
10
|
+
account_sid = 'AC043dcf9844e04758bc3a36a84c29761'
|
11
|
+
auth_token = '62ea81de3a5b414154eb263595357c69'
|
12
|
+
host = 'IP_Address_Restcomm_Instance'
|
13
|
+
|
14
|
+
# set up a client
|
15
|
+
client = Restcomm::REST::Client.new(account_sid, auth_token, host)
|
16
|
+
|
17
|
+
calls = client.calls.list
|
18
|
+
|
19
|
+
begin
|
20
|
+
calls.each do |call|
|
21
|
+
price = call.price || '0.00' # since apparently prices can be nil...
|
22
|
+
puts call.sid + "\t" + call.from + "\t" + call.to + "\t" + price
|
23
|
+
end
|
24
|
+
calls = calls.next_page
|
25
|
+
end while not calls.empty?
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Rack
|
2
|
+
# Middleware that authenticates webhooks from Restcomm 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::RestcommWebhookAuthentication, 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 RestcommWebhookAuthentication
|
20
|
+
def initialize(app, auth_token, *paths, &auth_token_lookup)
|
21
|
+
@app = app
|
22
|
+
@auth_token = auth_token
|
23
|
+
define_singleton_method(:get_auth_token, auth_token_lookup) if block_given?
|
24
|
+
@path_regex = Regexp.union(paths)
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(env)
|
28
|
+
return @app.call(env) unless env["PATH_INFO"].match(@path_regex)
|
29
|
+
request = Rack::Request.new(env)
|
30
|
+
original_url = request.url
|
31
|
+
params = request.post? ? request.POST : {}
|
32
|
+
auth_token = @auth_token || get_auth_token(params['AccountSid'])
|
33
|
+
validator = Restcomm::Util::RequestValidator.new(auth_token)
|
34
|
+
signature = env['HTTP_X_TWILIO_SIGNATURE'] || ""
|
35
|
+
if validator.validate(original_url, params, signature)
|
36
|
+
@app.call(env)
|
37
|
+
else
|
38
|
+
[
|
39
|
+
403,
|
40
|
+
{'Content-Type' => 'text/plain'},
|
41
|
+
["Restcomm Request Validation Failed."]
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|