-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
120 lines (103 loc) · 3.36 KB
/
Copy pathserver.js
File metadata and controls
120 lines (103 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import express from 'express';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { readFileSync, existsSync } from 'fs';
import { AccessToken } from 'livekit-server-sdk';
import { RoomConfiguration, RoomAgentDispatch } from '@livekit/protocol';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Load .env file if exists
const envPath = join(__dirname, '.env');
if (existsSync(envPath)) {
const envContent = readFileSync(envPath, 'utf-8');
for (const line of envContent.split('\n')) {
const trimmed = line.trim();
if (trimmed && !trimmed.startsWith('#')) {
const [key, ...valueParts] = trimmed.split('=');
if (key && valueParts.length > 0) {
process.env[key.trim()] = valueParts.join('=').trim();
}
}
}
}
const app = express();
const PORT = process.env.PORT || 3000;
const LIVEKIT_URL = process.env.LIVEKIT_URL;
const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY;
const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET;
// Middleware
app.use(express.json());
app.use(express.static(join(__dirname, 'public')));
// Generate LiveKit access token for a participant
app.post('/api/livekit/token', async (req, res) => {
if (!LIVEKIT_API_KEY || !LIVEKIT_API_SECRET) {
console.error('LiveKit credentials not configured');
return res.status(500).json({
error: 'Server configuration error',
detail: 'LiveKit credentials not configured'
});
}
try {
const { roomName, participantName } = req.body;
// Generate unique room and participant names if not provided
const room = roomName || `parle-${Date.now()}`;
const participant = participantName || `user-${Math.random().toString(36).substring(7)}`;
// Create access token
const token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET, {
identity: participant,
name: participant,
});
// Grant permissions for the room
token.addGrant({
room: room,
roomJoin: true,
canPublish: true,
canSubscribe: true,
canPublishData: true,
});
// Configure agent dispatch - empty agentName means use default agent
token.roomConfig = new RoomConfiguration({
agents: [
new RoomAgentDispatch({
agentName: '',
}),
],
});
const jwt = await token.toJwt();
console.log(`Token created for room: ${room}, participant: ${participant}`);
res.json({
token: jwt,
url: LIVEKIT_URL,
roomName: room,
participantName: participant
});
} catch (error) {
console.error('Error creating LiveKit token:', error);
res.status(500).json({
error: 'Failed to create token',
detail: error.message
});
}
});
// Health check endpoint
app.get('/api/health', (req, res) => {
res.json({
status: 'ok',
services: {
livekit: !!LIVEKIT_API_KEY,
beyondPresence: !!process.env.BEY_API_KEY
}
});
});
// Get configuration (without secrets)
app.get('/api/config', (req, res) => {
res.json({
livekitUrl: LIVEKIT_URL
});
});
app.listen(PORT, () => {
console.log(`Parle server running at http://localhost:${PORT}`);
console.log('');
console.log('To start the AI agent, run in another terminal:');
console.log(' npm run agent');
});