""" Enhanced LinkedIn Post Generator Powered by Google Gemini AI Features: - Multiple post formats (Standard, Story, List, Question) - Industry-specific templates - Post analytics predictions - Multiple language support - Batch generation - Advanced customization options Requirements: google-generativeai==0.3.2 gradio==4.20.0 requests==2.31.0 """ import gradio as gr import google.generativeai as genai import os import json import re from datetime import datetime from typing import List, Dict, Tuple, Optional # --- Configuration --- MODEL = "gemini-2.5-flash" SUPPORTED_LANGUAGES = { "English": "en", "Spanish": "es", "French": "fr", "German": "de", "Portuguese": "pt", "Italian": "it", "Dutch": "nl", "Japanese": "ja", "Korean": "ko", "Chinese": "zh" } class EnhancedLinkedInGenerator: def __init__(self, api_key=None): self.api_key = api_key self.model = None if api_key: self.configure_api(api_key) def configure_api(self, api_key: str) -> bool: """Configure Gemini API with provided key""" try: genai.configure(api_key=api_key) self.model = genai.GenerativeModel(MODEL) self.api_key = api_key return True except Exception as e: print(f"API Configuration Error: {e}") return False def extract_response_text(self, response) -> str: """Robust response text extraction for various Gemini API response formats""" try: # Method 1: Simple text accessor (most common) if hasattr(response, 'text') and response.text: return response.text # Method 2: Candidates with parts if hasattr(response, 'candidates') and response.candidates: candidate = response.candidates[0] if hasattr(candidate, 'content') and candidate.content: if hasattr(candidate.content, 'parts') and candidate.content.parts: return candidate.content.parts[0].text # Method 3: Direct parts access if hasattr(response, 'parts') and response.parts: return response.parts[0].text return "❌ Error: Unable to extract text from Gemini response." except Exception as e: return f"❌ Error parsing response: {str(e)}" def get_industry_context(self, industry: str) -> str: """Get industry-specific context and terminology""" industry_contexts = { "Technology": "Use tech terminology, mention innovation, digital transformation, and emerging technologies", "Healthcare": "Focus on patient care, medical advances, healthcare accessibility, and wellness", "Finance": "Emphasize financial literacy, market trends, investment strategies, and economic insights", "Education": "Highlight learning methodologies, educational technology, skill development, and knowledge sharing", "Marketing": "Discuss brand strategies, customer engagement, digital marketing trends, and creative campaigns", "Sales": "Focus on relationship building, sales techniques, customer success, and revenue growth", "HR": "Emphasize talent management, workplace culture, employee engagement, and professional development", "Consulting": "Highlight problem-solving, strategic thinking, client success stories, and industry expertise", "Real Estate": "Focus on market trends, property investment, client relationships, and industry insights", "Retail": "Discuss customer experience, retail innovation, market trends, and brand loyalty", "Manufacturing": "Emphasize operational efficiency, quality control, supply chain, and industrial innovation", "Non-Profit": "Focus on social impact, community engagement, fundraising, and mission-driven work" } return industry_contexts.get(industry, "Use professional language appropriate for your industry") def get_post_template(self, post_format: str, tone: str) -> str: """Get format-specific templates for different post types""" templates = { "Standard": f""" Create a {tone} LinkedIn post with this structure: 1. **Hook** (1-2 sentences): Start with an attention-grabbing statement or question 2. **Body** (2-3 paragraphs): Develop the main points with specific examples 3. **Call to Action**: End with engagement-driving question or action request 4. **Hashtags**: Include 3-5 relevant hashtags at the end """, "Story": f""" Create a {tone} LinkedIn story post with this structure: 1. **Opening** (1 sentence): Set the scene with "Recently..." or "Last week..." 2. **Challenge/Situation** (1-2 sentences): Describe the problem or situation 3. **Action/Solution** (2-3 sentences): What was done to address it 4. **Outcome/Lesson** (1-2 sentences): Results and key takeaway 5. **Question**: Ask readers about their similar experiences 6. **Hashtags**: Include 3-5 relevant hashtags """, "List": f""" Create a {tone} LinkedIn list post with this structure: 1. **Introduction** (1-2 sentences): Introduce the list topic 2. **List Items** (5-7 items): Each with brief explanation • Use bullet points or numbers • Keep each point concise but valuable 3. **Conclusion** (1 sentence): Summarize the value 4. **Engagement**: Ask which point resonates most 5. **Hashtags**: Include 3-5 relevant hashtags """, "Question": f""" Create a {tone} LinkedIn question post with this structure: 1. **Context** (2-3 sentences): Provide background for the question 2. **Main Question** (1 sentence): Clear, thought-provoking question 3. **Sub-questions** (2-3 follow-up questions): Guide the discussion 4. **Your Take** (1-2 sentences): Share your initial thoughts 5. **Call to Participate**: Encourage comments and discussion 6. **Hashtags**: Include 3-5 relevant hashtags """, "Achievement": f""" Create a {tone} LinkedIn achievement post with this structure: 1. **Announcement** (1 sentence): Share the achievement 2. **Journey** (2-3 sentences): Brief story of how you got there 3. **Gratitude** (1-2 sentences): Thank people who helped 4. **Learning** (1-2 sentences): What you learned along the way 5. **Forward Look**: What's next or how others can achieve similar success 6. **Hashtags**: Include 3-5 relevant hashtags """ } return templates.get(post_format, templates["Standard"]) def generate_post(self, topic: str, audience: str, key_points: str, tone: str, post_format: str, industry: str, language: str, api_key: str, include_emoji: bool = True, post_length: str = "Medium") -> str: """Generate enhanced LinkedIn post with advanced options""" # Validate inputs if not all([topic.strip(), audience.strip(), key_points.strip()]): return "❌ Error: Please fill in all required fields (Topic, Audience, Key Points)." if not api_key.strip(): return "❌ Error: Please provide your Gemini API key." # Configure API if not self.configure_api(api_key): return "❌ Error: Invalid API key. Please check your Gemini API key and try again." # Format key points formatted_key_points = "\n".join([f"- {line.strip()}" for line in key_points.split("\n") if line.strip()]) # Get industry context and post template industry_context = self.get_industry_context(industry) post_template = self.get_post_template(post_format, tone) # Determine post length guidance length_guidance = { "Short": "Keep the post concise (100-150 words). Perfect for quick insights.", "Medium": "Create a medium-length post (150-250 words). Balanced detail and readability.", "Long": "Write a comprehensive post (250-400 words). Detailed and informative." } # Build comprehensive prompt prompt = f""" You are an expert LinkedIn content strategist and copywriter with deep understanding of professional social media engagement. **Your Task:** Create a high-quality LinkedIn post based on the specifications below. **Post Specifications:** - **Topic:** {topic} - **Target Audience:** {audience} - **Post Format:** {post_format} - **Tone:** {tone} - **Industry:** {industry} - **Language:** {language} - **Length:** {length_guidance[post_length]} - **Include Emojis:** {include_emoji} **Industry Context:** {industry_context} **Key Points to Include:** {formatted_key_points} **Post Structure Guidelines:** {post_template} **Additional Requirements:** 1. **Professional Quality:** Ensure content is polished and error-free 2. **Engagement Optimization:** Use techniques that encourage likes, comments, and shares 3. **Value-First:** Every sentence should provide value to the reader 4. **Authenticity:** Make it sound natural and genuine, not overly promotional 5. **Visual Appeal:** {"Use relevant emojis strategically to enhance readability" if include_emoji else "Do not use emojis"} 6. **Language:** Write entirely in {language} 7. **Hashtag Strategy:** Choose hashtags that are popular but not oversaturated **Engagement Best Practices:** - Start with a hook that makes people want to read more - Use short paragraphs for better mobile readability - Include specific examples or data when possible - End with a question or call-to-action that encourages responses - Make it scannable with bullet points or line breaks Generate the complete LinkedIn post now: """ try: # Generate the post response = self.model.generate_content( prompt, generation_config=genai.types.GenerationConfig( temperature=0.7, top_p=0.9, max_output_tokens=1500, ) ) # Extract response text post_content = self.extract_response_text(response) if post_content.startswith("❌"): return post_content # Add metadata metadata = f""" **Post Analytics Prediction:** - **Estimated Reach:** {self.predict_reach(topic, audience, tone)} - **Best Posting Time:** {self.suggest_posting_time(audience)} - **Engagement Potential:** {self.predict_engagement(post_format, tone)} --- *Generated on {datetime.now().strftime("%Y-%m-%d at %H:%M")} using Enhanced LinkedIn Post Generator* """ return f"{post_content}\n\n{metadata}" except Exception as e: return f"❌ Error generating post: {str(e)}" def predict_reach(self, topic: str, audience: str, tone: str) -> str: """Predict potential reach based on topic and audience""" # Simplified prediction logic if "AI" in topic or "technology" in topic.lower(): return "High (5,000-15,000 impressions)" elif "business" in topic.lower() or "leadership" in topic.lower(): return "Medium-High (3,000-10,000 impressions)" else: return "Medium (1,000-5,000 impressions)" def suggest_posting_time(self, audience: str) -> str: """Suggest optimal posting times based on audience""" if "executive" in audience.lower() or "ceo" in audience.lower(): return "Tuesday-Thursday, 8-9 AM or 12-1 PM" elif "developer" in audience.lower() or "engineer" in audience.lower(): return "Tuesday-Wednesday, 9-10 AM or 2-3 PM" else: return "Tuesday-Thursday, 9 AM-12 PM" def predict_engagement(self, post_format: str, tone: str) -> str: """Predict engagement potential""" engagement_scores = { "Question": "High", "Story": "High", "List": "Medium-High", "Standard": "Medium", "Achievement": "Medium" } return f"{engagement_scores.get(post_format, 'Medium')} engagement expected" def generate_multiple_posts(self, topic: str, audience: str, key_points: str, api_key: str, count: int = 3) -> str: """Generate multiple post variations""" formats = ["Standard", "Story", "Question"] tones = ["Professional", "Inspirational", "Conversational"] results = [] for i in range(min(count, 3)): post = self.generate_post( topic=topic, audience=audience, key_points=key_points, tone=tones[i], post_format=formats[i], industry="Technology", language="English", api_key=api_key, include_emoji=True, post_length="Medium" ) results.append(f"**Variation {i+1} ({formats[i]} - {tones[i]}):**\n{post}\n\n{'='*50}\n") return "\n".join(results) # Initialize generator generator = EnhancedLinkedInGenerator() def save_post_to_file(post_content: str, topic: str) -> str: """Save generated post to downloadable file""" if not post_content or post_content.startswith("❌"): return None timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"linkedin_post_{topic.replace(' ', '_')}_{timestamp}.txt" with open(filename, 'w', encoding='utf-8') as f: f.write(post_content) return filename # Create the enhanced Gradio interface with gr.Blocks( theme=gr.themes.Soft(), title="Enhanced LinkedIn Post Generator - Powered by Google Gemini AI", css=""" .main-header { text-align: center; margin-bottom: 2rem; } .feature-box { background: linear-gradient(45deg, #667eea, #764ba2); padding: 1rem; border-radius: 8px; color: white; margin: 1rem 0; } .pro-tip { background: #f0f9ff; padding: 1rem; border-left: 4px solid #3b82f6; margin: 1rem 0; } """ ) as demo: # Header gr.Markdown("""

