Skip to content

Commit 2070cec

Browse files
author
timmydoza
authored
Merge pull request #60 from twilio-labs/feature/start-stop-recording
Feature/start stop recording
2 parents cbaeafc + dfffe25 commit 2070cec

File tree

13 files changed

+466
-146
lines changed

13 files changed

+466
-146
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## 0.7.0
4+
5+
### Enhancements
6+
7+
- This version adds a new endpoint which allows users to update the recording rules for a given room. See the [README](README.md#recording-rules) for more details.
8+
- Upgraded @twilio/cli-core from 5.9.1 to 5.9.3
9+
- Upgraded moment from 2.28.0 to 2.29.0
10+
- Upgraded nanoid from 3.1.13 to 3.1.16
11+
- Upgraded @twilio-labs/serverless-api from 4.0.2 to 4.0.3
12+
313
## 0.6.0
414

515
### Enhancements

README.md

Lines changed: 110 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,19 @@ A mobile and web collaboration application built with Twilio Programmable Video.
5656
- [iOS App](https://github.com/twilio/twilio-video-app-ios)
5757
- [Android App](https://github.com/twilio/twilio-video-app-android)
5858

59-
#### Token Server API Documentation
59+
## Token Server API Documentation
6060

6161
The following section documents the application [token server](/src/video-token-server.js) used to provide [Programable Video access tokens](https://www.twilio.com/docs/video/tutorials/user-identity-access-tokens) to supported Twilio Video applications. The token server is deployed as a [Twilio Function](https://www.twilio.com/docs/runtime/functions).
6262

6363
| Method | URL |
6464
| ------ | ------------------ |
6565
| POST | [`/token`](#token) |
6666

67-
##### Authentication
67+
### Authentication
6868

69-
The application token server requires an [authentication mechanism](#twilio-rtcappsvideodeploy---authentication-auth) to be specified when deploying. The following section documents each support authentication mechanism.
69+
The application token server requires an [authentication mechanism](#twilio-rtcappsvideodeploy---authentication-auth) to be specified when deploying. The following section documents each supported authentication mechanism.
7070

71-
###### Passcode
71+
#### Passcode
7272

7373
Each request is verified using a passcode generated at deploy time. Passcodes remain valid for one week. After the passcode expires, users can redeploy an application and a new passcode will be generated. The snippet below provides an example request body used by a supported application.
7474

@@ -80,15 +80,15 @@ Each request is verified using a passcode generated at deploy time. Passcodes re
8080
}
8181
```
8282

83-
##### Token
83+
### Token
8484

8585
Returns a Programmable Video Access token.
8686

8787
```shell
8888
POST /token
8989
```
9090

91-
###### Parameters
91+
#### Parameters
9292

9393
| Name | Type | Description |
9494
| --------------- | --------- | -------------------------------------------------------------------------------------- |
@@ -97,7 +97,7 @@ POST /token
9797
| `room_name` | `string` | A room name that will be used to create a token scoped to connecting to only one room. |
9898
| `create_room` | `boolean` | (default: `true`) When false, a room will not be created when a token is requested. |
9999

100-
###### Success Responses
100+
#### Success Responses
101101

102102
<table>
103103
<tr>
@@ -119,7 +119,7 @@ POST /token
119119

120120
</table>
121121

122-
###### Error Responses
122+
#### Error Responses
123123

124124
<table>
125125
<tr>
@@ -189,6 +189,108 @@ POST /token
189189

190190
</table>
191191

192+
### Recording Rules
193+
194+
Changes the Recording Rules for a given room SID.
195+
196+
```shell
197+
POST /recordingrules
198+
```
199+
200+
#### Parameters
201+
202+
| Name | Type | Description |
203+
| ---------- | -------- | ------------------------------------------------------------------- |
204+
| `passcode` | `string` | **Required**. The application passcode. |
205+
| `room_sid` | `string` | **Required**. The SID of the room to change the recording rules of. |
206+
| `rules` | `array` | **Required**. An array of recording rules to apply to the room. |
207+
208+
#### Success Responses
209+
210+
<table>
211+
<tr>
212+
<td> <b>Status</b> </td> <td> <b>Response</b> </td>
213+
</tr>
214+
<tr>
215+
<td> 200 </td>
216+
<td>
217+
218+
```json
219+
{
220+
"roomSid": "RM00000000000000000000000000000000",
221+
"rules": [
222+
{
223+
"all": true,
224+
"type": "exclude"
225+
}
226+
],
227+
"dateCreated": "2020-11-18T02:58:20.000Z",
228+
"dateUpdated": "2020-11-18T03:21:18.000Z"
229+
}
230+
```
231+
232+
</td>
233+
</tr>
234+
235+
</table>
236+
237+
#### Error Responses
238+
239+
<table>
240+
<tr>
241+
<td> <b>Status</b> </td> <td> <b>Response</b> </td>
242+
</tr>
243+
244+
<tr>
245+
<td> 400 </td>
246+
<td>
247+
248+
```json
249+
{
250+
"error": {
251+
"message": "missing room_sid",
252+
"explanation": "The room_sid parameter is missing."
253+
}
254+
}
255+
```
256+
257+
</td>
258+
</tr>
259+
260+
<tr>
261+
<td> 400 </td>
262+
<td>
263+
264+
```json
265+
{
266+
"error": {
267+
"message": "missing rules",
268+
"explanation": "The rules parameter is missing."
269+
}
270+
}
271+
```
272+
273+
</td>
274+
</tr>
275+
276+
<tr>
277+
<td> 401 </td>
278+
<td>
279+
280+
```json
281+
{
282+
"error": {
283+
"message": "passcode incorrect",
284+
"explanation": "The passcode used to validate application users is incorrect."
285+
}
286+
}
287+
```
288+
289+
</td>
290+
</tr>
291+
292+
</table>
293+
192294
## Commands
193295

194296
<!-- commands -->

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@twilio-labs/plugin-rtc",
3-
"version": "0.6.1",
3+
"version": "0.7.0",
44
"description": "A Twilio-CLI plugin for real-time communication apps",
55
"main": "index.js",
66
"publishConfig": {

src/helpers.js

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,33 @@ async function getAssets(folder) {
4747

4848
const indexHTML = assets.find(asset => asset.name.includes('index.html'));
4949

50-
assets.push({
51-
...indexHTML,
52-
path: '/',
53-
name: '/',
54-
});
55-
assets.push({
56-
...indexHTML,
57-
path: '/login',
58-
name: '/login',
59-
});
50+
const allAssets = assets.concat([
51+
{
52+
...indexHTML,
53+
path: '/',
54+
name: '/',
55+
},
56+
{
57+
...indexHTML,
58+
path: '/login',
59+
name: '/login',
60+
},
61+
]);
62+
63+
return allAssets;
64+
}
65+
66+
function getMiddleware() {
67+
const authHandlerFn = fs.readFileSync(path.join(__dirname, './serverless/middleware/auth.js'));
6068

61-
return assets;
69+
return [
70+
{
71+
name: 'auth-handler',
72+
path: '/auth-handler.js',
73+
content: authHandlerFn,
74+
access: 'private',
75+
},
76+
];
6277
}
6378

6479
async function findApp() {
@@ -80,7 +95,7 @@ async function getAppInfo() {
8095
const assets = await appInstance.assets.list();
8196

8297
const functions = await appInstance.functions.list();
83-
const tokenServerFunction = functions.find(fn => fn.friendlyName === 'token');
98+
const tokenServerFunction = functions.find(fn => fn.friendlyName.includes('token'));
8499

85100
const passcodeVar = variables.find(v => v.key === 'API_PASSCODE');
86101
const expiryVar = variables.find(v => v.key === 'API_PASSCODE_EXPIRY');
@@ -97,7 +112,7 @@ async function getAppInfo() {
97112
expiry: moment(Number(expiry)).toString(),
98113
sid: app.sid,
99114
passcode: fullPasscode,
100-
hasAssets: Boolean(assets.length),
115+
hasWebAssets: Boolean(assets.find(asset => asset.friendlyName.includes('index.html'))),
101116
roomType,
102117
environmentSid: environment.sid,
103118
functionSid: tokenServerFunction.sid,
@@ -112,7 +127,7 @@ async function displayAppInfo() {
112127
return;
113128
}
114129

115-
if (appInfo.hasAssets) {
130+
if (appInfo.hasWebAssets) {
116131
console.log(`Web App URL: ${appInfo.url}`);
117132
}
118133

@@ -130,6 +145,12 @@ async function displayAppInfo() {
130145

131146
async function deploy() {
132147
const assets = this.flags['app-directory'] ? await getAssets(this.flags['app-directory']) : [];
148+
const { functions } = await getListOfFunctionsAndAssets(__dirname, {
149+
functionsFolderNames: ['serverless/functions'],
150+
assetsFolderNames: [],
151+
});
152+
153+
assets.push(...getMiddleware());
133154

134155
if (this.twilioClient.username === this.twilioClient.accountSid) {
135156
// When twilioClient.username equals twilioClient.accountSid, it means that the user
@@ -158,8 +179,6 @@ TWILIO_API_SECRET = the secret for the API Key`);
158179
const pin = getRandomInt(6);
159180
const expiryTime = Date.now() + EXPIRY_PERIOD;
160181

161-
const fn = fs.readFileSync(path.join(__dirname, './video-token-server.js'));
162-
163182
cli.action.start('deploying app');
164183

165184
const deployOptions = {
@@ -170,17 +189,14 @@ TWILIO_API_SECRET = the secret for the API Key`);
170189
API_PASSCODE_EXPIRY: expiryTime,
171190
ROOM_TYPE: this.flags['room-type'],
172191
},
173-
pkgJson: {},
174-
functionsEnv: 'dev',
175-
functions: [
176-
{
177-
name: 'token',
178-
path: '/token',
179-
content: fn,
180-
access: 'public',
192+
pkgJson: {
193+
dependencies: {
194+
twilio: '^3.51.0',
181195
},
182-
],
183-
assets: assets,
196+
},
197+
functionsEnv: 'dev',
198+
functions,
199+
assets,
184200
};
185201

186202
if (this.appInfo && this.appInfo.sid) {
@@ -205,6 +221,7 @@ module.exports = {
205221
displayAppInfo,
206222
findApp,
207223
getAssets,
224+
getMiddleware,
208225
getAppInfo,
209226
getPasscode,
210227
getRandomInt,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/* global Twilio Runtime */
2+
'use strict';
3+
4+
// We need to use a newer twilio client than the one provided by context.getTwilioClient(),
5+
// so we require it here. The version is specified in helpers.js in the 'deployOptions' object.
6+
// TODO: replace with context.getTwilioClient() when https://issues.corp.twilio.com/browse/RUN-3731 is complete
7+
const twilio = require('twilio');
8+
9+
module.exports.handler = async (context, event, callback) => {
10+
const authHandler = require(Runtime.getAssets()['/auth-handler.js'].path);
11+
authHandler(context, event, callback);
12+
13+
let response = new Twilio.Response();
14+
response.appendHeader('Content-Type', 'application/json');
15+
16+
const { room_sid, rules } = event;
17+
18+
if (typeof room_sid === 'undefined') {
19+
response.setStatusCode(400);
20+
response.setBody({
21+
error: {
22+
message: 'missing room_sid',
23+
explanation: 'The room_sid parameter is missing.',
24+
},
25+
});
26+
return callback(null, response);
27+
}
28+
29+
if (typeof rules === 'undefined') {
30+
response.setStatusCode(400);
31+
response.setBody({
32+
error: {
33+
message: 'missing rules',
34+
explanation: 'The rules parameter is missing.',
35+
},
36+
});
37+
return callback(null, response);
38+
}
39+
40+
const client = twilio(context.ACCOUNT_SID, context.AUTH_TOKEN);
41+
42+
try {
43+
const recordingRulesResponse = await client.video.rooms(room_sid).recordingRules.update({ rules });
44+
response.setStatusCode(200);
45+
response.setBody(recordingRulesResponse);
46+
} catch (err) {
47+
response.setStatusCode(500);
48+
response.setBody({ error: { message: err.message, code: err.code } });
49+
}
50+
51+
callback(null, response);
52+
};

0 commit comments

Comments
 (0)