""" Apex Pitch Generator Module ============================ Generate personalized cold outreach pitches based on pain signals. Focus: Lead Generation as highest-margin service. """ from .logger import get_logger # Pitch templates by pain signal PITCH_TEMPLATES = { 'missed_calls': { 'hook': "I noticed {count} recent reviews mentioning people couldn't reach {business} by phone", 'problem': "Every missed call is a potential customer going to your competitor", 'solution': "I help businesses like yours capture every lead with smart call routing and instant follow-up", 'proof': "My last client recovered $12K/month in lost leads within 30 days", 'cta': "Can I show you how in a quick 10-minute call?", }, 'no_website': { 'hook': "I noticed {business} doesn't have a website yet", 'problem': "In 2026, 87% of customers search online before choosing a local business", 'solution': "I build fast, mobile-friendly websites that actually generate leads (not just look pretty)", 'proof': "Average client sees 15-20 new inquiries per month within 60 days", 'cta': "Want to see some examples of sites I've built for {industry} businesses?", }, 'broken_website': { 'hook': "I checked {business}'s website and noticed {issue}", 'problem': "This is likely costing you customers right now — Google penalizes broken sites in search rankings", 'solution': "I can fix this in 48 hours and get you back in Google's good books", 'proof': "Fixed 23 sites this year with avg 40% traffic increase within 2 weeks", 'cta': "Want me to send you a quick video showing exactly what's broken?", }, 'low_rating': { 'hook': "I noticed {business} has a {rating}★ rating with some concerning recent reviews", 'problem': "Anything under 4 stars is actively pushing customers to competitors", 'solution': "I help businesses rebuild their online reputation and respond professionally to negative reviews", 'proof': "Took a Joondalup dentist from 3.2★ to 4.6★ in 90 days with zero fake reviews", 'cta': "Can I share the exact system I use?", }, 'recent_1star': { 'hook': "I saw {business} got {count} one-star reviews in the last month", 'problem': "Unaddressed negative reviews stay on Google forever and scare away new customers", 'solution': "I help business owners respond professionally and turn critics into advocates", 'proof': "One client recovered from 8 bad reviews to 4.8★ rating in 60 days", 'cta': "Want to see the response templates that actually work?", }, 'unclaimed_gmb': { 'hook': "I noticed {business}'s Google Business profile appears unclaimed", 'problem': "Unclaimed profiles can't be optimized, so you're missing out on free local search traffic", 'solution': "I can claim and optimize your profile in 24 hours — it's the easiest SEO win available", 'proof': "Optimized profiles typically see 30-50% more calls within 30 days", 'cta': "Want me to walk you through the process?", }, 'few_reviews': { 'hook': "I noticed {business} only has {count} reviews on Google", 'problem': "Businesses with fewer than 20 reviews are invisible to most customers", 'solution': "I run ethical review generation campaigns that get real customers to leave real reviews", 'proof': "One client went from 12 to 87 reviews in 90 days — all genuine", 'cta': "Want to see the system I use?", }, 'no_contact_form': { 'hook': "I noticed {business}'s website doesn't have a contact form", 'problem': "You're relying 100% on phone calls, which means you're missing 60% of leads who prefer to fill forms", 'solution': "I add smart contact forms that capture leads 24/7 and send instant SMS notifications", 'proof': "Added forms to 15 sites this quarter — average 22 new leads/month per site", 'cta': "Can I mock up what it would look like on your site?", }, 'slow_website': { 'hook': "I tested {business}'s website and it took {load_time} seconds to load", 'problem': "Google's threshold is 3 seconds — anything slower loses 40% of visitors instantly", 'solution': "I optimize websites to load in under 2 seconds without rebuilding them", 'proof': "Average optimization takes 4 hours and improves load time by 60%", 'cta': "Want me to send you a speed report with specific fixes?", }, 'not_mobile_friendly': { 'hook': "I checked {business}'s website on my phone and it's not mobile-friendly", 'problem': "78% of local searches happen on mobile — Google actually hides non-mobile sites from phone users", 'solution': "I make existing websites mobile-friendly without a full rebuild", 'proof': "Mobile optimization typically recovers 30-40% of lost mobile traffic", 'cta': "Want me to show you what your site looks like on a phone right now?", }, } # Service pricing (for context, not mentioned in pitch) SERVICE_PRICING = { 'Lead Generation + Call Tracking': {'setup': '$1,500', 'monthly': '$500/mo'}, 'Website Development': {'setup': '$1,500-$3,000', 'monthly': '$150/mo hosting'}, 'Website Maintenance': {'setup': '$500', 'monthly': '$300/mo'}, 'Reputation Management': {'setup': '$800', 'monthly': '$400/mo'}, 'Review Response Service': {'setup': '$300', 'monthly': '$200/mo'}, 'GMB Optimization': {'setup': '$500', 'monthly': '$150/mo'}, 'Review Generation Campaign': {'setup': '$500', 'monthly': '$300/mo'}, 'Lead Capture Optimization': {'setup': '$600', 'monthly': '$100/mo'}, 'Website Performance': {'setup': '$400', 'monthly': '$0'}, 'Mobile Optimization': {'setup': '$500', 'monthly': '$0'}, } def generate_apex_pitch(lead, pain_data, channel='sms'): """ Generate a personalized apex pitch for a lead. Args: lead: Business data dictionary pain_data: Pain detection results from detect_pain_signals() channel: 'sms', 'email', 'call', or 'gumtree' Returns: Dictionary with pitch components """ logger = get_logger() if not pain_data or not pain_data.get('signals'): return None # Get primary signal (highest pain) signals = pain_data['signals'] primary_key = max(signals.keys(), key=lambda k: signals[k].get('signal_info', {}).get('weight', 0)) primary_signal = signals[primary_key] # Get template template = PITCH_TEMPLATES.get(primary_key) if not template: # Fallback to generic template = { 'hook': f"I noticed {lead.get('name', 'your business')} has some opportunities to improve online presence", 'problem': "These issues are likely costing you customers every day", 'solution': "I help local businesses fix these problems and generate more leads", 'proof': "Working with Perth businesses for 5+ years", 'cta': "Can I show you how?", } # Build context context = { 'business': lead.get('name', 'your business'), 'industry': lead.get('category', 'local'), 'rating': lead.get('rating', 0), 'count': primary_signal.get('count', 1), 'load_time': '', 'issue': '', } # Add website-specific context if 'slow_website' in signals: details = signals['slow_website'].get('details', {}) context['load_time'] = f"{details.get('load_time', 4)}" if 'broken_website' in signals: details = signals['broken_website'].get('details', {}) issues = details.get('issues', []) context['issue'] = issues[0] if issues else "some technical issues" # Fill template try: hook = template['hook'].format(**context) problem = template['problem'].format(**context) solution = template['solution'].format(**context) proof = template['proof'].format(**context) cta = template['cta'].format(**context) except KeyError as e: logger.warning(f"Missing context for pitch template: {e}") hook = f"I've been looking at {lead.get('name', 'your business')} online" problem = template['problem'] solution = template['solution'] proof = template['proof'] cta = template['cta'] # Format for channel if channel == 'sms': # Short, punchy, under 160 chars ideally (but up to 320 OK) pitch = f"{hook}. {cta}" if len(pitch) > 160: pitch = f"{hook[:80]}... {cta}" elif channel == 'email': # Full pitch with all components pitch = f"""Hi, {hook}. {problem}. {solution}. {proof}. {cta} Cheers, Zul Darwisyah Digital Media 0405 022 460""" elif channel == 'call': # Conversational script pitch = f"""OPENING: "Hi, is this {lead.get('name', 'the business')}? This is Zul — I'm a local business owner in Perth. I'll be quick. {hook}. Is that something you've noticed yourself?" PROBE: "How has that been affecting your business?" PITCH: "{solution}. {proof}." CLOSE: "{cta}" OBJECTION HANDLING: - "Not interested": "Totally understand. Can I send you a quick 2-minute video showing what I found? No pressure either way." - "How much?": "Depends on what you need — happy to give you a ballpark if you tell me more about what's not working." - "Send info": "Will do — what's the best email? And quick question — what's your biggest challenge right now with [problem area]?" """ elif channel == 'gumtree': # Casual, local tone pitch = f"""Hi there, I came across {lead.get('name', 'your business')} online and noticed {hook.lower()}. {problem}. I'm Zul, a local Perth guy who helps businesses fix exactly these kinds of issues. {solution}. {proof}. {cta} Happy to chat — no hard sell. Cheers, Zul 0405 022 460""" else: pitch = f"{hook}. {problem}. {solution}. {proof}. {cta}" result = { 'pitch': pitch, 'channel': channel, 'primary_service': pain_data.get('primary_service'), 'pain_score': pain_data.get('pain_score'), 'hook': hook, 'problem': problem, 'solution': solution, 'proof': proof, 'cta': cta, 'pricing': SERVICE_PRICING.get(pain_data.get('primary_service'), {}), } logger.info(f"Generated {channel} pitch for '{lead.get('name')}': pain_score={pain_data.get('pain_score')}") return result def generate_batch_pitches(leads_with_pain, channel='sms'): """ Generate pitches for multiple leads. Args: leads_with_pain: List of (lead, pain_data) tuples channel: Pitch channel Returns: List of pitch dictionaries """ pitches = [] for lead, pain_data in leads_with_pain: if pain_data and pain_data.get('pain_score', 0) > 0: pitch = generate_apex_pitch(lead, pain_data, channel) if pitch: pitches.append({ 'lead': lead, 'pitch': pitch, }) return pitches