JeCabrera's picture
Upload app.py
82a9601 verified
raw
history blame
7.03 kB
from dotenv import load_dotenv
import streamlit as st
import os
import google.generativeai as genai
from cta_formulas import cta_formulas
from styles import apply_styles
from tone_formulas import tone_settings
# Cargar variables de entorno
load_dotenv()
# Configurar API de Google Gemini
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
def get_gemini_response(product_service, target_audience, desired_action, formula_type, tone_type, temperature, postdata_theme=None, cta_count=5):
if not product_service or not target_audience or not desired_action:
return "Por favor, completa todos los campos requeridos."
formula = cta_formulas[formula_type]
tone = tone_settings[tone_type]
# Lista de fórmulas que ya incluyen P.D. en su estructura
formulas_with_pd = ["El Último Aviso (No tan Último)", "Cierra con Corazón", "Gancho Cachondo"]
# Preparar información de postdata
postdata_instruction = ""
if postdata_theme:
# Solo aplicar la instrucción de postdata si la fórmula tiene PD en su estructura
if formula_type in formulas_with_pd:
postdata_instruction = f"""
POSTDATA THEME:
Use the following theme for the P.S. section: {postdata_theme}
IMPORTANT: For formulas with P.S.2 sections, use a DIFFERENT theme or approach than the one used in P.S.1.
DO NOT repeat the same urgency factor, benefit, or discount information in both postdatas.
Examples:
- If P.S.1 mentions "only 2 days left", P.S.2 should NOT mention time limits again
- If P.S.1 talks about "limited spots", P.S.2 should focus on a different benefit or feature
Make sure each postdata adds unique value and persuasion elements.
"""
model = genai.GenerativeModel('gemini-2.0-flash')
full_prompt = f"""
You are an expert copywriter specialized in creating persuasive Calls to Action (CTAs).
Analyze (internally, don't include in output) the following information:
BUSINESS INFORMATION:
Product/Service: {product_service}
Target Audience: {target_audience}
Desired Action: {desired_action}
CTA Type: {formula_type}
Tone Style: {tone['style']}
Keywords to consider: {', '.join(tone['keywords'])}
{formula["description"]}
{postdata_instruction}
First, analyze (but don't show) these points:
1. TARGET AUDIENCE ANALYSIS:
- What motivates them to take action?
- What obstacles prevent them from acting?
- What immediate benefits are they seeking?
- What fears or doubts do they have?
- What language and tone resonates with them?
2. PERSUASION ELEMENTS:
- How to make the desired action more appealing?
- What emotional triggers will resonate most?
- How to create a sense of urgency naturally?
- What unique value proposition to emphasize?
- How to minimize perceived risk?
Based on your internal analysis, create {cta_count} different CTAs following EXACTLY the formula structure:
{formula["description"]}
CRITICAL INSTRUCTIONS:
- Follow the exact formula structure shown in the description above
- Create {cta_count} different CTAs using the same formula pattern
- ALL CTAs MUST BE IN SPANISH
- DO NOT add postdata (P.S.) to formulas that don't include it in their structure
- When a formula includes multiple postdatas (P.S.1 and P.S.2), make sure they focus on DIFFERENT themes and don't repeat the same urgency factors or benefits
EXAMPLES TO FOLLOW:
{formula["examples"]}
Output EXACTLY in this format based on {formula_type}:
1. Follow format from {formula["examples"]}
2. Follow format from {formula["examples"]}
3. Follow format from {formula["examples"]}
"""
response = model.generate_content([full_prompt], generation_config={"temperature": temperature})
return response.parts[0].text if response and response.parts else "Error al generar contenido."
# Configurar la aplicación Streamlit
st.set_page_config(page_title="CTA Generator", page_icon="🎯", layout="wide")
# Leer y mostrar el manual en el sidebar
with open("manual.md", "r", encoding="utf-8") as file:
manual_content = file.read()
st.sidebar.markdown(manual_content)
# Aplicar estilos
st.markdown(apply_styles(), unsafe_allow_html=True)
# Título de la app
st.markdown("<h1>Generador de CTAs Persuasivos</h1>", unsafe_allow_html=True)
st.markdown("<h3>Crea llamados a la acción que motiven a tu audiencia a dar el siguiente paso.</h3>", unsafe_allow_html=True)
# Remove the duplicate manual expander from here
# Crear dos columnas
col1, col2 = st.columns([0.4, 0.6]) # 40% for left column, 60% for right column
# Columna izquierda para inputs
with col1:
target_audience = st.text_area(
"¿Cuál es tu público objetivo?",
placeholder="Ejemplo: Emprendedores que buscan automatizar su negocio..."
)
product_service = st.text_area(
"¿Cuál es tu producto o servicio?",
placeholder="Ejemplo: Curso de automatización con IA, Software de gestión..."
)
desired_action = st.text_area(
"¿Qué acción quieres que realicen?",
placeholder="Ejemplo: Registrarse al webinar, Descargar la guía gratuita..."
)
# Mover el botón aquí, antes del acordeón
generate_button = st.button("Generar CTAs")
with st.expander("Opciones avanzadas"):
formula_type = st.selectbox(
"Tipo de CTA:",
options=list(cta_formulas.keys())
)
tone_type = st.selectbox(
"Tono del CTA:",
options=list(tone_settings.keys()),
)
# Nuevos campos para postdata
postdata_theme = st.text_input(
"Tema o enfoque para la postdata",
placeholder="Ejemplo: urgencia, beneficio, descuento"
)
cta_count = st.number_input(
"Número de llamados a la acción",
min_value=1,
max_value=5,
value=3
)
temperature = st.slider(
"Nivel de creatividad:",
min_value=0.0,
max_value=2.0,
value=1.0,
step=0.1,
help="Valores más altos generan CTAs más creativos pero menos predecibles."
)
# Columna derecha para resultados
with col2:
if generate_button and (response := get_gemini_response(
product_service,
target_audience,
desired_action,
formula_type,
tone_type,
temperature,
postdata_theme,
cta_count
)):
st.markdown("### Tus Llamados a la Acción")
st.write(response)