import { Router, Request, Response } from 'express'; import { z } from 'zod'; import { ttsService } from '../services/ttsService'; import { languageService } from '../services/languageService'; const router = Router(); // Schema for TTS request const ttsSchema = z.object({ text: z.string().min(1).max(5000), voiceId: z.string().optional(), }); router.post('/speak', async (req: Request, res: Response) => { try { const validatedData = ttsSchema.parse(req.body); // Detect language if not already set if (!req.language) { const detectedLanguage = await languageService.detectFromText( validatedData.text, req.sessionId || 'default' ); req.language = detectedLanguage; } // Generate speech using detected/stored language const result = await ttsService.generateSpeech({ ...validatedData, language: req.language.code, }); // Set appropriate headers for audio file res.setHeader('Content-Type', 'audio/mpeg'); res.setHeader('Content-Disposition', 'attachment; filename="speech.mp3"'); res.setHeader('X-Detected-Language', req.language.code); // Send the file and clean up afterward res.sendFile(result.audioPath, async (err) => { if (err) { console.error('Error sending audio file:', err); } // Clean up the file after sending await ttsService.cleanup(result.audioPath); }); } catch (error) { if (error instanceof z.ZodError) { return res.status(400).json({ success: false, error: 'Validation error', details: error.errors, }); } console.error('Error processing TTS request:', error); res.status(500).json({ success: false, error: 'Failed to generate speech', }); } }); export default router;