🚀 Enhanced LinkedIn Post Generator

Powered by Google Gemini AI

Create professional, engaging LinkedIn content with advanced AI assistance

""", elem_classes=["main-header"]) # Feature highlights gr.Markdown("""

✨ Advanced Features

""", elem_classes=["feature-box"]) with gr.Tabs(): # Single Post Generation Tab with gr.TabItem("📝 Generate Single Post"): with gr.Row(): with gr.Column(scale=2): gr.Markdown("## 🔑 API Configuration") api_key_input = gr.Textbox( label="Gemini API Key", placeholder="Enter your Google Gemini API key", type="password", info="Get your free API key from: https://aistudio.google.com/app/apikey" ) gr.Markdown("## 📋 Basic Information") topic_input = gr.Textbox( label="Post Topic *", placeholder="e.g., 'The Future of Remote Work', 'AI in Healthcare', 'Leadership Lessons'", lines=1 ) audience_input = gr.Textbox( label="Target Audience *", placeholder="e.g., 'Software Engineers and Tech Leaders', 'Healthcare Professionals', 'Marketing Executives'", lines=2 ) key_points_input = gr.Textbox( label="Key Points to Cover *", placeholder="Enter one key point per line:\n- Main insight or benefit\n- Supporting evidence or example\n- Personal experience or tip\n- Future implications or next steps", lines=6 ) gr.Markdown("## 🎨 Customization Options") with gr.Row(): tone_input = gr.Dropdown( label="Tone of Voice", choices=[ "Professional", "Inspirational", "Conversational", "Thought-provoking", "Educational", "Enthusiastic", "Analytical", "Motivational", "Friendly", "Authoritative" ], value="Professional" ) post_format_input = gr.Dropdown( label="Post Format", choices=["Standard", "Story", "List", "Question", "Achievement"], value="Standard", info="Choose the structure that best fits your content" ) with gr.Row(): industry_input = gr.Dropdown( label="Industry", choices=[ "Technology", "Healthcare", "Finance", "Education", "Marketing", "Sales", "HR", "Consulting", "Real Estate", "Retail", "Manufacturing", "Non-Profit" ], value="Technology" ) language_input = gr.Dropdown( label="Language", choices=list(SUPPORTED_LANGUAGES.keys()), value="English" ) with gr.Row(): post_length_input = gr.Dropdown( label="Post Length", choices=["Short", "Medium", "Long"], value="Medium", info="Short: 100-150 words, Medium: 150-250 words, Long: 250-400 words" ) include_emoji_input = gr.Checkbox( label="Include Emojis", value=True, info="Add emojis to enhance readability and engagement" ) generate_button = gr.Button( "🚀 Generate LinkedIn Post", variant="primary", size="lg" ) with gr.Column(scale=3): gr.Markdown("## 📊 Generated Content") output_post = gr.Markdown( label="Your LinkedIn Post", value="Your AI-generated LinkedIn post will appear here...", show_copy_button=True ) with gr.Row(): download_btn = gr.DownloadButton( "💾 Download Post", size="sm", variant="secondary", visible=False ) regenerate_btn = gr.Button( "🔄 Regenerate with Same Settings", size="sm", variant="secondary" ) # Batch Generation Tab with gr.TabItem("🔄 Generate Multiple Variations"): with gr.Row(): with gr.Column(scale=1): gr.Markdown("## 📝 Batch Generation") gr.Markdown("Generate 3 different variations of your post with different formats and tones.") batch_api_key = gr.Textbox( label="Gemini API Key", placeholder="Enter your Google Gemini API key", type="password" ) batch_topic = gr.Textbox( label="Post Topic", placeholder="e.g., 'Digital Transformation in Healthcare'" ) batch_audience = gr.Textbox( label="Target Audience", placeholder="e.g., 'Healthcare IT Directors and Medical Professionals'", lines=2 ) batch_key_points = gr.Textbox( label="Key Points", placeholder="Enter key points, one per line", lines=5 ) batch_generate_btn = gr.Button( "🎯 Generate 3 Variations", variant="primary" ) with gr.Column(scale=2): batch_output = gr.Markdown( label="Post Variations", value="Multiple post variations will appear here...", show_copy_button=True ) # Pro Tips Section gr.Markdown("""

