Skip to content

Commit d6137fb

Browse files
authored
Update token endpoint response to match working standard (#59)
* feat: add body parser as existing implementation was missing it This meant that passing a custom body to /createToken did nothing! * feat: bring token endpoint up to the working standard - Make request / response body snake_case not camelCase - Add `participant_identity` / `participant_metadata` / `participant_attributes` / `room_config` request fields - Add `server_url` to token generation response * feat: add note by old fields for backwards compatibility * feat: add randomly generated room/participant names
1 parent 6718f0f commit d6137fb

File tree

3 files changed

+148
-13
lines changed

3 files changed

+148
-13
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
"format": "prettier --write \"**/*.ts\""
1212
},
1313
"dependencies": {
14+
"@livekit/protocol": "^1.41.0",
15+
"body-parser": "^2.2.0",
1416
"dotenv": "^16.4.5",
1517
"express": "^4.21.1",
1618
"livekit-server-sdk": "^2.8.1"
@@ -19,6 +21,7 @@
1921
"@eslint/eslintrc": "^3.1.0",
2022
"@eslint/js": "^9.13.0",
2123
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
24+
"@types/body-parser": "^1.19.6",
2225
"@types/express": "^5.0.0",
2326
"@types/node": "^22.8.6",
2427
"@typescript-eslint/eslint-plugin": "^8.12.2",

pnpm-lock.yaml

Lines changed: 100 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.ts

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,78 @@
1+
import { RoomConfiguration } from '@livekit/protocol';
2+
import bodyParser from 'body-parser';
13
import dotenv from 'dotenv';
24
import express from 'express';
35
import { AccessToken } from 'livekit-server-sdk';
46

57
type TokenRequest = {
6-
roomName: string;
7-
participantName: string;
8+
room_name?: string;
9+
participant_name?: string;
10+
participant_identity?: string;
11+
participant_metadata?: string;
12+
participant_attributes?: Record<string, string>;
13+
room_config?: ReturnType<RoomConfiguration['toJson']>;
14+
15+
// (old fields, here for backwards compatibility)
16+
roomName?: string;
17+
participantName?: string;
818
};
919

1020
// Load environment variables from .env.local file
1121
dotenv.config({ path: '.env.local' });
1222

1323
// This route handler creates a token for a given room and participant
14-
async function createToken({ roomName, participantName }: TokenRequest) {
24+
async function createToken(request: TokenRequest) {
25+
const roomName = request.room_name ?? request.roomName!;
26+
const participantName = request.participant_name ?? request.participantName!;
27+
1528
const at = new AccessToken(process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET, {
1629
identity: participantName,
1730
// Token to expire after 10 minutes
1831
ttl: '10m',
1932
});
33+
2034
// Token permissions can be added here based on the
2135
// desired capabilities of the participant
2236
at.addGrant({
2337
roomJoin: true,
2438
room: roomName,
2539
canUpdateOwnMetadata: true,
2640
});
41+
42+
if (request.participant_identity) {
43+
at.identity = request.participant_identity;
44+
}
45+
if (request.participant_metadata) {
46+
at.metadata = request.participant_metadata;
47+
}
48+
if (request.participant_attributes) {
49+
at.attributes = request.participant_attributes;
50+
}
51+
if (request.room_config) {
52+
at.roomConfig = RoomConfiguration.fromJson(request.room_config);
53+
}
54+
2755
return at.toJwt();
2856
}
2957

3058
const app = express();
59+
app.use(bodyParser.json());
3160
const port = 3000;
3261

3362
app.post('/createToken', async (req, res) => {
34-
const { roomName = 'demo-room', participantName = 'demo-user' } = req.body ?? {};
35-
res.send(await createToken({ roomName, participantName }));
63+
const body = req.body ?? {};
64+
body.roomName = body.roomName ?? `room-${crypto.randomUUID()}`;
65+
body.participantName = body.participantName ?? `user-${crypto.randomUUID()}`;
66+
67+
try {
68+
res.send({
69+
server_url: process.env.LIVEKIT_URL,
70+
participant_token: await createToken(body),
71+
});
72+
} catch (err) {
73+
console.error('Error generating token:', err);
74+
res.status(500).send({ message: 'Generating token failed' });
75+
}
3676
});
3777

3878
app.listen(port, () => {

0 commit comments

Comments
 (0)