|
import os |
|
import gradio as gr |
|
import google.generativeai as genai |
|
from dotenv import load_dotenv |
|
import PyPDF2 |
|
import docx |
|
from PIL import Image |
|
import io |
|
import json |
|
import datetime |
|
|
|
load_dotenv() |
|
genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) |
|
|
|
model = genai.GenerativeModel( |
|
model_name="gemini-2.0-flash", |
|
generation_config={ |
|
"temperature": 0.9, |
|
"top_p": 1, |
|
"max_output_tokens": 2048, |
|
} |
|
) |
|
|
|
|
|
HISTORY_DIR = "historial_analisis" |
|
os.makedirs(HISTORY_DIR, exist_ok=True) |
|
|
|
system_prompt = """Eres un equipo colaborativo de expertos de clase mundial en copywriting que trabajan juntos para ANALIZAR y MEJORAR textos persuasivos. Tu objetivo principal es identificar puntos débiles en el copy y transformarlos en mensajes más persuasivos y efectivos. |
|
|
|
IMPORTANTE: Eres un agente virtual cuyo objetivo es realizar cuantas iteraciones sean necesarias hasta que el usuario esté conforme con el resultado. Siempre pregunta si hay algo más que puedas mejorar o ajustar. |
|
|
|
CUANDO ANALICES CUALQUIER TEXTO (INCLUYENDO TITULARES): |
|
1. Realiza un análisis certero y directo, identificando los puntos más importantes |
|
2. Enfócate en los problemas principales que afectan la persuasión |
|
3. Ofrece recomendaciones específicas basadas en principios de copywriting |
|
4. Incluye una versión mejorada del texto |
|
5. SIEMPRE pregunta: "¿Hay algún aspecto específico que quieras que mejore más?" |
|
|
|
PARA TITULARES ESPECÍFICAMENTE: |
|
Siempre proporciona 5 ejemplos de titulares mejorados que estén LISTOS PARA USAR (sin placeholders ni corchetes). Por ejemplo: |
|
|
|
1. "Descubre cómo nuestro curso de marketing digital te ayuda a duplicar tus ventas más rápido que nunca." |
|
2. "Resultados comprobados es lo que nos diferencia. Aprende cómo impacta tu negocio desde el primer día." |
|
3. "¿Cansado de perder clientes? Nosotros te damos la solución definitiva y te mostramos cómo implementarla." |
|
4. "La publicidad digital ya no será lo mismo. Te revelamos la estrategia que está revolucionando las conversiones." |
|
5. "Únete a los 10,000 emprendedores que ya están experimentando un aumento del 300% gracias a nuestra metodología." |
|
|
|
NO analices los ejemplos proporcionados, simplemente ofrécelos como alternativas. |
|
|
|
EL EQUIPO DE EXPERTOS QUE DEBE PARTICIPAR EN CADA ANÁLISIS: |
|
|
|
1. ANALISTA DE COPY: |
|
- Especialista en identificar fortalezas y debilidades en textos persuasivos |
|
- Detecta problemas de estructura, claridad y enfoque |
|
- Evalúa la alineación entre mensaje y audiencia objetivo |
|
- Proporciona diagnósticos precisos sobre lo que funciona y lo que no |
|
|
|
2. COPYWRITER DE RESPUESTA DIRECTA: |
|
- Formado por Gary Halbert, Gary Bencivenga y David Ogilvy |
|
- Transforma textos débiles en mensajes persuasivos y directos |
|
- Mejora ganchos, historias y llamados a la acción |
|
- Asegura que cada palabra contribuya a la conversión |
|
|
|
3. ESPECIALISTA EN PSICOLOGÍA DE AUDIENCIA: |
|
- Experto en comprender las motivaciones y objeciones de la audiencia |
|
- Identifica desconexiones emocionales en el mensaje |
|
- Refuerza la relevancia y conexión personal del texto |
|
- Asegura que el contenido resuene con los deseos y miedos del público |
|
|
|
4. MAESTRO DEL STORYTELLING: |
|
- Mejora las narrativas para hacerlas más convincentes |
|
- Identifica oportunidades para insertar historias persuasivas |
|
- Transforma conceptos abstractos en ejemplos concretos |
|
- Añade elementos narrativos que aumentan la retención y el impacto |
|
|
|
5. EXPERTO EN ANUNCIOS Y PUBLICIDAD: |
|
- Especialista en optimizar anuncios para diferentes plataformas |
|
- Mejora titulares, imágenes y textos para aumentar CTR |
|
- Conoce las mejores prácticas para Facebook, Google y otras plataformas |
|
- Asegura que los anuncios capten atención y generen acción inmediata |
|
|
|
PROCESO DE ANÁLISIS Y MEJORA: |
|
Para cada texto que analices, SIEMPRE debes seguir este proceso de 4 pasos: |
|
|
|
1. ANÁLISIS CERTERO: |
|
- Identifica el objetivo principal del texto |
|
- Evalúa los puntos débiles más importantes |
|
- Señala fortalezas que deben mantenerse |
|
|
|
2. DIAGNÓSTICO DE PROBLEMAS CLAVE: |
|
- Explica por qué ciertos elementos no funcionan |
|
- Identifica las principales oportunidades perdidas de persuasión |
|
- Evalúa la claridad del valor ofrecido |
|
|
|
3. RECOMENDACIONES ESPECÍFICAS: |
|
- Proporciona sugerencias concretas para cada problema principal |
|
- Ofrece alternativas para elementos clave |
|
- Explica el razonamiento psicológico detrás de cada mejora |
|
|
|
4. VERSIÓN MEJORADA: |
|
- Reescribe el texto incorporando todas las mejoras |
|
- Mantén el tono y estilo original cuando sea apropiado |
|
- Asegura que la versión final sea coherente y fluida |
|
|
|
5. PREGUNTA FINAL: |
|
- Siempre termina preguntando: "¿Hay algún aspecto específico que quieras que mejore más?" |
|
|
|
TIPOS DE CONTENIDO QUE PUEDES ANALIZAR Y MEJORAR: |
|
- Anuncios de Facebook, Google y otras plataformas |
|
- Páginas de ventas y landing pages |
|
- Emails de secuencias de ventas |
|
- Titulares y subtítulos |
|
- Descripciones de producto |
|
- Guiones de webinar |
|
- Historias de caso y testimonios |
|
- Propuestas únicas de valor |
|
- Llamados a la acción (CTAs) |
|
|
|
RESPONDE SIEMPRE EN ESPAÑOL con un enfoque orientado a resultados, mostrando claramente cómo tus mejoras aumentarán la persuasión y efectividad del texto. |
|
|
|
IMPORTANTE: Siempre mantén un equilibrio entre persuasión efectiva y ética. El objetivo es mejorar la comunicación y la persuasión, no engañar o manipular.""" |
|
|
|
def save_to_history(user_input, ai_response): |
|
"""Guarda la interacción en el historial""" |
|
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") |
|
filename = f"{HISTORY_DIR}/analisis_{timestamp}.json" |
|
|
|
data = { |
|
"timestamp": timestamp, |
|
"user_input": user_input, |
|
"ai_response": ai_response |
|
} |
|
|
|
with open(filename, 'w', encoding='utf-8') as f: |
|
json.dump(data, f, ensure_ascii=False, indent=2) |
|
|
|
return filename |
|
|
|
def process_file(file): |
|
if file is None: |
|
return "", False, None |
|
|
|
file_path = file.name |
|
file_extension = os.path.splitext(file_path)[1].lower() |
|
file_content = "" |
|
is_image = False |
|
image_parts = None |
|
|
|
|
|
if file_extension in ['.txt']: |
|
try: |
|
with open(file_path, 'r', encoding='utf-8') as f: |
|
file_content = f.read() |
|
except Exception as e: |
|
file_content = f"Error al leer el archivo TXT: {str(e)}" |
|
|
|
elif file_extension in ['.pdf']: |
|
try: |
|
pdf_reader = PyPDF2.PdfReader(file_path) |
|
file_content = "" |
|
for page in pdf_reader.pages: |
|
file_content += page.extract_text() + "\n" |
|
except Exception as e: |
|
file_content = f"Error al leer el archivo PDF: {str(e)}" |
|
|
|
elif file_extension in ['.docx']: |
|
try: |
|
doc = docx.Document(file_path) |
|
file_content = "\n".join([para.text for para in doc.paragraphs]) |
|
except Exception as e: |
|
file_content = f"Error al leer el archivo DOCX: {str(e)}" |
|
|
|
|
|
elif file_extension in ['.jpg', '.jpeg', '.png']: |
|
try: |
|
image = Image.open(file_path) |
|
with open(file_path, 'rb') as img_file: |
|
image_bytes = img_file.read() |
|
|
|
image_parts = { |
|
"mime_type": f"image/{file_extension[1:]}", |
|
"data": image_bytes |
|
} |
|
is_image = True |
|
file_content = "Imagen cargada correctamente" |
|
except Exception as e: |
|
file_content = f"Error al procesar la imagen: {str(e)}" |
|
is_image = False |
|
|
|
else: |
|
file_content = f"Tipo de archivo no soportado: {file_extension}" |
|
|
|
return file_content, is_image, image_parts |
|
|
|
def chat(message, history, file=None, temperature=0.9): |
|
try: |
|
|
|
file_content, is_image, image_parts = process_file(file) |
|
|
|
|
|
combined_message = message |
|
|
|
|
|
if message.strip() == "" and file is not None: |
|
if is_image: |
|
combined_message = "Analiza esta imagen de anuncio y proporciona mejoras específicas para aumentar su efectividad" |
|
else: |
|
combined_message = "Analiza este texto y proporciona mejoras específicas para aumentar su persuasión y efectividad" |
|
|
|
|
|
elif file is not None and not is_image: |
|
combined_message += f"\n\nTexto a analizar y mejorar:\n{file_content}" |
|
|
|
|
|
formatted_history = [] |
|
for msg in history: |
|
if isinstance(msg, dict): |
|
if msg["role"] == "user": |
|
formatted_history.append({"role": "user", "parts": [msg["content"]]}) |
|
else: |
|
formatted_history.append({"role": "model", "parts": [msg["content"]]}) |
|
else: |
|
formatted_history.append({"role": "user", "parts": [msg[0]]}) |
|
formatted_history.append({"role": "model", "parts": [msg[1]]}) |
|
|
|
|
|
if is_image and image_parts: |
|
|
|
messages = [ |
|
{"role": "user", "parts": [system_prompt]}, |
|
*formatted_history, |
|
{"role": "user", "parts": [ |
|
combined_message, |
|
image_parts |
|
]} |
|
] |
|
else: |
|
|
|
messages = [ |
|
{"role": "user", "parts": [system_prompt]}, |
|
*formatted_history, |
|
{"role": "user", "parts": [combined_message]} |
|
] |
|
|
|
|
|
generation_config = { |
|
"temperature": temperature, |
|
"top_p": 1, |
|
"max_output_tokens": 2048, |
|
} |
|
response = model.generate_content(messages, generation_config=generation_config) |
|
|
|
|
|
save_to_history(combined_message, response.text) |
|
|
|
|
|
return history + [{"role": "user", "content": message}, {"role": "assistant", "content": response.text}] |
|
except Exception as e: |
|
return history + [{"role": "user", "content": message}, {"role": "assistant", "content": f"Error: {e}"}] |
|
|
|
with gr.Blocks(title="📝 CopyAnalyzer - Análisis y Mejora de Textos Persuasivos") as demo: |
|
gr.Markdown("# 📝 CopyAnalyzer - Análisis y Mejora de Textos Persuasivos") |
|
gr.Markdown("¡Hola! Soy CopyAnalyzer, tu equipo de expertos en copywriting. Puedo analizar y mejorar tus textos persuasivos para aumentar su efectividad. Sube un texto o imagen de anuncio, o simplemente escribe tu copy actual para recibir un análisis detallado y una versión mejorada.") |
|
|
|
with gr.Row(): |
|
with gr.Column(scale=4): |
|
chatbot = gr.Chatbot(type="messages", height=500) |
|
|
|
with gr.Row(): |
|
msg = gr.Textbox( |
|
placeholder="Pega tu texto aquí o describe qué tipo de copy quieres analizar...", |
|
container=False, |
|
scale=7 |
|
) |
|
submit = gr.Button("Analizar", variant="primary") |
|
|
|
with gr.Row(): |
|
clear = gr.Button("Limpiar") |
|
|
|
with gr.Column(scale=1): |
|
file_upload = gr.File( |
|
label="📄 Sube tu texto o imagen de anuncio", |
|
file_types=["txt", "pdf", "docx", "jpg", "jpeg", "png"], |
|
type="filepath", |
|
visible=True |
|
) |
|
|
|
|
|
temperature_slider = gr.Slider( |
|
label="Nivel de creatividad:", |
|
minimum=0.0, |
|
maximum=2.0, |
|
value=0.9, |
|
step=0.1, |
|
info="Valores más altos generan ideas más creativas pero menos predecibles." |
|
) |
|
|
|
examples = gr.Examples( |
|
examples=[ |
|
|
|
"Quiero mejorar este titular: 'Soy el mejor'", |
|
"Quiero mejorar este titular: 'Curso de marketing digital'", |
|
|
|
|
|
"Quiero mejorar esta descripción de producto: 'Nuestro producto es de alta calidad y tiene muchas funciones útiles. Lo hemos diseñado pensando en ti.'", |
|
|
|
|
|
"Quiero mejorar este CTA: 'Haz clic aquí para más información'", |
|
|
|
|
|
"Quiero mejorar este anuncio de Facebook: 'Oferta por tiempo limitado. Nuestro producto ahora con 20% de descuento. No te lo pierdas.'", |
|
|
|
|
|
"Quiero mejorar este email de ventas: 'Estimado cliente, le informamos que tenemos una oferta especial para usted. Esperamos su respuesta. Saludos cordiales.'", |
|
|
|
|
|
"Quiero mejorar esta introducción de página de ventas: 'Bienvenido a nuestra página. Ofrecemos los mejores servicios del mercado a precios competitivos. Contáctanos para más información.'", |
|
|
|
|
|
"Quiero mejorar esta propuesta de valor: 'Somos una empresa con años de experiencia en el sector, ofreciendo soluciones integrales para tu negocio.'", |
|
|
|
|
|
"Quiero mejorar esta historia para mi marca: 'Nuestra empresa comenzó hace 10 años con una idea simple. Hoy somos líderes en el mercado gracias a nuestro esfuerzo.'" |
|
], |
|
inputs=msg |
|
) |
|
|
|
submit.click( |
|
chat, |
|
inputs=[msg, chatbot, file_upload, temperature_slider], |
|
outputs=chatbot, |
|
queue=True |
|
).then( |
|
lambda: "", |
|
None, |
|
msg, |
|
queue=False |
|
) |
|
|
|
clear.click(lambda: [], None, chatbot, queue=False) |
|
msg.submit( |
|
chat, |
|
inputs=[msg, chatbot, file_upload, temperature_slider], |
|
outputs=chatbot, |
|
queue=True |
|
).then( |
|
lambda: "", |
|
None, |
|
msg, |
|
queue=False |
|
) |
|
|
|
demo.launch() |
|
|
|
|