💡 Pro Tips for Better LinkedIn Posts

""", elem_classes=["pro-tip"]) # Footer gr.Markdown(""" --- ### 🔗 Getting Started 1. **Get Your API Key:** Visit [Google AI Studio](https://aistudio.google.com/app/apikey) to get your free Gemini API key 2. **Choose Your Format:** Select the post format that best matches your content type 3. **Customize Settings:** Adjust tone, industry, and length to match your brand voice 4. **Generate & Refine:** Create your post and use the regenerate button for variations **API Usage:** Each post generation uses ~1,000-1,500 tokens. The free tier includes 60 requests per minute. *Built with ❤️ using Google Gemini AI and Gradio* """) # Event handlers def generate_and_prepare_download(topic, audience, key_points, tone, post_format, industry, language, post_length, include_emoji, api_key): # Generate post post = generator.generate_post( topic=topic, audience=audience, key_points=key_points, tone=tone, post_format=post_format, industry=industry, language=language, api_key=api_key, include_emoji=include_emoji, post_length=post_length ) # Prepare download if not post.startswith("❌") and topic.strip(): filename = save_post_to_file(post, topic) return post, gr.DownloadButton("💾 Download Post", value=filename, visible=True) else: return post, gr.DownloadButton("💾 Download Post", visible=False) def generate_batch_posts(topic, audience, key_points, api_key): if not api_key.strip(): return "❌ Error: Please provide your Gemini API key." return generator.generate_multiple_posts(topic, audience, key_points, api_key, 3) # Connect event handlers generate_button.click( fn=generate_and_prepare_download, inputs=[topic_input, audience_input, key_points_input, tone_input, post_format_input, industry_input, language_input, post_length_input, include_emoji_input, api_key_input], outputs=[output_post, download_btn] ) regenerate_btn.click( fn=generate_and_prepare_download, inputs=[topic_input, audience_input, key_points_input, tone_input, post_format_input, industry_input, language_input, post_length_input, include_emoji_input, api_key_input], outputs=[output_post, download_btn] ) batch_generate_btn.click( fn=generate_batch_posts, inputs=[batch_topic, batch_audience, batch_key_points, batch_api_key], outputs=[batch_output] ) # Launch configuration if __name__ == "__main__": print("🚀 Launching Enhanced LinkedIn Post Generator...") print("✨ Powered by Google Gemini AI") print("🌟 Advanced Features Enabled") print("🔑 Get your API key: https://aistudio.google.com/app/apikey") print() # Cloud-friendly launch (FIXED) demo.launch( server_name="0.0.0.0", server_port=7860, share=False, show_error=True )