GPT_copy / app.py
JeCabrera's picture
Update app.py
181e1e3 verified
raw
history blame
10.5 kB
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,
}
)
# Directorio para guardar el historial
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: Sé CONCISO y PRÁCTICO. No hagas análisis excesivamente detallados. Ve directo al grano con recomendaciones accionables.
CUANDO ANALICES TITULARES:
1. Identifica 1-2 problemas principales (no más)
2. Proporciona 5 ejemplos de titulares mejorados
3. Pregunta si el usuario desea refinar alguno de los titulares propuestos
CUANDO ANALICES CUALQUIER TEXTO:
1. Identifica máximo 3 problemas principales
2. Proporciona una versión mejorada concisa
3. Pregunta si el usuario desea refinar algún aspecto específico
EL EQUIPO DE EXPERTOS:
1. ANALISTA DE COPY: Identifica problemas de estructura, claridad y enfoque
2. COPYWRITER DE RESPUESTA DIRECTA: Transforma textos débiles en mensajes persuasivos
3. ESPECIALISTA EN PSICOLOGÍA DE AUDIENCIA: Asegura conexión emocional con la audiencia
4. MAESTRO DEL STORYTELLING: Mejora narrativas para hacerlas más convincentes
5. EXPERTO EN ANUNCIOS Y PUBLICIDAD: Optimiza anuncios para diferentes plataformas
PROCESO DE ANÁLISIS Y MEJORA (SIMPLIFICADO):
1. ANÁLISIS RÁPIDO: Identifica el objetivo y los principales problemas
2. DIAGNÓSTICO CONCISO: Explica brevemente por qué no funciona
3. MEJORAS CONCRETAS: Proporciona alternativas claras y directas
4. VERSIÓN MEJORADA: Reescribe el texto de forma más persuasiva
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
# Procesar archivos de texto
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)}"
# Procesar archivos de imagen
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:
# Procesar el archivo si se ha subido
file_content, is_image, image_parts = process_file(file)
# Preparar el mensaje combinado
combined_message = message
# Si no hay mensaje pero hay archivo, usamos un mensaje predeterminado
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"
# Si hay un mensaje y un archivo de texto, añadimos el contenido
elif file is not None and not is_image:
combined_message += f"\n\nTexto a analizar y mejorar:\n{file_content}"
# Construir el historial de mensajes para el modelo
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]]})
# Crear el mensaje para el modelo
if is_image and image_parts:
# Si es una imagen, usamos multimodal
messages = [
{"role": "user", "parts": [system_prompt]},
*formatted_history,
{"role": "user", "parts": [
combined_message,
image_parts
]}
]
else:
# Si es texto, usamos el formato normal
messages = [
{"role": "user", "parts": [system_prompt]},
*formatted_history,
{"role": "user", "parts": [combined_message]}
]
# Generar la respuesta
save_to_history(combined_message, response.text)
# Devolver en el formato esperado por gr.Chatbot
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
)
# Slider para el nivel de creatividad
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 este titular: 'Aprende a programar'",
"Quiero mejorar este titular: 'Oferta especial'",
"Quiero mejorar este titular: 'Nuevo producto disponible'"
],
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()