import { GlobalFunctions, TransferAreaProperties } from '@/GlobalFunctions'; import { apiService } from './api'; /** * Tipos de vozes disponíveis para geração de áudio */ export type VoiceType = 'alloy' | 'echo' | 'fable' | 'nova' | 'onyx' | 'shimmer'; /** * Interface para a resposta da API de geração de áudio */ export interface AudioGenerationResponse { success: boolean; audio_url: string; // URL do áudio gerado audio_generation_id: string; message: string; // Texto que foi convertido em áudio } /** * Interface para os dados necessários para geração de áudio */ export interface AudioGenerationRequest { message: string; voice: VoiceType; userEmail?: string; estabelecimentoId?: number; } /** * Informações sobre cada tipo de voz disponível */ export const VOICE_OPTIONS = { alloy: { label: "Alloy", gender: "Masculina", style: "Neutra, equilibrada, tom corporativo", description: "Boa para tutoriais e comunicações institucionais." }, echo: { label: "Echo", gender: "Masculina", style: "Forte e profissional, mais grave", description: "Ideal para voz de autoridade ou locução firme." }, fable: { label: "Fable", gender: "Feminina", style: "Narrativa, calorosa e envolvente", description: "Ótima para storytelling e áudios empáticos." }, onyx: { label: "Onyx", gender: "Masculina", style: "Grave, autoritária, impactante", description: "Excelente para trailers, mensagens sérias ou institucionais." }, nova: { label: "Nova", gender: "Feminina", style: "Brilhante, animada, energética", description: "Boa para vídeos curtos, marketing ou conteúdos leves." }, shimmer: { label: "Shimmer", gender: "Feminina", style: "Suave, otimista, clara", description: "Boa para mensagens acolhedoras, explicações e IA conversacional." } } as const; /** * Serviço de geração de áudio (Text-to-Speech) */ class AudioGenerationService { private readonly AUDIO_GENERATION_ENDPOINT = '/webhook/codex/gerar_audio'; /** * Gera um arquivo de áudio a partir de texto * * @param request - Dados da requisição (texto, voz, email, estabelecimento) * @returns Promise com a resposta da API */ async generateAudio(request: AudioGenerationRequest): Promise { const { message, voice, userEmail, estabelecimentoId } = request; // Usa valores do .env se não forem fornecidos const email = GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);//userEmail || import.meta.env.VITE_USER_EMAIL || ''; const estabId = GlobalFunctions.getTransferProperty(TransferAreaProperties.EstabelecimentoCodigo);//estabelecimentoId || parseInt(import.meta.env.VITE_ESTABELECIMENTO_ID) || 1; // Valida o texto if (!message || message.trim().length === 0) { throw { success: false, message: 'O texto não pode estar vazio', }; } // Valida a voz if (!this.isValidVoice(voice)) { throw { success: false, message: `Voz inválida. Opções disponíveis: ${Object.keys(VOICE_OPTIONS).join(', ')}`, }; } // Log para debug (remover em produção se necessário) console.log('Gerando áudio:', { messageLength: message.length, voice, userEmail: email, estabelecimentoId: estabId, }); try { // Faz a requisição usando o serviço de API const response = await apiService.post( this.AUDIO_GENERATION_ENDPOINT, { estabelecimento_id: estabId, user_email: email, message: message, voice: voice, } ); return response.data; } catch (error: any) { // Trata erros específicos console.error('Erro na geração de áudio:', error); throw { success: false, message: error.message || 'Erro ao gerar áudio', status: error.status, }; } } /** * Valida se a voz selecionada é suportada * * @param voice - Voz a ser validada * @returns true se a voz é válida */ isValidVoice(voice: string): voice is VoiceType { return Object.keys(VOICE_OPTIONS).includes(voice); } /** * Obtém informações sobre uma voz específica * * @param voice - Tipo de voz * @returns Informações da voz */ getVoiceInfo(voice: VoiceType) { return VOICE_OPTIONS[voice]; } /** * Lista todas as vozes disponíveis * * @returns Array com todas as opções de voz */ getAllVoices() { return Object.entries(VOICE_OPTIONS).map(([key, info]) => ({ value: key as VoiceType, ...info, })); } /** * Valida o texto para geração de áudio * * @param text - Texto a ser validado * @param maxLength - Comprimento máximo (padrão: 4096 caracteres) * @returns Objeto com resultado da validação */ validateText(text: string, maxLength: number = 4096): { valid: boolean; error?: string } { if (!text || text.trim().length === 0) { return { valid: false, error: 'O texto não pode estar vazio', }; } if (text.length > maxLength) { return { valid: false, error: `O texto é muito longo. Máximo: ${maxLength} caracteres`, }; } return { valid: true }; } } // Exporta instância única (Singleton) export const audioGenerationService = new AudioGenerationService();