Spaces:
Sleeping
Sleeping
| 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, story_context=None): | |
| 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. | |
| """ | |
| # Preparar información de contexto/historia | |
| story_instruction = "" | |
| if story_context: | |
| story_instruction = f""" | |
| STORY CONTEXT: | |
| Incorporate elements from the following story/context into your CTAs when appropriate: | |
| {story_context} | |
| Use this context to make the CTAs more relatable, authentic, and emotionally resonant. | |
| You can reference specific elements, metaphors, or situations from the story. | |
| """ | |
| 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} | |
| {story_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 | |
| - If a story context was provided, weave elements from it naturally into the CTAs | |
| 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 (opcional)", | |
| placeholder="Ejemplo: urgencia, beneficio, descuento" | |
| ) | |
| # Mover el campo de historia aquí, después del tema de postdata | |
| story_context = st.text_area( | |
| "Historia o contexto (opcional)", | |
| placeholder="Ejemplo: Escribe el texto para crear una P.D. más específica a tus requerimientos" | |
| ) | |
| 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, | |
| story_context | |
| )): | |
| st.markdown("### Tus Llamados a la Acción") | |
| st.write(response) |