import express from 'express' import { AccessToken } from 'livekit-server-sdk' const app = express() app.use(express.json()) const API_KEY = process.env.LIVEKIT_API_KEY || 'APIyxZGQjM2' const API_SECRET = process.env.LIVEKIT_API_SECRET || 'secretNmU4ZDU3YjA0OWIxNDM4YjhlNWY3YTFjZGUzOWRi' const PB_URL = process.env.PB_URL || 'http://gamegroup-pb:8090' const PORT = process.env.PORT || 7882 app.post('/api/voice-token/:sessionId', async (req, res) => { try { const { sessionId } = req.params const authHeader = req.headers.authorization console.log('Voice token request:', { sessionId, authHeader: authHeader ? authHeader.slice(0, 20) + '...' : null }) if (!authHeader) { console.log('Missing auth header') return res.status(401).json({ error: '未登录' }) } // 验证用户 token — 调用 PocketBase const pbRefreshUrl = `${PB_URL}/api/collections/users/auth-refresh` console.log('Calling PB auth-refresh:', pbRefreshUrl) const pbRes = await fetch(pbRefreshUrl, { method: 'POST', headers: { Authorization: authHeader, 'Content-Type': 'application/json', }, body: '{}', }) console.log('PB auth-refresh status:', pbRes.status) if (!pbRes.ok) { const pbBody = await pbRes.text().catch(() => 'unknown') console.log('PB auth-refresh error body:', pbBody) return res.status(401).json({ error: '认证失败', detail: pbBody }) } const userData = await pbRes.json() console.log('PB auth-refresh success, userId:', userData.record?.id) const userId = userData.record?.id const userName = userData.record?.name || userData.record?.username || userId if (!userId) { return res.status(401).json({ error: '无效用户' }) } // 获取 session 并验证成员 const sessionRes = await fetch(`${PB_URL}/api/collections/team_sessions/records/${sessionId}`, { headers: { Authorization: authHeader }, }) if (!sessionRes.ok) { return res.status(404).json({ error: '未找到临时小组' }) } const session = await sessionRes.json() const members = session.members || [] if (!members.includes(userId)) { return res.status(403).json({ error: '你不是该小队的成员' }) } // 签发 LiveKit token const at = new AccessToken(API_KEY, API_SECRET, { identity: userId, name: userName, }) at.addGrant({ roomJoin: true, room: `team-${sessionId}`, canPublish: true, canSubscribe: true, }) const token = await at.toJwt() res.json({ token }) } catch (err) { console.error('Voice token error:', err) res.status(500).json({ error: '服务器错误' }) } }) app.get('/health', (_req, res) => { res.json({ status: 'ok' }) }) app.listen(PORT, () => { console.log(`Voice token service listening on :${PORT}`) })