import streamlit as st import os import re # Handle both old and new OpenAI library versions try: from openai import OpenAI OPENAI_V1 = True except ImportError: import openai OPENAI_V1 = False # Initialize OpenAI client def get_openai_client(): api_key = os.getenv("OPENAI_API_KEY") or st.secrets.get("OPENAI_API_KEY") if not api_key: st.error("OpenAI API key not found. Please set OPENAI_API_KEY in your environment variables or Streamlit secrets.") return None if OPENAI_V1: return OpenAI(api_key=api_key) else: openai.api_key = api_key return openai # Subject line analysis functions def analyze_subject_line(subject_line): """Analyze subject line for key metrics""" analysis = { 'character_count': len(subject_line), 'word_count': len(subject_line.split()), 'mobile_preview': subject_line[:33] + "..." if len(subject_line) > 33 else subject_line, 'has_emoji': bool(re.search(r'[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\U0001F1E0-\U0001F1FF\U00002600-\U000027BF]', subject_line)), 'has_numbers': bool(re.search(r'\d', subject_line)), 'exclamation_count': subject_line.count('!'), } # Simple scoring score = 8 # Start with good score # Length optimization (2-4 words ideal, 33 chars max for mobile) if analysis['word_count'] <= 4: score += 1 elif analysis['word_count'] > 7: score -= 1 if analysis['character_count'] <= 33: score += 1 elif analysis['character_count'] > 50: score -= 2 # Bonuses if analysis['has_numbers']: score += 1 if analysis['has_emoji']: score += 1 # Penalties if analysis['exclamation_count'] > 1: score -= 2 analysis['score'] = max(1, min(10, score)) return analysis def generate_subject_lines_advanced(audience, message, tone, psychology_framework, industry, personalization, client): """Generate high-quality, compelling subject lines""" try: framework_strategies = { "FOMO (Fear of Missing Out)": "Create genuine urgency and scarcity. Use time-sensitive language, countdown elements, or limited availability", "Curiosity Gap": "Create compelling information gaps that demand closure. Hint at valuable secrets, surprising revelations, or counterintuitive insights", "Social Proof": "Leverage what others are doing - specific user numbers, testimonials, trending status, or peer behavior", "Loss Aversion": "Frame what they're currently missing or losing rather than what they could gain", "Reciprocity": "Lead with valuable gifts, free resources, or helpful insights before asking for anything", "Authority": "Reference credible experts, research data, proven methodologies, or industry leadership", "Scarcity": "Emphasize genuine limited availability, exclusive access, or member-only benefits" } framework_strategy = framework_strategies.get(psychology_framework, '') prompt_text = f"""You are a world-class email copywriter who has written subject lines for the highest-performing email campaigns. Your subject lines are known for being irresistibly compelling while staying authentic. Campaign Context: - Target Audience: {audience} - Core Message: {message} - Brand Tone: {tone} - Psychological Strategy: {psychology_framework} - Industry Context: {industry} - Personalization Approach: {personalization} Advanced Strategy: {framework_strategy} Your Mission: Create 10 subject lines that would make someone instantly stop scrolling and click. Each should feel fresh, compelling, and impossible to ignore. CRITICAL EMOJI REQUIREMENT: Include emojis in at least 6 out of 10 subject lines (60%+). Emojis increase open rates by 39% when used appropriately. Place them strategically at the beginning or end for maximum impact. LENGTH VARIATION REQUIREMENT: - 7 subject lines: Ultra-short (2-4 words, max 33 characters) for mobile optimization - 2 subject lines: Medium length (5-7 words, 34-50 characters) for desktop impact - 1 subject line: Longer format (8+ words, 51-65 characters) for storytelling appeal Quality Requirements: 1. Apply {psychology_framework} psychology masterfully, not obviously 2. Include power words that trigger emotional response 3. Use numbers strategically (proven to increase opens by 45%) 4. Make each line feel unique and scroll-stopping 5. Avoid clichés, generic phrases, or obvious sales language 6. Ensure emojis enhance rather than distract from the message Examples of compelling techniques: - Specific numbers: "2-min trick", "73% faster", "$847 saved" - Intriguing questions: "Still doing this?", "Why X?", "Ready for Y?" - Surprising statements: "We're wrong", "This failed", "Oops..." - Personal urgency: "Your deadline", "Behind schedule?", "Missing this?" CRITICAL: Output format must be exactly: **1.** [subject line] (Length: Short/Medium/Long) [preheader text] **2.** [subject line] (Length: Short/Medium/Long) [preheader text] **3.** [subject line] (Length: Short/Medium/Long) [preheader text] Continue for all 10 options. Make each subject line feel like it was crafted by a master copywriter, not an AI tool. Remember: 6+ must have emojis, vary the lengths as specified.""" if OPENAI_V1: response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt_text}], max_tokens=1000, temperature=0.7 ) return response.choices[0].message.content else: response = client.ChatCompletion.create( model="gpt-4o", messages=[{"role": "user", "content": prompt_text}], max_tokens=1000, temperature=0.7 ) return response.choices[0].message.content except Exception as e: st.error(f"Error generating subject lines: {str(e)}") return None def optimize_existing_subject_line_clean(existing_subject, existing_preheader, audience, message, tone, psychology_framework, industry, personalization, client): """Advanced optimization with superior subject lines""" try: analysis = analyze_subject_line(existing_subject) preheader_text = f"Current preheader: {existing_preheader}" if existing_preheader else "No preheader provided" prompt_text = f"""You are an elite email optimization specialist who transforms mediocre subject lines into irresistible ones. Your optimizations consistently achieve 40%+ higher open rates. CURRENT SUBJECT LINE ANALYSIS: "{existing_subject}" {preheader_text} Length: {analysis['character_count']} characters, {analysis['word_count']} words Mobile Preview: "{analysis['mobile_preview']}" Current Effectiveness Score: {analysis['score']}/10 OPTIMIZATION BRIEF: - Target Audience: {audience} - Core Message: {message} - Desired Tone: {tone} - Psychology to Apply: {psychology_framework} - Industry Context: {industry} - Personalization Strategy: {personalization} YOUR MISSION: Transform this into 5 compelling alternatives that would dramatically outperform the original. CRITICAL EMOJI REQUIREMENT: Include emojis in at least 3 out of 5 optimized options (60%+). Emojis increase open rates by 39% when used strategically. LENGTH VARIATION REQUIREMENT: - 3 options: Ultra-short (2-4 words, max 33 characters) for mobile optimization - 1 option: Medium length (5-7 words, 34-50 characters) for desktop impact - 1 option: Longer format (8+ words, 51-65 characters) for storytelling appeal Advanced Optimization Strategies: 1. Apply {psychology_framework} psychology masterfully 2. Maximize mobile impact while offering variety 3. Use power words that trigger immediate action 4. Include specific numbers or percentages when relevant 5. Create genuine intrigue without being misleading 6. Leverage industry-specific pain points and desires 7. Make each option feel scroll-stopping and urgent Quality Standards: - Each subject line should feel like it was written by the world's best copywriter - Avoid generic, cliché, or obviously promotional language - Create genuine curiosity and emotional pull - Ensure mobile-first optimization with strategic longer options - Focus on what makes people instantly want to click EXACT OUTPUT FORMAT: **Current:** {existing_subject} (Score: {analysis['score']}/10) **Option 1:** [compelling subject line] (Length: Short/Medium/Long) [irresistible preheader] **Option 2:** [compelling subject line] (Length: Short/Medium/Long) [irresistible preheader] **Option 3:** [compelling subject line] (Length: Short/Medium/Long) [irresistible preheader] **Option 4:** [compelling subject line] (Length: Short/Medium/Long) [irresistible preheader] **Option 5:** [compelling subject line] (Length: Short/Medium/Long) [irresistible preheader] Make each option significantly more compelling than the original. Remember: 3+ must have emojis, vary lengths as specified.""" if OPENAI_V1: response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt_text}], max_tokens=1200, temperature=0.7 ) return response.choices[0].message.content else: response = client.ChatCompletion.create( model="gpt-4o", messages=[{"role": "user", "content": prompt_text}], max_tokens=1200, temperature=0.7 ) return response.choices[0].message.content except Exception as e: st.error(f"Error optimizing subject line: {str(e)}") return None def main(): st.set_page_config(page_title="Email Subject Line Optimizer", layout="wide") # Clean, minimal styling st.markdown(""" """, unsafe_allow_html=True) # Header st.markdown('