restcomm-ruby 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/AUTHORS.md +38 -0
  2. data/CHANGES.md +171 -0
  3. data/Gemfile +11 -0
  4. data/LICENSE +662 -0
  5. data/LICENSE.md +19 -0
  6. data/Makefile +12 -0
  7. data/README.md +155 -0
  8. data/Rakefile +10 -0
  9. data/conf/cacert.pem +3376 -0
  10. data/docs/Makefile +130 -0
  11. data/docs/_themes/LICENSE +45 -0
  12. data/docs/_themes/README.rst +25 -0
  13. data/docs/_themes/flask_theme_support.py +86 -0
  14. data/docs/_themes/kr/layout.html +32 -0
  15. data/docs/_themes/kr/relations.html +19 -0
  16. data/docs/_themes/kr/static/flasky.css_t +469 -0
  17. data/docs/_themes/kr/static/small_flask.css +70 -0
  18. data/docs/_themes/kr/theme.conf +7 -0
  19. data/docs/_themes/kr_small/layout.html +22 -0
  20. data/docs/_themes/kr_small/static/flasky.css_t +287 -0
  21. data/docs/_themes/kr_small/theme.conf +10 -0
  22. data/docs/changelog.rst +1 -0
  23. data/docs/conf.py +266 -0
  24. data/docs/faq.rst +42 -0
  25. data/docs/getting-started.rst +100 -0
  26. data/docs/index.rst +109 -0
  27. data/docs/make.bat +170 -0
  28. data/docs/src/pip-delete-this-directory.txt +5 -0
  29. data/docs/usage/accounts.rst +96 -0
  30. data/docs/usage/addresses.rst +102 -0
  31. data/docs/usage/applications.rst +111 -0
  32. data/docs/usage/basics.rst +120 -0
  33. data/docs/usage/caller-ids.rst +47 -0
  34. data/docs/usage/conferences.rst +112 -0
  35. data/docs/usage/errors.rst +31 -0
  36. data/docs/usage/messages.rst +142 -0
  37. data/docs/usage/notifications.rst +72 -0
  38. data/docs/usage/phone-calls.rst +193 -0
  39. data/docs/usage/phone-numbers.rst +192 -0
  40. data/docs/usage/queues.rst +117 -0
  41. data/docs/usage/recordings.rst +102 -0
  42. data/docs/usage/sip.rst +108 -0
  43. data/docs/usage/token-generation.rst +96 -0
  44. data/docs/usage/transcriptions.rst +34 -0
  45. data/docs/usage/twiml.rst +69 -0
  46. data/docs/usage/validation.rst +107 -0
  47. data/examples/examples.rb +200 -0
  48. data/examples/print-call-log.rb +25 -0
  49. data/lib/rack/restcomm_webhook_authentication.rb +47 -0
  50. data/lib/restcomm-ruby.rb +103 -0
  51. data/lib/restcomm-ruby/rest/accounts.rb +17 -0
  52. data/lib/restcomm-ruby/rest/addresses.rb +12 -0
  53. data/lib/restcomm-ruby/rest/addresses/dependent_phone_numbers.rb +6 -0
  54. data/lib/restcomm-ruby/rest/applications.rb +6 -0
  55. data/lib/restcomm-ruby/rest/authorized_connect_apps.rb +6 -0
  56. data/lib/restcomm-ruby/rest/available_phone_numbers.rb +13 -0
  57. data/lib/restcomm-ruby/rest/available_phone_numbers/country.rb +10 -0
  58. data/lib/restcomm-ruby/rest/available_phone_numbers/local.rb +11 -0
  59. data/lib/restcomm-ruby/rest/available_phone_numbers/mobile.rb +11 -0
  60. data/lib/restcomm-ruby/rest/available_phone_numbers/toll_free.rb +11 -0
  61. data/lib/restcomm-ruby/rest/call_feedback.rb +28 -0
  62. data/lib/restcomm-ruby/rest/call_feedback_summary.rb +13 -0
  63. data/lib/restcomm-ruby/rest/calls.rb +37 -0
  64. data/lib/restcomm-ruby/rest/client.rb +555 -0
  65. data/lib/restcomm-ruby/rest/conferences.rb +12 -0
  66. data/lib/restcomm-ruby/rest/conferences/participants.rb +23 -0
  67. data/lib/restcomm-ruby/rest/connect_apps.rb +6 -0
  68. data/lib/restcomm-ruby/rest/errors.rb +14 -0
  69. data/lib/restcomm-ruby/rest/incoming_phone_numbers.rb +17 -0
  70. data/lib/restcomm-ruby/rest/incoming_phone_numbers/local.rb +13 -0
  71. data/lib/restcomm-ruby/rest/incoming_phone_numbers/mobile.rb +13 -0
  72. data/lib/restcomm-ruby/rest/incoming_phone_numbers/toll_free.rb +13 -0
  73. data/lib/restcomm-ruby/rest/instance_resource.rb +88 -0
  74. data/lib/restcomm-ruby/rest/list_resource.rb +132 -0
  75. data/lib/restcomm-ruby/rest/media.rb +14 -0
  76. data/lib/restcomm-ruby/rest/messages.rb +23 -0
  77. data/lib/restcomm-ruby/rest/next_gen_list_resource.rb +29 -0
  78. data/lib/restcomm-ruby/rest/notifications.rb +6 -0
  79. data/lib/restcomm-ruby/rest/outgoing_caller_ids.rb +25 -0
  80. data/lib/restcomm-ruby/rest/queues.rb +12 -0
  81. data/lib/restcomm-ruby/rest/queues/members.rb +29 -0
  82. data/lib/restcomm-ruby/rest/recordings.rb +35 -0
  83. data/lib/restcomm-ruby/rest/sandbox.rb +5 -0
  84. data/lib/restcomm-ruby/rest/sip.rb +10 -0
  85. data/lib/restcomm-ruby/rest/sip/credential_lists.rb +11 -0
  86. data/lib/restcomm-ruby/rest/sip/credential_lists/credentials.rb +6 -0
  87. data/lib/restcomm-ruby/rest/sip/domains.rb +12 -0
  88. data/lib/restcomm-ruby/rest/sip/domains/credential_list_mappings.rb +6 -0
  89. data/lib/restcomm-ruby/rest/sip/domains/ip_access_control_list_mappings.rb +6 -0
  90. data/lib/restcomm-ruby/rest/sip/ip_access_control_lists.rb +11 -0
  91. data/lib/restcomm-ruby/rest/sip/ip_access_control_lists/ip_addresses.rb +6 -0
  92. data/lib/restcomm-ruby/rest/sms.rb +11 -0
  93. data/lib/restcomm-ruby/rest/sms/messages.rb +39 -0
  94. data/lib/restcomm-ruby/rest/sms/short_codes.rb +8 -0
  95. data/lib/restcomm-ruby/rest/task_router/activities.rb +8 -0
  96. data/lib/restcomm-ruby/rest/task_router/events.rb +8 -0
  97. data/lib/restcomm-ruby/rest/task_router/reservations.rb +8 -0
  98. data/lib/restcomm-ruby/rest/task_router/task_queues.rb +8 -0
  99. data/lib/restcomm-ruby/rest/task_router/task_queues_statistics.rb +15 -0
  100. data/lib/restcomm-ruby/rest/task_router/tasks.rb +15 -0
  101. data/lib/restcomm-ruby/rest/task_router/workers.rb +8 -0
  102. data/lib/restcomm-ruby/rest/task_router/workers_statistics.rb +8 -0
  103. data/lib/restcomm-ruby/rest/task_router/workflow_statistics.rb +7 -0
  104. data/lib/restcomm-ruby/rest/task_router/workflows.rb +8 -0
  105. data/lib/restcomm-ruby/rest/task_router/workspace_statistics.rb +7 -0
  106. data/lib/restcomm-ruby/rest/task_router/workspaces.rb +15 -0
  107. data/lib/restcomm-ruby/rest/tokens.rb +7 -0
  108. data/lib/restcomm-ruby/rest/transcriptions.rb +6 -0
  109. data/lib/restcomm-ruby/rest/usage.rb +10 -0
  110. data/lib/restcomm-ruby/rest/usage/records.rb +21 -0
  111. data/lib/restcomm-ruby/rest/usage/triggers.rb +12 -0
  112. data/lib/restcomm-ruby/rest/utils.rb +49 -0
  113. data/lib/restcomm-ruby/task_router.rb +0 -0
  114. data/lib/restcomm-ruby/task_router/capability.rb +87 -0
  115. data/lib/restcomm-ruby/twiml/response.rb +16 -0
  116. data/lib/restcomm-ruby/util.rb +15 -0
  117. data/lib/restcomm-ruby/util/capability.rb +64 -0
  118. data/lib/restcomm-ruby/util/configuration.rb +7 -0
  119. data/lib/restcomm-ruby/util/request_validator.rb +37 -0
  120. data/lib/restcomm-ruby/version.rb +3 -0
  121. data/restcomm-ruby.gemspec +34 -0
  122. data/spec/rack/twilio_webhook_authentication_spec.rb +110 -0
  123. data/spec/rest/account_spec.rb +89 -0
  124. data/spec/rest/address_spec.rb +11 -0
  125. data/spec/rest/call_feedback_spec.rb +12 -0
  126. data/spec/rest/call_feedback_summary_spec.rb +9 -0
  127. data/spec/rest/call_spec.rb +22 -0
  128. data/spec/rest/client_spec.rb +258 -0
  129. data/spec/rest/conference_spec.rb +11 -0
  130. data/spec/rest/instance_resource_spec.rb +15 -0
  131. data/spec/rest/message_spec.rb +12 -0
  132. data/spec/rest/numbers_spec.rb +58 -0
  133. data/spec/rest/queue_spec.rb +11 -0
  134. data/spec/rest/recording_spec.rb +11 -0
  135. data/spec/rest/sms/message_spec.rb +37 -0
  136. data/spec/rest/sms/messages_spec.rb +36 -0
  137. data/spec/rest/task_router/reservation_spec.rb +9 -0
  138. data/spec/rest/task_router/task_queue_spec.rb +9 -0
  139. data/spec/rest/token_spec.rb +7 -0
  140. data/spec/rest/utils_spec.rb +45 -0
  141. data/spec/spec_helper.rb +15 -0
  142. data/spec/support/fakeweb.rb +2 -0
  143. data/spec/task_router_spec.rb +114 -0
  144. data/spec/twilio_spec.rb +15 -0
  145. data/spec/util/capability_spec.rb +186 -0
  146. data/spec/util/configuration_spec.rb +13 -0
  147. data/spec/util/request_validator_spec.rb +93 -0
  148. data/spec/util/url_encode_spec.rb +12 -0
  149. 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