feat: Step 8 - Deepgram token API
Implement serverless-friendly Deepgram token generation. This provides a secure, stateless way for clients to use Deepgram's real-time streaming without exposing the main API key: 1. Client requests temporary token from Next.js API 2. Server generates short-lived (60s) token with 'member' scope 3. Client uses token to connect directly to Deepgram WebSocket This architecture bypasses Vercel's serverless WebSocket limitations while maintaining security by keeping the main Deepgram API key server-side only. Security: - Main API key never exposed to client - Temporary tokens expire in 60 seconds - Minimal 'member' scope permissions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
47
app/api/voice-token/route.ts
Normal file
47
app/api/voice-token/route.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
import { createClient } from '@deepgram/sdk';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This API route generates a short-lived, temporary API key
|
||||||
|
* for a client to connect directly to Deepgram's WebSocket.
|
||||||
|
* This avoids exposing our main API key and bypasses
|
||||||
|
* serverless WebSocket limitations.
|
||||||
|
*/
|
||||||
|
export async function POST(request: NextRequest) {
|
||||||
|
const deepgramApiKey = process.env.DEEPGRAM_API_KEY;
|
||||||
|
|
||||||
|
if (!deepgramApiKey) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Deepgram API key not configured' },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const deepgram = createClient(deepgramApiKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Create a new, temporary key with 'member' permissions
|
||||||
|
// that expires in 1 minute (60 seconds).
|
||||||
|
const response = await deepgram.manage.createProjectKey(
|
||||||
|
process.env.DEEPGRAM_PROJECT_ID || '',
|
||||||
|
{
|
||||||
|
comment: 'Temporary key for Ponderants user',
|
||||||
|
scopes: ['member'],
|
||||||
|
time_to_live_in_seconds: 60,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response || !response.key) {
|
||||||
|
throw new Error('Failed to create temporary key');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the temporary key back to the client
|
||||||
|
return NextResponse.json({ key: response.key });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating Deepgram key:', error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Failed to generate voice token' },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user