// ============================================================ // ANALIZADOR — GPT-4o // Prompt maestro multidisciplinario: Storytelling + Cialdini // + Neuropublicidad + Copywriting → JSON de 49 campos // ============================================================ import OpenAI from 'openai' const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }) const PROMPT_SISTEMA = `Eres un experto en ingeniería de guiones para video corto (TikTok, Reels, YouTube Shorts) con especialización en: - Storytelling y estructura narrativa - Psicología de la persuasión (Cialdini, sesgos cognitivos) - Neuropublicidad y neuromarketing - Copywriting directo (Eugene Schwartz, Gary Halbert, David Ogilvy) - Marketing de contenidos para múltiples nichos Tu tarea es analizar la transcripción de un video y devolver un JSON con el análisis completo. SOLO devuelve el JSON, sin texto adicional, sin markdown, sin explicaciones.` /** * @param {string} transcript Texto transcrito por Whisper * @param {string} niche Nicho del video (ej: "fitness", "finanzas") * @param {string} plataforma tiktok | reels | shorts * @param {number} duracion Duración en segundos * @param {string} contextoVideo Contexto adicional opcional sobre el video * @returns {object} JSON con todos los campos de análisis */ export async function analizarTranscript(transcript, niche, plataforma, duracion, contextoVideo = '') { const bloqueContexto = contextoVideo ? `CONTEXTO ADICIONAL DEL VIDEO (úsalo para enriquecer el análisis):\n"""\n${contextoVideo}\n"""\n\n` : '' const promptUsuario = `Analiza este video de ${plataforma} de ${duracion} segundos del nicho "${niche}". ${bloqueContexto}TRANSCRIPCIÓN: """ ${transcript} """ Devuelve EXACTAMENTE este JSON con los valores que correspondan: { "estructura_narrativa": "", "gancho_tipo": "", "gancho_texto": "", "apertura_exacta": "", "cierre_exacto": "", "gancho_duracion_seg": , "desarrollo_tipo": "", "cta_tipo": "", "cta_texto": "", "arco_emocional": "", "conflicto_central": "", "resolucion": "", "pacing_ritmo": "", "numero_actos": <1, 2 o 3>, "tecnica_retencion": "", "momento_pico_seg": , "cialdini_reciprocidad": , "cialdini_escasez": , "cialdini_autoridad": , "cialdini_consistencia": , "cialdini_prueba_social": , "cialdini_simpatia": , "cialdini_unidad": , "sesgo_cognitivo": "", "trigger_emocional": "", "intensidad_emocional": , "atencion_visual": "", "lenguaje_sensorial": , "contraste_narrativo": , "efecto_novedad": , "dolor_placer": "", "personalizacion": , "carga_cognitiva": "", "velocidad_locucion": "", "uso_musica": , "micro_compromisos": , "ratio_emocion_logica": "", "tema_principal": "", "angulo_unico": "", "palabras_clave": ["", "", "", "", ""], "tono": "", "persona_narradora": "", "promesa_explicita": "", "nivel_especificidad": "", "nivel_consciencia": "", "objecion_principal": "", "avatar_descripcion": "", "ingredientes_clave": ["", "", ""], "replicabilidad": "", "fortalezas": ["", "", ""], "debilidades": ["", ""], "sugerencias_mejora": ["", "", ""], "hashtags_sugeridos": ["", "", "", "", "", "", ""], "score_virabilidad": , "resumen_patron": "" }` const completion = await openai.chat.completions.create({ model: 'gpt-4o', temperature: 0.2, messages: [ { role: 'system', content: PROMPT_SISTEMA }, { role: 'user', content: promptUsuario }, ], }) const contenido = completion.choices[0]?.message?.content?.trim() if (!contenido) { throw new Error('GPT-4o devolvió una respuesta vacía') } const jsonLimpio = contenido .replace(/^```json\n?/, '') .replace(/^```\n?/, '') .replace(/\n?```$/, '') .trim() try { return JSON.parse(jsonLimpio) } catch { throw new Error(`GPT-4o devolvió JSON inválido. Primeros 200 chars: ${jsonLimpio.slice(0, 200)}`) } }