ALwrity Prompts - AI Integration Plan
This commit is contained in:
@@ -1,358 +0,0 @@
|
||||
"""
|
||||
Facebook AI Writer
|
||||
|
||||
This module provides a comprehensive suite of tools for generating Facebook content.
|
||||
"""
|
||||
|
||||
import time
|
||||
import os
|
||||
import json
|
||||
import requests
|
||||
import streamlit as st
|
||||
import importlib
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Union
|
||||
|
||||
from ...gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from .modules.post_generator import write_fb_post
|
||||
from .modules.story_generator import write_fb_story
|
||||
from .modules.facebook_reel.reel_generator import write_fb_reel
|
||||
from .modules.facebook_carousel.carousel_generator import write_fb_carousel
|
||||
from .modules.event_generator import write_fb_event
|
||||
from .modules.hashtag_generator import write_fb_hashtags
|
||||
from .modules.engagement_analyzer import analyze_fb_engagement
|
||||
from .modules.group_post_generator import write_fb_group_post
|
||||
from .modules.page_about_generator import write_fb_page_about
|
||||
from .modules.ad_copy_generator import write_fb_ad_copy
|
||||
|
||||
#from streamlit_quill import st_quill
|
||||
|
||||
|
||||
def generate_facebook_post(business_type, target_audience, post_goal, post_tone, include, avoid):
|
||||
"""
|
||||
Generates a Facebook post prompt for an LLM based on user input.
|
||||
"""
|
||||
prompt = f"""
|
||||
I am a {business_type} looking to engage my target audience, {target_audience}, on Facebook.
|
||||
|
||||
My goal for this detailed post is: {post_goal}. The tone should be {post_tone}.
|
||||
|
||||
Here are some additional preferences:
|
||||
- **Include:** {include}
|
||||
- **Avoid:** {avoid}
|
||||
|
||||
Please write a well-structured Facebook post with:
|
||||
1. A **catchy opening** to grab attention.
|
||||
2. Detailed **Engaging content** that highlights key benefits or features.
|
||||
3. A **strong call-to-action** (CTA) encouraging my audience to take action.
|
||||
4. If applicable, suggest **multimedia** (images, videos, etc.).
|
||||
5. Include **relevant hashtags** for visibility.
|
||||
|
||||
"""
|
||||
try:
|
||||
response = llm_text_gen(prompt)
|
||||
return response
|
||||
except Exception as err:
|
||||
st.error(f"An error occurred while generating the prompt: {err}")
|
||||
return None
|
||||
|
||||
|
||||
def facebook_main_menu():
|
||||
"""Main function for the Facebook AI Writer."""
|
||||
|
||||
# Initialize session state for selected tool if it doesn't exist
|
||||
if "selected_tool" not in st.session_state:
|
||||
st.session_state.selected_tool = None
|
||||
|
||||
# Define the Facebook tools with their details
|
||||
facebook_tools = [
|
||||
# Content Creation Tools
|
||||
{
|
||||
"name": "FB Post Generator",
|
||||
"icon": "📝",
|
||||
"description": "Create engaging Facebook posts that drive engagement and reach.",
|
||||
"color": "#1877F2", # Facebook blue
|
||||
"category": "Content Creation",
|
||||
"function": write_fb_post,
|
||||
"status": "active"
|
||||
},
|
||||
{
|
||||
"name": "FB Story Generator",
|
||||
"icon": "📱",
|
||||
"description": "Generate creative Facebook Stories with text overlays and engagement elements.",
|
||||
"color": "#1877F2",
|
||||
"category": "Content Creation",
|
||||
"function": write_fb_story,
|
||||
"status": "active"
|
||||
},
|
||||
{
|
||||
"name": "FB Reel Generator",
|
||||
"icon": "🎥",
|
||||
"description": "Create engaging Facebook Reels scripts with trending music suggestions.",
|
||||
"color": "#1877F2",
|
||||
"category": "Content Creation",
|
||||
"function": write_fb_reel,
|
||||
"status": "active"
|
||||
},
|
||||
{
|
||||
"name": "Carousel Generator",
|
||||
"icon": "🔄",
|
||||
"description": "Generate multi-image carousel posts with engaging captions for each slide.",
|
||||
"color": "#1877F2",
|
||||
"category": "Content Creation",
|
||||
"function": write_fb_carousel,
|
||||
"status": "active"
|
||||
},
|
||||
|
||||
# Business Tools
|
||||
{
|
||||
"name": "Event Description Generator",
|
||||
"icon": "📅",
|
||||
"description": "Create compelling event descriptions that drive attendance and engagement.",
|
||||
"color": "#1877F2",
|
||||
"category": "Business Tools",
|
||||
"function": write_fb_event,
|
||||
"status": "active"
|
||||
},
|
||||
{
|
||||
"name": "Group Post Generator",
|
||||
"icon": "👥",
|
||||
"description": "Generate engaging posts for Facebook Groups with community-focused content.",
|
||||
"color": "#1877F2",
|
||||
"category": "Business Tools",
|
||||
"function": write_fb_group_post,
|
||||
"status": "active"
|
||||
},
|
||||
{
|
||||
"name": "Page About Generator",
|
||||
"icon": "ℹ️",
|
||||
"description": "Create professional and engaging About sections for your Facebook Page.",
|
||||
"color": "#1877F2",
|
||||
"category": "Business Tools",
|
||||
"function": write_fb_page_about,
|
||||
"status": "active"
|
||||
},
|
||||
|
||||
# Marketing Tools
|
||||
{
|
||||
"name": "Ad Copy Generator",
|
||||
"icon": "💰",
|
||||
"description": "Generate high-converting ad copy for Facebook Ads with targeting suggestions.",
|
||||
"color": "#1877F2",
|
||||
"category": "Marketing Tools",
|
||||
"function": write_fb_ad_copy,
|
||||
"status": "active"
|
||||
},
|
||||
{
|
||||
"name": "Hashtag Generator",
|
||||
"icon": "#️⃣",
|
||||
"description": "Generate trending and relevant hashtags for your Facebook content.",
|
||||
"color": "#1877F2",
|
||||
"category": "Marketing Tools",
|
||||
"function": write_fb_hashtags,
|
||||
"status": "active"
|
||||
},
|
||||
{
|
||||
"name": "Engagement Analyzer",
|
||||
"icon": "📊",
|
||||
"description": "Analyze your content performance and get AI-powered improvement suggestions.",
|
||||
"color": "#1877F2",
|
||||
"category": "Marketing Tools",
|
||||
"function": analyze_fb_engagement,
|
||||
"status": "active"
|
||||
},
|
||||
|
||||
# Future Tools
|
||||
{
|
||||
"name": "Content Calendar",
|
||||
"icon": "📅",
|
||||
"description": "Plan and organize your Facebook content with AI-powered scheduling suggestions.",
|
||||
"color": "#1877F2",
|
||||
"category": "Future Tools",
|
||||
"function": None,
|
||||
"status": "future"
|
||||
},
|
||||
{
|
||||
"name": "Live Stream Script",
|
||||
"icon": "🎥",
|
||||
"description": "Generate engaging scripts for Facebook Live streams with audience interaction points.",
|
||||
"color": "#1877F2",
|
||||
"category": "Future Tools",
|
||||
"function": None,
|
||||
"status": "future"
|
||||
}
|
||||
]
|
||||
|
||||
# Create a container for the dashboard
|
||||
dashboard_container = st.container()
|
||||
|
||||
# Create a container for the tool input section
|
||||
tool_container = st.container()
|
||||
|
||||
# If a tool is selected, show its input section
|
||||
if st.session_state.selected_tool is not None:
|
||||
with tool_container:
|
||||
# Add a back button at the top
|
||||
if st.button("← Back to Dashboard", key="back_to_facebook_dashboard"):
|
||||
st.session_state.selected_tool = None
|
||||
st.rerun()
|
||||
|
||||
# Display the tool header with card layout
|
||||
st.markdown(f"""
|
||||
<div style='
|
||||
background: linear-gradient(145deg, #ffffff 0%, #f0f7ff 50%, #e6f0ff 100%);
|
||||
padding: 2.5rem;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 10px 25px rgba(24, 119, 242, 0.08);
|
||||
margin: 1rem 0 2.5rem 0;
|
||||
border: 1px solid rgba(24, 119, 242, 0.1);
|
||||
'>
|
||||
<div style='
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1.2rem;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
padding: 1rem 1.5rem;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 15px rgba(24, 119, 242, 0.05);
|
||||
'>
|
||||
<div style='
|
||||
font-size: 2.5rem;
|
||||
margin-right: 1rem;
|
||||
color: #1877F2;
|
||||
'>{st.session_state.selected_tool['icon']}</div>
|
||||
<div>
|
||||
<h1 style='
|
||||
margin: 0;
|
||||
color: #1877F2;
|
||||
font-size: 2.2rem;
|
||||
font-weight: 600;
|
||||
'>{st.session_state.selected_tool['name']}</h1>
|
||||
<p style='
|
||||
color: #666;
|
||||
margin: 0.5rem 0 0 0;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.5;
|
||||
'>{st.session_state.selected_tool['description']}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Call the function for the selected tool
|
||||
if st.session_state.selected_tool["function"]:
|
||||
st.session_state.selected_tool["function"]()
|
||||
else:
|
||||
# Display coming soon or future tool information
|
||||
st.info(f"**{st.session_state.selected_tool['status'].replace('_', ' ').title()}!**")
|
||||
st.write(st.session_state.selected_tool["description"])
|
||||
st.image(f"https://via.placeholder.com/600x300?text={st.session_state.selected_tool['name']}+Coming+Soon", use_container_width=True)
|
||||
else:
|
||||
with dashboard_container:
|
||||
# Display the dashboard
|
||||
# Header
|
||||
st.markdown("""
|
||||
<div style='background-color: #f0f2f6; padding: 10px; border-radius: 5px; margin-bottom: 10px;'>
|
||||
<h1 style='color: #1877F2; text-align: center;'>📱 Facebook AI Writer</h1>
|
||||
<p style='text-align: center;'>Generate professional Facebook content with ALwrity's AI-powered tools</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Group tools by category
|
||||
categories = {}
|
||||
for tool in facebook_tools:
|
||||
category = tool["category"]
|
||||
if category not in categories:
|
||||
categories[category] = []
|
||||
categories[category].append(tool)
|
||||
|
||||
# Display tools by category
|
||||
for category, tools in categories.items():
|
||||
st.markdown(f"## {category}")
|
||||
|
||||
# Create a 3-column layout for the tool cards
|
||||
cols = st.columns(3)
|
||||
|
||||
# Display the tool cards
|
||||
for i, tool in enumerate(tools):
|
||||
# Determine which column to use
|
||||
col = cols[i % 3]
|
||||
|
||||
with col:
|
||||
# Create a card for each tool
|
||||
status_badge = ""
|
||||
if tool["status"] == "coming_soon":
|
||||
status_badge = "<span style='background-color: #FFA500; color: white; padding: 2px 8px; border-radius: 10px; font-size: 0.8em;'>Coming Soon</span>"
|
||||
elif tool["status"] == "future":
|
||||
status_badge = "<span style='background-color: #808080; color: white; padding: 2px 8px; border-radius: 10px; font-size: 0.8em;'>Future</span>"
|
||||
|
||||
st.markdown(f"""
|
||||
<div style='background-color: {tool["color"]}; padding: 20px; border-radius: 10px; margin-bottom: 20px; color: white;'>
|
||||
<h2 style='color: white;'>{tool["icon"]} {tool["name"]} {status_badge}</h2>
|
||||
<p>{tool["description"]}</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Add a button to access the tool
|
||||
if st.button(f"Use {tool['name']}", key=f"btn_{tool['name']}"):
|
||||
# Store the selected tool in session state
|
||||
st.session_state.selected_tool = tool
|
||||
st.rerun()
|
||||
|
||||
|
||||
class FacebookAIWriter:
|
||||
"""
|
||||
AI-powered content generator for Facebook marketing and communication.
|
||||
|
||||
This class provides various tools for generating Facebook content including:
|
||||
- Posts and updates
|
||||
- Page About sections
|
||||
- Event descriptions
|
||||
- Ad copy
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the Facebook AI Writer."""
|
||||
pass
|
||||
|
||||
def generate_post(self, **kwargs) -> str:
|
||||
"""Generate a Facebook post."""
|
||||
return write_fb_post(**kwargs)
|
||||
|
||||
def generate_page_about(self, **kwargs) -> str:
|
||||
"""Generate a Facebook Page About section."""
|
||||
return write_fb_page_about(**kwargs)
|
||||
|
||||
def generate_event(self, **kwargs) -> str:
|
||||
"""Generate a Facebook Event description."""
|
||||
return write_fb_event(**kwargs)
|
||||
|
||||
def generate_ad_copy(self, **kwargs) -> Dict[str, Union[str, List[str]]]:
|
||||
"""
|
||||
Generate Facebook Ad copy with variations.
|
||||
|
||||
Returns:
|
||||
Dict containing the generated ad copy and its variations.
|
||||
"""
|
||||
return write_fb_ad_copy(**kwargs)
|
||||
|
||||
# List of available tools
|
||||
AVAILABLE_TOOLS = [
|
||||
'Post Generator',
|
||||
'Page About Generator',
|
||||
'Event Generator',
|
||||
'Ad Copy Generator'
|
||||
]
|
||||
|
||||
# Coming soon features
|
||||
COMING_SOON = [
|
||||
'Story Generator',
|
||||
'Poll Generator',
|
||||
'Group Post Generator',
|
||||
'Carousel Post Generator',
|
||||
'Comment Response Generator'
|
||||
]
|
||||
|
||||
if __name__ == "__main__":
|
||||
facebook_main_menu()
|
||||
@@ -1,142 +0,0 @@
|
||||
# Facebook Ad Copy Generator
|
||||
|
||||
## Overview
|
||||
The Facebook Ad Copy Generator is a powerful tool designed to help marketers and businesses create high-converting ad copy for Facebook Ads. It provides a comprehensive interface for crafting compelling ad content with targeting suggestions and performance optimization features.
|
||||
|
||||
## Features
|
||||
|
||||
### Ad Objective & Format
|
||||
- **Ad Objectives**: Choose from Awareness, Traffic, Engagement, Leads, App Promotion, Sales, Conversions
|
||||
- **Ad Formats**: Single Image, Carousel, Video, Collection, Instant Experience
|
||||
- **Campaign Setup**: Name, budget range, and placement options
|
||||
- **Format Preview**: Visual examples of each ad format
|
||||
|
||||
### Target Audience
|
||||
- **Demographics**: Age, gender, location targeting
|
||||
- **Interest Targeting**: Interest-based audience selection
|
||||
- **Behavior Targeting**: User behavior and activity-based targeting
|
||||
- **Custom Audiences**: Upload and manage custom audience lists
|
||||
- **Lookalike Audiences**: Create similar audience profiles
|
||||
|
||||
### Ad Content
|
||||
- **Headlines**: Primary and secondary headline options
|
||||
- **Description**: Main ad copy with character limits
|
||||
- **Link Description**: URL preview text optimization
|
||||
- **Brand Voice**: Tone and style customization
|
||||
- **Key Points**: Highlight main benefits and features
|
||||
- **USP**: Unique selling proposition emphasis
|
||||
|
||||
### Call-to-Action
|
||||
- **CTA Buttons**: Various pre-defined CTA options
|
||||
- **Custom CTAs**: Create personalized call-to-actions
|
||||
- **Urgency Elements**: Time-sensitive offer integration
|
||||
- **Offer Details**: Special promotion formatting
|
||||
|
||||
### Preview & Export
|
||||
- **Live Preview**: See how your ad will appear
|
||||
- **Mobile/Desktop**: View across different devices
|
||||
- **A/B Testing**: Generate multiple variations
|
||||
- **Export Options**: Various format support
|
||||
|
||||
## How to Use
|
||||
|
||||
1. **Access the Generator**
|
||||
- Navigate to the Ad Copy Generator in the AI Writer dashboard
|
||||
- Select "Create New Ad" to start
|
||||
|
||||
2. **Configure Ad Settings**
|
||||
- Choose your objective and format
|
||||
- Set up campaign details
|
||||
- Select ad placements
|
||||
|
||||
3. **Define Target Audience**
|
||||
- Set demographic parameters
|
||||
- Choose interests and behaviors
|
||||
- Configure custom audiences
|
||||
|
||||
4. **Create Ad Content**
|
||||
- Write or generate headlines
|
||||
- Craft main ad copy
|
||||
- Add call-to-action
|
||||
- Preview and adjust
|
||||
|
||||
5. **Export and Test**
|
||||
- Preview across devices
|
||||
- Generate variations
|
||||
- Export final copy
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Ad Copy Creation
|
||||
- Keep copy clear and concise
|
||||
- Focus on benefits over features
|
||||
- Use strong call-to-actions
|
||||
- Include social proof
|
||||
- Maintain brand voice
|
||||
|
||||
### Targeting
|
||||
- Define specific audience segments
|
||||
- Use relevant interests
|
||||
- Leverage custom audiences
|
||||
- Test different combinations
|
||||
- Monitor performance
|
||||
|
||||
### Format Selection
|
||||
- Match format to objective
|
||||
- Optimize for placements
|
||||
- Use high-quality visuals
|
||||
- Follow Facebook guidelines
|
||||
- Test multiple formats
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
- Python 3.7+
|
||||
- Streamlit
|
||||
- Required Python packages:
|
||||
- streamlit
|
||||
- typing
|
||||
- datetime
|
||||
- json
|
||||
- logging
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
1. **Content Generation Fails**
|
||||
- Check internet connection
|
||||
- Verify input parameters
|
||||
- Try reducing complexity
|
||||
|
||||
2. **Preview Issues**
|
||||
- Clear cache
|
||||
- Check format compatibility
|
||||
- Verify character limits
|
||||
|
||||
3. **Export Problems**
|
||||
- Check file permissions
|
||||
- Verify format support
|
||||
- Ensure valid content
|
||||
|
||||
## Future Updates
|
||||
|
||||
- Enhanced AI copy suggestions
|
||||
- Advanced audience insights
|
||||
- Performance prediction
|
||||
- Multi-language support
|
||||
- Dynamic content optimization
|
||||
- Automated A/B testing
|
||||
- ROI calculator
|
||||
- Campaign scheduling
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions to improve the Facebook Ad Copy Generator. Please follow these steps:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
This module is licensed under the MIT License. See the LICENSE file for details.
|
||||
@@ -1,11 +0,0 @@
|
||||
"""
|
||||
Facebook Ad Copy Generator Module
|
||||
|
||||
This module provides functionality to generate high-converting ad copy for Facebook Ads.
|
||||
It helps marketers create compelling ad content with targeting suggestions and
|
||||
performance optimization features.
|
||||
"""
|
||||
|
||||
from .ad_copy_generator import write_fb_ad_copy
|
||||
|
||||
__all__ = ['write_fb_ad_copy']
|
||||
@@ -1,673 +0,0 @@
|
||||
"""
|
||||
Facebook Ad Copy Generator Module
|
||||
|
||||
This module provides functionality to generate high-converting ad copy for Facebook Ads.
|
||||
It helps marketers create compelling ad content with targeting suggestions and
|
||||
performance optimization features.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Optional, Union, Tuple
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
|
||||
# Set up logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def write_fb_ad_copy():
|
||||
"""
|
||||
Generate Facebook Ad copy with various customization options.
|
||||
|
||||
This function provides a comprehensive interface for creating high-converting
|
||||
ad copy for Facebook Ads with features like:
|
||||
- Ad objective and format selection
|
||||
- Target audience configuration
|
||||
- Ad content customization
|
||||
- Call-to-action optimization
|
||||
- Preview and export options
|
||||
"""
|
||||
|
||||
st.title("Facebook Ad Copy Generator")
|
||||
st.markdown("""
|
||||
Create high-converting ad copy for your Facebook Ads with AI-powered suggestions
|
||||
and targeting recommendations.
|
||||
""")
|
||||
|
||||
# Initialize session state for form data
|
||||
if 'ad_copy_data' not in st.session_state:
|
||||
st.session_state.ad_copy_data = {
|
||||
# Ad Objective & Format
|
||||
'objective': 'awareness',
|
||||
'format': 'single_image',
|
||||
'campaign_name': '',
|
||||
'budget_range': (100, 1000),
|
||||
'placements': ['feed'],
|
||||
|
||||
# Target Audience
|
||||
'age_range': (18, 65),
|
||||
'gender': 'all',
|
||||
'location': '',
|
||||
'interests': [],
|
||||
'behaviors': [],
|
||||
'custom_audience': '',
|
||||
'lookalike_source': '',
|
||||
|
||||
# Ad Content
|
||||
'primary_headline': '',
|
||||
'secondary_headline': '',
|
||||
'description': '',
|
||||
'link_description': '',
|
||||
'brand_voice': 'professional',
|
||||
'key_points': [],
|
||||
'usp': '',
|
||||
|
||||
# Call-to-Action
|
||||
'cta_type': 'learn_more',
|
||||
'cta_text': '',
|
||||
'use_urgency': False,
|
||||
'offer_details': '',
|
||||
|
||||
# Content Length
|
||||
'content_length': 'standard',
|
||||
|
||||
# Generated Content
|
||||
'generated_content': '',
|
||||
'show_preview': False,
|
||||
'variations': []
|
||||
}
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3, tab4, tab5 = st.tabs([
|
||||
"Ad Objective & Format",
|
||||
"Target Audience",
|
||||
"Ad Content",
|
||||
"Call-to-Action",
|
||||
"Preview & Export"
|
||||
])
|
||||
|
||||
with tab1:
|
||||
render_objective_format_tab()
|
||||
|
||||
with tab2:
|
||||
render_target_audience_tab()
|
||||
|
||||
with tab3:
|
||||
render_ad_content_tab()
|
||||
|
||||
with tab4:
|
||||
render_cta_tab()
|
||||
|
||||
with tab5:
|
||||
render_preview_export_tab()
|
||||
|
||||
# Generate button
|
||||
if st.button("Generate Ad Copy", type="primary"):
|
||||
if validate_ad_copy_fields():
|
||||
with st.spinner("Generating your ad copy..."):
|
||||
ad_content = generate_ad_copy()
|
||||
if ad_content:
|
||||
st.session_state.ad_copy_data['generated_content'] = ad_content
|
||||
st.success("Ad copy generated successfully!")
|
||||
st.session_state.ad_copy_data['show_preview'] = True
|
||||
# Generate variations for A/B testing
|
||||
variations = generate_ad_variations()
|
||||
if variations:
|
||||
st.session_state.ad_copy_data['variations'] = variations
|
||||
st.rerun()
|
||||
|
||||
def render_objective_format_tab():
|
||||
"""Render the ad objective and format selection fields."""
|
||||
|
||||
st.header("Ad Objective & Format")
|
||||
|
||||
# Ad Objective
|
||||
objective = st.selectbox(
|
||||
"Ad Objective",
|
||||
options=['awareness', 'traffic', 'engagement', 'leads', 'app_promotion', 'sales', 'conversions'],
|
||||
index=['awareness', 'traffic', 'engagement', 'leads', 'app_promotion', 'sales', 'conversions'].index(
|
||||
st.session_state.ad_copy_data['objective']
|
||||
),
|
||||
help="Choose the main objective of your ad campaign"
|
||||
)
|
||||
st.session_state.ad_copy_data['objective'] = objective
|
||||
|
||||
# Ad Format
|
||||
format_col1, format_col2 = st.columns(2)
|
||||
|
||||
with format_col1:
|
||||
ad_format = st.selectbox(
|
||||
"Ad Format",
|
||||
options=['single_image', 'carousel', 'video', 'collection', 'instant_experience'],
|
||||
index=['single_image', 'carousel', 'video', 'collection', 'instant_experience'].index(
|
||||
st.session_state.ad_copy_data['format']
|
||||
),
|
||||
help="Choose the format of your ad"
|
||||
)
|
||||
st.session_state.ad_copy_data['format'] = ad_format
|
||||
|
||||
with format_col2:
|
||||
# Show format preview
|
||||
st.image(
|
||||
f"https://via.placeholder.com/600x300?text={ad_format.replace('_', ' ').title()}+Coming+Soon",
|
||||
caption=f"{ad_format.replace('_', ' ').title()} Format Example",
|
||||
use_container_width=True
|
||||
)
|
||||
|
||||
# Campaign Setup
|
||||
st.subheader("Campaign Setup")
|
||||
|
||||
campaign_name = st.text_input(
|
||||
"Campaign Name",
|
||||
value=st.session_state.ad_copy_data['campaign_name'],
|
||||
help="Enter a name for your ad campaign"
|
||||
)
|
||||
st.session_state.ad_copy_data['campaign_name'] = campaign_name
|
||||
|
||||
# Budget Range
|
||||
budget_range = st.slider(
|
||||
"Budget Range ($)",
|
||||
min_value=1,
|
||||
max_value=10000,
|
||||
value=st.session_state.ad_copy_data['budget_range'],
|
||||
help="Set your campaign budget range"
|
||||
)
|
||||
st.session_state.ad_copy_data['budget_range'] = budget_range
|
||||
|
||||
# Ad Placements
|
||||
placement_options = [
|
||||
'feed', 'stories', 'messenger', 'marketplace', 'video_feeds',
|
||||
'in_stream', 'search', 'instagram', 'audience_network'
|
||||
]
|
||||
|
||||
placements = st.multiselect(
|
||||
"Ad Placements",
|
||||
options=placement_options,
|
||||
default=st.session_state.ad_copy_data['placements'],
|
||||
help="Choose where your ad will appear"
|
||||
)
|
||||
st.session_state.ad_copy_data['placements'] = placements
|
||||
|
||||
def render_target_audience_tab():
|
||||
"""Render the target audience configuration fields."""
|
||||
|
||||
st.header("Target Audience")
|
||||
|
||||
# Demographics
|
||||
st.subheader("Demographics")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
age_range = st.slider(
|
||||
"Age Range",
|
||||
min_value=13,
|
||||
max_value=65,
|
||||
value=st.session_state.ad_copy_data['age_range'],
|
||||
help="Select target age range"
|
||||
)
|
||||
st.session_state.ad_copy_data['age_range'] = age_range
|
||||
|
||||
with col2:
|
||||
gender = st.selectbox(
|
||||
"Gender",
|
||||
options=['all', 'male', 'female'],
|
||||
index=['all', 'male', 'female'].index(
|
||||
st.session_state.ad_copy_data['gender']
|
||||
),
|
||||
help="Select target gender"
|
||||
)
|
||||
st.session_state.ad_copy_data['gender'] = gender
|
||||
|
||||
location = st.text_input(
|
||||
"Location",
|
||||
value=st.session_state.ad_copy_data['location'],
|
||||
help="Enter target location (city, state, country)"
|
||||
)
|
||||
st.session_state.ad_copy_data['location'] = location
|
||||
|
||||
# Interests
|
||||
st.subheader("Interests")
|
||||
|
||||
# Initialize interests in session state if not present
|
||||
if 'interests' not in st.session_state.ad_copy_data:
|
||||
st.session_state.ad_copy_data['interests'] = []
|
||||
|
||||
# Add new interest
|
||||
new_interest = st.text_input("Add an interest", key="new_interest")
|
||||
if st.button("Add Interest") and new_interest:
|
||||
if new_interest not in st.session_state.ad_copy_data['interests']:
|
||||
st.session_state.ad_copy_data['interests'].append(new_interest)
|
||||
st.rerun()
|
||||
|
||||
# Display and allow removal of existing interests
|
||||
if st.session_state.ad_copy_data['interests']:
|
||||
st.write("Current Interests:")
|
||||
for i, interest in enumerate(st.session_state.ad_copy_data['interests']):
|
||||
col1, col2 = st.columns([4, 1])
|
||||
with col1:
|
||||
st.write(f"{i+1}. {interest}")
|
||||
with col2:
|
||||
if st.button("Remove", key=f"remove_interest_{i}"):
|
||||
st.session_state.ad_copy_data['interests'].pop(i)
|
||||
st.rerun()
|
||||
|
||||
# Behaviors
|
||||
st.subheader("Behaviors")
|
||||
|
||||
behavior_options = [
|
||||
'engaged_shoppers',
|
||||
'frequent_travelers',
|
||||
'technology_early_adopters',
|
||||
'small_business_owners',
|
||||
'mobile_users',
|
||||
'luxury_shoppers'
|
||||
]
|
||||
|
||||
behaviors = st.multiselect(
|
||||
"Select Behaviors",
|
||||
options=behavior_options,
|
||||
default=st.session_state.ad_copy_data['behaviors'],
|
||||
help="Choose relevant user behaviors"
|
||||
)
|
||||
st.session_state.ad_copy_data['behaviors'] = behaviors
|
||||
|
||||
# Custom & Lookalike Audiences
|
||||
st.subheader("Advanced Targeting")
|
||||
|
||||
custom_audience = st.text_area(
|
||||
"Custom Audience Source",
|
||||
value=st.session_state.ad_copy_data['custom_audience'],
|
||||
help="Describe your custom audience source (e.g., email list, website visitors)",
|
||||
height=100
|
||||
)
|
||||
st.session_state.ad_copy_data['custom_audience'] = custom_audience
|
||||
|
||||
lookalike_source = st.text_area(
|
||||
"Lookalike Audience Source",
|
||||
value=st.session_state.ad_copy_data['lookalike_source'],
|
||||
help="Describe your lookalike audience source",
|
||||
height=100
|
||||
)
|
||||
st.session_state.ad_copy_data['lookalike_source'] = lookalike_source
|
||||
|
||||
def render_ad_content_tab():
|
||||
"""Render the ad content configuration fields."""
|
||||
|
||||
st.header("Ad Content")
|
||||
|
||||
# Headlines
|
||||
st.subheader("Headlines")
|
||||
|
||||
primary_headline = st.text_input(
|
||||
"Primary Headline",
|
||||
value=st.session_state.ad_copy_data['primary_headline'],
|
||||
help="Enter your main headline (max 40 characters)",
|
||||
max_chars=40
|
||||
)
|
||||
st.session_state.ad_copy_data['primary_headline'] = primary_headline
|
||||
|
||||
secondary_headline = st.text_input(
|
||||
"Secondary Headline (optional)",
|
||||
value=st.session_state.ad_copy_data['secondary_headline'],
|
||||
help="Enter a secondary headline (max 40 characters)",
|
||||
max_chars=40
|
||||
)
|
||||
st.session_state.ad_copy_data['secondary_headline'] = secondary_headline
|
||||
|
||||
# Description
|
||||
description = st.text_area(
|
||||
"Ad Description",
|
||||
value=st.session_state.ad_copy_data['description'],
|
||||
help="Enter your ad description (max 125 characters)",
|
||||
max_chars=125,
|
||||
height=100
|
||||
)
|
||||
st.session_state.ad_copy_data['description'] = description
|
||||
|
||||
# Link Description
|
||||
link_description = st.text_input(
|
||||
"Link Description",
|
||||
value=st.session_state.ad_copy_data['link_description'],
|
||||
help="Enter your link description (max 30 characters)",
|
||||
max_chars=30
|
||||
)
|
||||
st.session_state.ad_copy_data['link_description'] = link_description
|
||||
|
||||
# Brand Voice
|
||||
brand_voice = st.selectbox(
|
||||
"Brand Voice",
|
||||
options=['professional', 'friendly', 'casual', 'formal', 'humorous'],
|
||||
index=['professional', 'friendly', 'casual', 'formal', 'humorous'].index(
|
||||
st.session_state.ad_copy_data['brand_voice']
|
||||
),
|
||||
help="Choose the tone for your ad copy"
|
||||
)
|
||||
st.session_state.ad_copy_data['brand_voice'] = brand_voice
|
||||
|
||||
# Key Points
|
||||
st.subheader("Key Points")
|
||||
|
||||
# Initialize key_points in session state if not present
|
||||
if 'key_points' not in st.session_state.ad_copy_data:
|
||||
st.session_state.ad_copy_data['key_points'] = []
|
||||
|
||||
# Add new key point
|
||||
new_point = st.text_input("Add a key point", key="new_key_point")
|
||||
if st.button("Add Point") and new_point:
|
||||
if new_point not in st.session_state.ad_copy_data['key_points']:
|
||||
st.session_state.ad_copy_data['key_points'].append(new_point)
|
||||
st.rerun()
|
||||
|
||||
# Display and allow removal of existing key points
|
||||
if st.session_state.ad_copy_data['key_points']:
|
||||
st.write("Current Key Points:")
|
||||
for i, point in enumerate(st.session_state.ad_copy_data['key_points']):
|
||||
col1, col2 = st.columns([4, 1])
|
||||
with col1:
|
||||
st.write(f"{i+1}. {point}")
|
||||
with col2:
|
||||
if st.button("Remove", key=f"remove_point_{i}"):
|
||||
st.session_state.ad_copy_data['key_points'].pop(i)
|
||||
st.rerun()
|
||||
|
||||
# Unique Selling Proposition
|
||||
usp = st.text_area(
|
||||
"Unique Selling Proposition",
|
||||
value=st.session_state.ad_copy_data['usp'],
|
||||
help="What makes your offer unique? (max 80 characters)",
|
||||
max_chars=80,
|
||||
height=100
|
||||
)
|
||||
st.session_state.ad_copy_data['usp'] = usp
|
||||
|
||||
def render_cta_tab():
|
||||
"""Render the call-to-action configuration fields."""
|
||||
|
||||
st.header("Call-to-Action")
|
||||
|
||||
# CTA Type
|
||||
cta_options = {
|
||||
'learn_more': 'Learn More',
|
||||
'shop_now': 'Shop Now',
|
||||
'sign_up': 'Sign Up',
|
||||
'book_now': 'Book Now',
|
||||
'contact_us': 'Contact Us',
|
||||
'download': 'Download',
|
||||
'get_offer': 'Get Offer',
|
||||
'watch_more': 'Watch More',
|
||||
'subscribe': 'Subscribe',
|
||||
'custom': 'Custom'
|
||||
}
|
||||
|
||||
cta_type = st.selectbox(
|
||||
"CTA Button Type",
|
||||
options=list(cta_options.keys()),
|
||||
index=list(cta_options.keys()).index(
|
||||
st.session_state.ad_copy_data['cta_type']
|
||||
),
|
||||
format_func=lambda x: cta_options[x],
|
||||
help="Choose your call-to-action button type"
|
||||
)
|
||||
st.session_state.ad_copy_data['cta_type'] = cta_type
|
||||
|
||||
# Custom CTA Text (if custom selected)
|
||||
if cta_type == 'custom':
|
||||
cta_text = st.text_input(
|
||||
"Custom CTA Text",
|
||||
value=st.session_state.ad_copy_data['cta_text'],
|
||||
help="Enter your custom call-to-action text (max 20 characters)",
|
||||
max_chars=20
|
||||
)
|
||||
st.session_state.ad_copy_data['cta_text'] = cta_text
|
||||
|
||||
# Urgency Elements
|
||||
st.subheader("Urgency Elements")
|
||||
|
||||
use_urgency = st.checkbox(
|
||||
"Add Urgency",
|
||||
value=st.session_state.ad_copy_data['use_urgency'],
|
||||
help="Add time-sensitive elements to your ad"
|
||||
)
|
||||
st.session_state.ad_copy_data['use_urgency'] = use_urgency
|
||||
|
||||
if use_urgency:
|
||||
offer_details = st.text_area(
|
||||
"Offer Details",
|
||||
value=st.session_state.ad_copy_data['offer_details'],
|
||||
help="Enter time-sensitive offer details (e.g., 'Limited time offer - 24 hours only!')",
|
||||
height=100
|
||||
)
|
||||
st.session_state.ad_copy_data['offer_details'] = offer_details
|
||||
|
||||
def render_preview_export_tab():
|
||||
"""Render the preview and export options."""
|
||||
|
||||
st.header("Preview & Export")
|
||||
|
||||
# Show preview if content has been generated
|
||||
if st.session_state.ad_copy_data['show_preview'] and st.session_state.ad_copy_data['generated_content']:
|
||||
st.subheader("Preview")
|
||||
|
||||
# Toggle between mobile and desktop view
|
||||
view_mode = st.radio("View Mode", ["Desktop", "Mobile"])
|
||||
|
||||
if view_mode == "Desktop":
|
||||
st.markdown("""
|
||||
<div style='background-color: #f0f2f6; padding: 20px; border-radius: 10px;'>
|
||||
<h2 style='color: #1877F2;'>Ad Preview</h2>
|
||||
<div style='white-space: pre-wrap;'>
|
||||
""", unsafe_allow_html=True)
|
||||
st.write(st.session_state.ad_copy_data['generated_content'])
|
||||
st.markdown("</div></div>", unsafe_allow_html=True)
|
||||
else:
|
||||
st.markdown("""
|
||||
<div style='max-width: 375px; margin: 0 auto; background-color: #f0f2f6; padding: 15px; border-radius: 10px;'>
|
||||
<h2 style='color: #1877F2; font-size: 18px;'>Ad Preview</h2>
|
||||
<div style='white-space: pre-wrap; font-size: 14px;'>
|
||||
""", unsafe_allow_html=True)
|
||||
st.write(st.session_state.ad_copy_data['generated_content'])
|
||||
st.markdown("</div></div>", unsafe_allow_html=True)
|
||||
|
||||
# A/B Testing Variations
|
||||
if st.session_state.ad_copy_data['variations']:
|
||||
st.subheader("A/B Testing Variations")
|
||||
for i, variation in enumerate(st.session_state.ad_copy_data['variations']):
|
||||
with st.expander(f"Variation {i+1}"):
|
||||
st.write(variation)
|
||||
|
||||
# Export options
|
||||
st.subheader("Export Options")
|
||||
|
||||
col1, col2, col3 = st.columns(3)
|
||||
|
||||
with col1:
|
||||
if st.button("Copy to Clipboard"):
|
||||
st.code(st.session_state.ad_copy_data['generated_content'], language=None)
|
||||
st.success("Content copied to clipboard!")
|
||||
|
||||
with col2:
|
||||
if st.button("Download as Text"):
|
||||
download_ad_copy(st.session_state.ad_copy_data['generated_content'])
|
||||
|
||||
with col3:
|
||||
if st.button("Export as JSON"):
|
||||
export_ad_copy_json()
|
||||
else:
|
||||
st.info("Generate your ad copy to see a preview and export options.")
|
||||
|
||||
def validate_ad_copy_fields() -> bool:
|
||||
"""Validate the required fields for the ad copy generator."""
|
||||
|
||||
data = st.session_state.ad_copy_data
|
||||
|
||||
# Check required fields
|
||||
if not data['campaign_name']:
|
||||
st.error("Campaign Name is required.")
|
||||
return False
|
||||
|
||||
if not data['location']:
|
||||
st.error("Location is required.")
|
||||
return False
|
||||
|
||||
if not data['primary_headline']:
|
||||
st.error("Primary Headline is required.")
|
||||
return False
|
||||
|
||||
if not data['description']:
|
||||
st.error("Ad Description is required.")
|
||||
return False
|
||||
|
||||
if not data['key_points']:
|
||||
st.error("At least one Key Point is required.")
|
||||
return False
|
||||
|
||||
if not data['usp']:
|
||||
st.error("Unique Selling Proposition is required.")
|
||||
return False
|
||||
|
||||
if data['cta_type'] == 'custom' and not data['cta_text']:
|
||||
st.error("Custom CTA Text is required when using a custom CTA.")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def generate_ad_copy() -> Optional[str]:
|
||||
"""Generate the ad copy content using AI."""
|
||||
|
||||
try:
|
||||
data = st.session_state.ad_copy_data
|
||||
|
||||
# Prepare the prompt for the LLM
|
||||
prompt = f"""
|
||||
Create a Facebook Ad with the following specifications:
|
||||
|
||||
Campaign Details:
|
||||
- Name: {data['campaign_name']}
|
||||
- Objective: {data['objective']}
|
||||
- Format: {data['format']}
|
||||
- Placements: {', '.join(data['placements'])}
|
||||
|
||||
Target Audience:
|
||||
- Age: {data['age_range'][0]}-{data['age_range'][1]}
|
||||
- Gender: {data['gender']}
|
||||
- Location: {data['location']}
|
||||
- Interests: {', '.join(data['interests'])}
|
||||
- Behaviors: {', '.join(data['behaviors'])}
|
||||
|
||||
Ad Content:
|
||||
- Primary Headline: {data['primary_headline']}
|
||||
- Secondary Headline: {data['secondary_headline']}
|
||||
- Description: {data['description']}
|
||||
- Link Description: {data['link_description']}
|
||||
- Brand Voice: {data['brand_voice']}
|
||||
- Key Points: {', '.join(data['key_points'])}
|
||||
- USP: {data['usp']}
|
||||
|
||||
Call-to-Action:
|
||||
- Type: {data['cta_type']}
|
||||
- Custom Text: {data['cta_text'] if data['cta_type'] == 'custom' else 'N/A'}
|
||||
- Urgency: {data['offer_details'] if data['use_urgency'] else 'No urgency element'}
|
||||
|
||||
The ad copy should be engaging, persuasive, and optimized for the selected objective.
|
||||
Use appropriate formatting and ensure the tone matches the selected brand voice.
|
||||
Include all key points and USP in a natural way.
|
||||
Make the call-to-action compelling and relevant to the objective.
|
||||
"""
|
||||
|
||||
# Get response from LLM
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
if response:
|
||||
return response
|
||||
else:
|
||||
st.error("Failed to generate ad copy content. Please try again.")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating ad copy: {str(e)}")
|
||||
st.error("An error occurred while generating the ad copy. Please try again.")
|
||||
return None
|
||||
|
||||
def generate_ad_variations() -> Optional[List[str]]:
|
||||
"""Generate variations of the ad copy for A/B testing."""
|
||||
|
||||
try:
|
||||
data = st.session_state.ad_copy_data
|
||||
|
||||
# Prepare the prompt for variations
|
||||
prompt = f"""
|
||||
Create 2 variations of the following Facebook Ad copy for A/B testing.
|
||||
Keep the core message and USP but vary the:
|
||||
1. Headline approach
|
||||
2. Description structure
|
||||
3. Call-to-action phrasing
|
||||
|
||||
Original Ad Copy:
|
||||
{data['generated_content']}
|
||||
|
||||
Make each variation unique while maintaining the brand voice ({data['brand_voice']})
|
||||
and focusing on the main objective ({data['objective']}).
|
||||
"""
|
||||
|
||||
# Get response from LLM
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
if response:
|
||||
# Split the response into variations
|
||||
variations = response.split('\n\nVariation')
|
||||
return variations[1:] if len(variations) > 1 else []
|
||||
else:
|
||||
st.warning("Failed to generate ad variations. Using original copy only.")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating ad variations: {str(e)}")
|
||||
st.warning("Failed to generate ad variations. Using original copy only.")
|
||||
return None
|
||||
|
||||
def download_ad_copy(content: str):
|
||||
"""Download the ad copy content as a text file."""
|
||||
|
||||
try:
|
||||
# Create a timestamp for the filename
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"facebook_ad_copy_{timestamp}.txt"
|
||||
|
||||
# Create a download button
|
||||
st.download_button(
|
||||
label="Download Text File",
|
||||
data=content,
|
||||
file_name=filename,
|
||||
mime="text/plain"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error downloading ad copy: {str(e)}")
|
||||
st.error("An error occurred while downloading the ad copy. Please try again.")
|
||||
|
||||
def export_ad_copy_json():
|
||||
"""Export the ad copy data as a JSON file."""
|
||||
|
||||
try:
|
||||
data = st.session_state.ad_copy_data
|
||||
|
||||
# Create a timestamp for the filename
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"facebook_ad_copy_{timestamp}.json"
|
||||
|
||||
# Convert data to JSON
|
||||
json_data = json.dumps(data, indent=2)
|
||||
|
||||
# Create a download button
|
||||
st.download_button(
|
||||
label="Download JSON File",
|
||||
data=json_data,
|
||||
file_name=filename,
|
||||
mime="application/json"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error exporting ad copy JSON: {str(e)}")
|
||||
st.error("An error occurred while exporting the ad copy data. Please try again.")
|
||||
@@ -1,88 +0,0 @@
|
||||
# Facebook Engagement Analyzer
|
||||
|
||||
## Overview
|
||||
The Facebook Engagement Analyzer is a powerful tool designed to help content creators understand and improve their Facebook content performance. It provides detailed analytics, audience insights, and AI-powered suggestions to optimize engagement and reach.
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Content Analysis
|
||||
- **AI-Powered Content Evaluation**: Analyzes your content for quality and engagement potential
|
||||
- **Strengths Identification**: Highlights what's working well in your content
|
||||
- **Improvement Areas**: Points out specific areas that could be enhanced
|
||||
- **Optimization Suggestions**: Provides actionable recommendations for content improvement
|
||||
|
||||
### 2. Performance Metrics
|
||||
- **Comprehensive Metrics Tracking**: Monitor likes, comments, shares, reach, impressions, and clicks
|
||||
- **Engagement Rate Calculation**: Automatically calculates and visualizes your engagement rate
|
||||
- **Competitor Benchmarking**: Compare your performance against industry averages and top performers
|
||||
- **Visual Analytics**: Interactive charts and graphs to visualize your performance data
|
||||
|
||||
### 3. Audience Insights
|
||||
- **Demographic Analysis**: Understand your audience's age, gender, location, and device usage
|
||||
- **Peak Engagement Times**: Identify the best days and times to post for maximum engagement
|
||||
- **Audience Behavior Patterns**: Gain insights into how your audience interacts with your content
|
||||
- **Visual Data Representation**: Pie charts, bar graphs, and line charts to visualize audience data
|
||||
|
||||
### 4. Improvement Suggestions
|
||||
- **AI-Generated Recommendations**: Get personalized suggestions based on your content and metrics
|
||||
- **Expected Impact Predictions**: Understand the potential impact of each suggestion
|
||||
- **Implementation Guidance**: Step-by-step instructions for implementing each suggestion
|
||||
- **A/B Testing Ideas**: Generate and manage A/B testing scenarios to optimize your content
|
||||
|
||||
## How to Use
|
||||
|
||||
1. **Access the Tool**: Navigate to the Facebook AI Writer dashboard and select "Engagement Analyzer"
|
||||
2. **Enter Your Content**: Paste your Facebook content or URL in the Content Analysis tab
|
||||
3. **Select Content Type**: Choose the type of content you're analyzing (Post, Story, Reel, etc.)
|
||||
4. **Set Date Range**: Specify the date range for your analysis
|
||||
5. **Analyze Content**: Click "Analyze Content" to get AI-powered insights
|
||||
6. **Enter Performance Metrics**: Input your actual performance metrics in the Performance Metrics tab
|
||||
7. **Review Audience Insights**: Explore demographic data and peak engagement times
|
||||
8. **Generate Improvement Suggestions**: Get personalized recommendations to improve your content
|
||||
9. **Create A/B Tests**: Set up A/B tests based on the suggested variations
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Content Analysis
|
||||
- Be specific about your content goals when analyzing
|
||||
- Include the full content text for most accurate analysis
|
||||
- Consider analyzing multiple pieces of content to identify patterns
|
||||
|
||||
### Performance Metrics
|
||||
- Enter accurate metrics for the most reliable insights
|
||||
- Track metrics consistently over time to identify trends
|
||||
- Compare metrics across different content types to understand what works best
|
||||
|
||||
### Audience Insights
|
||||
- Use demographic data to tailor your content to your audience
|
||||
- Post during peak engagement times for maximum reach
|
||||
- Consider your audience's device preferences when creating content
|
||||
|
||||
### Improvement Suggestions
|
||||
- Implement suggestions gradually and measure the impact
|
||||
- Focus on high-impact, low-effort improvements first
|
||||
- Use A/B testing to validate improvements before full implementation
|
||||
|
||||
## Technical Requirements
|
||||
- Internet connection
|
||||
- Facebook account with content to analyze
|
||||
- Performance metrics data (optional but recommended)
|
||||
|
||||
## Troubleshooting
|
||||
- **Analysis Not Working**: Ensure you've entered content and selected a content type
|
||||
- **Metrics Not Updating**: Check that you've entered valid numbers for all metrics
|
||||
- **Charts Not Displaying**: Try refreshing the page or clearing your browser cache
|
||||
- **Suggestions Not Generating**: Make sure you've analyzed content and entered metrics first
|
||||
|
||||
## Future Updates
|
||||
- Historical performance tracking
|
||||
- Competitor content analysis
|
||||
- Advanced sentiment analysis
|
||||
- Custom metric tracking
|
||||
- Export functionality for reports
|
||||
|
||||
## Contributing
|
||||
We welcome feedback and contributions to improve the Engagement Analyzer. Please share your suggestions and report any issues you encounter.
|
||||
|
||||
## License
|
||||
This tool is part of the ALwrity AI Writer suite and is subject to the same licensing terms.
|
||||
@@ -1,10 +0,0 @@
|
||||
"""
|
||||
Facebook Engagement Analyzer Module
|
||||
|
||||
This module provides functionality to analyze Facebook content performance and provide
|
||||
AI-powered suggestions for improvement.
|
||||
"""
|
||||
|
||||
from .engagement_analyzer import analyze_fb_engagement
|
||||
|
||||
__all__ = ['analyze_fb_engagement']
|
||||
@@ -1,907 +0,0 @@
|
||||
"""
|
||||
Facebook Engagement Analyzer Module
|
||||
|
||||
This module provides functionality to analyze Facebook content performance and provide
|
||||
AI-powered suggestions for improvement. It helps content creators understand what works
|
||||
and how to optimize their content for better engagement.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import json
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from datetime import datetime, timedelta
|
||||
import plotly.express as px
|
||||
import plotly.graph_objects as go
|
||||
from typing import Dict, List, Any, Tuple, Optional, Union
|
||||
from loguru import logger
|
||||
import sys
|
||||
import base64
|
||||
from io import BytesIO
|
||||
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
|
||||
# Configure logging
|
||||
logger.remove()
|
||||
logger.add(sys.stdout,
|
||||
colorize=True,
|
||||
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
|
||||
)
|
||||
|
||||
def initialize_session_state():
|
||||
"""Initialize session state with default values."""
|
||||
if 'engagement_data' not in st.session_state:
|
||||
st.session_state.engagement_data = {
|
||||
'content': "",
|
||||
'content_type': "Post",
|
||||
'metrics': {
|
||||
'likes': 0,
|
||||
'comments': 0,
|
||||
'shares': 0,
|
||||
'reach': 0,
|
||||
'impressions': 0,
|
||||
'clicks': 0,
|
||||
'engagement_rate': 0.0
|
||||
},
|
||||
'audience_demographics': {
|
||||
'age_groups': {},
|
||||
'gender': {},
|
||||
'location': {},
|
||||
'device': {}
|
||||
},
|
||||
'peak_engagement_times': [],
|
||||
'competitor_benchmarks': {},
|
||||
'analysis_results': {},
|
||||
'improvement_suggestions': []
|
||||
}
|
||||
|
||||
def analyze_fb_engagement():
|
||||
"""Analyze Facebook content performance and provide improvement suggestions."""
|
||||
|
||||
# Initialize session state
|
||||
initialize_session_state()
|
||||
|
||||
st.markdown("""
|
||||
### 📊 Facebook Engagement Analyzer
|
||||
Analyze your content performance and get AI-powered suggestions to improve engagement.
|
||||
Understand what works, identify patterns, and optimize your Facebook strategy.
|
||||
""")
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3, tab4 = st.tabs(["Content Analysis", "Performance Metrics", "Audience Insights", "Improvement Suggestions"])
|
||||
|
||||
with tab1:
|
||||
render_content_analysis_tab()
|
||||
|
||||
with tab2:
|
||||
render_performance_metrics_tab()
|
||||
|
||||
with tab3:
|
||||
render_audience_insights_tab()
|
||||
|
||||
with tab4:
|
||||
render_improvement_suggestions_tab()
|
||||
|
||||
def render_content_analysis_tab():
|
||||
"""Render the content analysis tab with input fields."""
|
||||
|
||||
st.markdown("#### Content for Analysis")
|
||||
|
||||
# Content Input
|
||||
content = st.text_area(
|
||||
"Enter your Facebook content or paste a URL",
|
||||
value=st.session_state.engagement_data['content'],
|
||||
height=150,
|
||||
help="Enter the text content or paste a URL to your Facebook post",
|
||||
key="content_input"
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.engagement_data['content'] = content
|
||||
|
||||
# Content Type Selection
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
content_types = ["Post", "Story", "Reel", "Carousel", "Event", "Group Post", "Page"]
|
||||
|
||||
content_type = st.selectbox(
|
||||
"Content Type",
|
||||
options=content_types,
|
||||
index=content_types.index(st.session_state.engagement_data['content_type']) if st.session_state.engagement_data['content_type'] in content_types else 0,
|
||||
help="Select the type of content you're analyzing",
|
||||
key="content_type_select"
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.engagement_data['content_type'] = content_type
|
||||
|
||||
with col2:
|
||||
# Date Range Selection
|
||||
date_range = st.date_input(
|
||||
"Date Range",
|
||||
value=(datetime.now() - timedelta(days=7), datetime.now()),
|
||||
help="Select the date range for analysis",
|
||||
key="date_range_select"
|
||||
)
|
||||
|
||||
# Analyze Button
|
||||
if st.button("Analyze Content", key="analyze_content_button"):
|
||||
if not content:
|
||||
st.warning("Please enter some content to analyze.")
|
||||
else:
|
||||
with st.spinner("Analyzing content performance..."):
|
||||
# Perform content analysis
|
||||
analysis_results = analyze_content(
|
||||
content,
|
||||
content_type,
|
||||
date_range
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.engagement_data['analysis_results'] = analysis_results
|
||||
|
||||
# Display results
|
||||
display_content_analysis(analysis_results)
|
||||
|
||||
def render_performance_metrics_tab():
|
||||
"""Render the performance metrics tab."""
|
||||
|
||||
st.markdown("#### Performance Metrics")
|
||||
|
||||
# Check if we have analysis results
|
||||
if not st.session_state.engagement_data['analysis_results']:
|
||||
st.info("Please analyze your content first in the Content Analysis tab.")
|
||||
return
|
||||
|
||||
# Metrics Input
|
||||
st.markdown("##### Enter Performance Metrics")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
metrics = st.session_state.engagement_data['metrics']
|
||||
|
||||
metrics['likes'] = st.number_input(
|
||||
"Likes",
|
||||
min_value=0,
|
||||
value=metrics['likes'],
|
||||
help="Number of likes",
|
||||
key="likes_input"
|
||||
)
|
||||
|
||||
metrics['comments'] = st.number_input(
|
||||
"Comments",
|
||||
min_value=0,
|
||||
value=metrics['comments'],
|
||||
help="Number of comments",
|
||||
key="comments_input"
|
||||
)
|
||||
|
||||
metrics['shares'] = st.number_input(
|
||||
"Shares",
|
||||
min_value=0,
|
||||
value=metrics['shares'],
|
||||
help="Number of shares",
|
||||
key="shares_input"
|
||||
)
|
||||
|
||||
metrics['reach'] = st.number_input(
|
||||
"Reach",
|
||||
min_value=0,
|
||||
value=metrics['reach'],
|
||||
help="Number of people who saw your content",
|
||||
key="reach_input"
|
||||
)
|
||||
|
||||
with col2:
|
||||
metrics['impressions'] = st.number_input(
|
||||
"Impressions",
|
||||
min_value=0,
|
||||
value=metrics['impressions'],
|
||||
help="Number of times your content was shown",
|
||||
key="impressions_input"
|
||||
)
|
||||
|
||||
metrics['clicks'] = st.number_input(
|
||||
"Clicks",
|
||||
min_value=0,
|
||||
value=metrics['clicks'],
|
||||
help="Number of clicks on your content",
|
||||
key="clicks_input"
|
||||
)
|
||||
|
||||
# Calculate engagement rate
|
||||
if metrics['reach'] > 0:
|
||||
metrics['engagement_rate'] = ((metrics['likes'] + metrics['comments'] + metrics['shares']) / metrics['reach']) * 100
|
||||
else:
|
||||
metrics['engagement_rate'] = 0.0
|
||||
|
||||
st.metric(
|
||||
"Engagement Rate",
|
||||
f"{metrics['engagement_rate']:.2f}%",
|
||||
help="Percentage of people who engaged with your content"
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.engagement_data['metrics'] = metrics
|
||||
|
||||
# Visualize metrics
|
||||
visualize_performance_metrics(metrics)
|
||||
|
||||
# Competitor Benchmarks
|
||||
st.markdown("##### Competitor Benchmarks")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
competitor_metrics = {
|
||||
"Industry Average": {
|
||||
"engagement_rate": 2.5,
|
||||
"reach": metrics['reach'] * 1.2,
|
||||
"comments": metrics['comments'] * 1.1
|
||||
},
|
||||
"Top Performers": {
|
||||
"engagement_rate": 5.0,
|
||||
"reach": metrics['reach'] * 2.0,
|
||||
"comments": metrics['comments'] * 2.5
|
||||
}
|
||||
}
|
||||
|
||||
st.session_state.engagement_data['competitor_benchmarks'] = competitor_metrics
|
||||
|
||||
# Create a DataFrame for comparison
|
||||
comparison_data = {
|
||||
"Metric": ["Engagement Rate", "Reach", "Comments"],
|
||||
"Your Content": [
|
||||
metrics['engagement_rate'],
|
||||
metrics['reach'],
|
||||
metrics['comments']
|
||||
],
|
||||
"Industry Average": [
|
||||
competitor_metrics["Industry Average"]["engagement_rate"],
|
||||
competitor_metrics["Industry Average"]["reach"],
|
||||
competitor_metrics["Industry Average"]["comments"]
|
||||
],
|
||||
"Top Performers": [
|
||||
competitor_metrics["Top Performers"]["engagement_rate"],
|
||||
competitor_metrics["Top Performers"]["reach"],
|
||||
competitor_metrics["Top Performers"]["comments"]
|
||||
]
|
||||
}
|
||||
|
||||
df = pd.DataFrame(comparison_data)
|
||||
|
||||
# Display comparison chart
|
||||
fig = go.Figure()
|
||||
|
||||
fig.add_trace(go.Bar(
|
||||
x=df["Metric"],
|
||||
y=df["Your Content"],
|
||||
name="Your Content",
|
||||
marker_color="#1877F2"
|
||||
))
|
||||
|
||||
fig.add_trace(go.Bar(
|
||||
x=df["Metric"],
|
||||
y=df["Industry Average"],
|
||||
name="Industry Average",
|
||||
marker_color="#34A853"
|
||||
))
|
||||
|
||||
fig.add_trace(go.Bar(
|
||||
x=df["Metric"],
|
||||
y=df["Top Performers"],
|
||||
name="Top Performers",
|
||||
marker_color="#EA4335"
|
||||
))
|
||||
|
||||
fig.update_layout(
|
||||
title="Performance Comparison",
|
||||
xaxis_title="Metric",
|
||||
yaxis_title="Value",
|
||||
barmode="group",
|
||||
legend=dict(
|
||||
orientation="h",
|
||||
yanchor="bottom",
|
||||
y=1.02,
|
||||
xanchor="right",
|
||||
x=1
|
||||
)
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
def render_audience_insights_tab():
|
||||
"""Render the audience insights tab."""
|
||||
|
||||
st.markdown("#### Audience Insights")
|
||||
|
||||
# Check if we have analysis results
|
||||
if not st.session_state.engagement_data['analysis_results']:
|
||||
st.info("Please analyze your content first in the Content Analysis tab.")
|
||||
return
|
||||
|
||||
# Audience Demographics
|
||||
st.markdown("##### Audience Demographics")
|
||||
|
||||
# Initialize demographics if not exists
|
||||
demographics = st.session_state.engagement_data['audience_demographics']
|
||||
|
||||
# Age Groups
|
||||
st.markdown("###### Age Distribution")
|
||||
|
||||
age_data = {
|
||||
"18-24": 15,
|
||||
"25-34": 30,
|
||||
"35-44": 25,
|
||||
"45-54": 15,
|
||||
"55-64": 10,
|
||||
"65+": 5
|
||||
}
|
||||
|
||||
demographics['age_groups'] = age_data
|
||||
|
||||
# Create age distribution chart
|
||||
fig = px.pie(
|
||||
values=list(age_data.values()),
|
||||
names=list(age_data.keys()),
|
||||
title="Age Distribution"
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
# Gender
|
||||
st.markdown("###### Gender Distribution")
|
||||
|
||||
gender_data = {
|
||||
"Male": 45,
|
||||
"Female": 52,
|
||||
"Other": 3
|
||||
}
|
||||
|
||||
demographics['gender'] = gender_data
|
||||
|
||||
# Create gender distribution chart
|
||||
fig = px.pie(
|
||||
values=list(gender_data.values()),
|
||||
names=list(gender_data.keys()),
|
||||
title="Gender Distribution"
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
# Location
|
||||
st.markdown("###### Top Locations")
|
||||
|
||||
location_data = {
|
||||
"United States": 40,
|
||||
"United Kingdom": 15,
|
||||
"Canada": 10,
|
||||
"Australia": 8,
|
||||
"India": 7,
|
||||
"Other": 20
|
||||
}
|
||||
|
||||
demographics['location'] = location_data
|
||||
|
||||
# Create location distribution chart
|
||||
fig = px.bar(
|
||||
x=list(location_data.keys()),
|
||||
y=list(location_data.values()),
|
||||
title="Top Locations"
|
||||
)
|
||||
|
||||
fig.update_layout(
|
||||
xaxis_title="Country",
|
||||
yaxis_title="Percentage"
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
# Device
|
||||
st.markdown("###### Device Usage")
|
||||
|
||||
device_data = {
|
||||
"Mobile": 75,
|
||||
"Desktop": 20,
|
||||
"Tablet": 5
|
||||
}
|
||||
|
||||
demographics['device'] = device_data
|
||||
|
||||
# Create device distribution chart
|
||||
fig = px.pie(
|
||||
values=list(device_data.values()),
|
||||
names=list(device_data.keys()),
|
||||
title="Device Usage"
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
# Update session state
|
||||
st.session_state.engagement_data['audience_demographics'] = demographics
|
||||
|
||||
# Peak Engagement Times
|
||||
st.markdown("##### Peak Engagement Times")
|
||||
|
||||
peak_times = [
|
||||
{"day": "Monday", "time": "9:00 AM", "engagement": 85},
|
||||
{"day": "Tuesday", "time": "2:00 PM", "engagement": 90},
|
||||
{"day": "Wednesday", "time": "11:00 AM", "engagement": 95},
|
||||
{"day": "Thursday", "time": "3:00 PM", "engagement": 88},
|
||||
{"day": "Friday", "time": "5:00 PM", "engagement": 92},
|
||||
{"day": "Saturday", "time": "10:00 AM", "engagement": 78},
|
||||
{"day": "Sunday", "time": "4:00 PM", "engagement": 82}
|
||||
]
|
||||
|
||||
st.session_state.engagement_data['peak_engagement_times'] = peak_times
|
||||
|
||||
# Create peak times chart
|
||||
days = [item["day"] for item in peak_times]
|
||||
times = [item["time"] for item in peak_times]
|
||||
engagement = [item["engagement"] for item in peak_times]
|
||||
|
||||
fig = go.Figure()
|
||||
|
||||
fig.add_trace(go.Scatter(
|
||||
x=days,
|
||||
y=engagement,
|
||||
mode="lines+markers",
|
||||
name="Engagement",
|
||||
line=dict(color="#1877F2", width=3),
|
||||
marker=dict(size=10)
|
||||
))
|
||||
|
||||
fig.update_layout(
|
||||
title="Peak Engagement Times",
|
||||
xaxis_title="Day of Week",
|
||||
yaxis_title="Engagement Score",
|
||||
annotations=[
|
||||
dict(
|
||||
x=days[i],
|
||||
y=engagement[i],
|
||||
text=times[i],
|
||||
showarrow=True,
|
||||
arrowhead=1,
|
||||
ax=0,
|
||||
ay=-40
|
||||
) for i in range(len(days))
|
||||
]
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
def render_improvement_suggestions_tab():
|
||||
"""Render the improvement suggestions tab."""
|
||||
|
||||
st.markdown("#### Improvement Suggestions")
|
||||
|
||||
# Check if we have analysis results
|
||||
if not st.session_state.engagement_data['analysis_results']:
|
||||
st.info("Please analyze your content first in the Content Analysis tab.")
|
||||
return
|
||||
|
||||
# Generate improvement suggestions
|
||||
if st.button("Generate Improvement Suggestions", key="generate_suggestions_button"):
|
||||
with st.spinner("Generating improvement suggestions..."):
|
||||
# Generate suggestions
|
||||
suggestions = generate_improvement_suggestions(
|
||||
st.session_state.engagement_data['content'],
|
||||
st.session_state.engagement_data['content_type'],
|
||||
st.session_state.engagement_data['metrics'],
|
||||
st.session_state.engagement_data['audience_demographics']
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.engagement_data['improvement_suggestions'] = suggestions
|
||||
|
||||
# Display suggestions
|
||||
display_improvement_suggestions(suggestions)
|
||||
|
||||
# Display existing suggestions if available
|
||||
if st.session_state.engagement_data['improvement_suggestions']:
|
||||
display_improvement_suggestions(st.session_state.engagement_data['improvement_suggestions'])
|
||||
|
||||
# A/B Testing
|
||||
st.markdown("##### A/B Testing Suggestions")
|
||||
|
||||
# Generate A/B testing suggestions
|
||||
if st.button("Generate A/B Testing Suggestions", key="generate_ab_testing_button"):
|
||||
with st.spinner("Generating A/B testing suggestions..."):
|
||||
# Generate A/B testing suggestions
|
||||
ab_testing_suggestions = generate_ab_testing_suggestions(
|
||||
st.session_state.engagement_data['content'],
|
||||
st.session_state.engagement_data['content_type']
|
||||
)
|
||||
|
||||
# Display A/B testing suggestions
|
||||
display_ab_testing_suggestions(ab_testing_suggestions)
|
||||
|
||||
def analyze_content(content: str, content_type: str, date_range: Tuple[datetime.date, datetime.date]) -> Dict[str, Any]:
|
||||
"""Analyze content and return analysis results."""
|
||||
|
||||
# Prepare prompt for content analysis
|
||||
prompt = f"""
|
||||
Analyze the following Facebook {content_type} content and provide insights on its performance potential:
|
||||
|
||||
Content: "{content}"
|
||||
|
||||
Date Range: {date_range[0]} to {date_range[1]}
|
||||
|
||||
Please provide a detailed analysis including:
|
||||
1. Content quality assessment
|
||||
2. Engagement potential
|
||||
3. Key strengths
|
||||
4. Areas for improvement
|
||||
5. Suggested optimizations
|
||||
|
||||
Format your response as a JSON object with the following structure:
|
||||
{{
|
||||
"content_quality": {{
|
||||
"score": <score from 1-10>,
|
||||
"feedback": "<detailed feedback>"
|
||||
}},
|
||||
"engagement_potential": {{
|
||||
"score": <score from 1-10>,
|
||||
"feedback": "<detailed feedback>"
|
||||
}},
|
||||
"strengths": ["<strength 1>", "<strength 2>", ...],
|
||||
"improvements": ["<improvement 1>", "<improvement 2>", ...],
|
||||
"optimizations": ["<optimization 1>", "<optimization 2>", ...]
|
||||
}}
|
||||
"""
|
||||
|
||||
try:
|
||||
# Generate analysis using LLM
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
# Parse JSON response
|
||||
analysis_results = json.loads(response)
|
||||
|
||||
return analysis_results
|
||||
except Exception as e:
|
||||
logger.error(f"Error analyzing content: {e}")
|
||||
|
||||
# Return default analysis results
|
||||
return {
|
||||
"content_quality": {
|
||||
"score": 7,
|
||||
"feedback": "Content appears to be well-structured and engaging."
|
||||
},
|
||||
"engagement_potential": {
|
||||
"score": 8,
|
||||
"feedback": "Content has good potential for engagement based on its format and content."
|
||||
},
|
||||
"strengths": [
|
||||
"Clear and concise messaging",
|
||||
"Engaging content structure",
|
||||
"Relevant to target audience"
|
||||
],
|
||||
"improvements": [
|
||||
"Add more visual elements",
|
||||
"Include a stronger call-to-action",
|
||||
"Optimize posting time"
|
||||
],
|
||||
"optimizations": [
|
||||
"Add relevant hashtags",
|
||||
"Include emojis for visual appeal",
|
||||
"Tag relevant accounts"
|
||||
]
|
||||
}
|
||||
|
||||
def display_content_analysis(analysis_results: Dict[str, Any]):
|
||||
"""Display content analysis results."""
|
||||
|
||||
# Content Quality
|
||||
st.markdown("##### Content Quality")
|
||||
|
||||
quality_score = analysis_results["content_quality"]["score"]
|
||||
quality_feedback = analysis_results["content_quality"]["feedback"]
|
||||
|
||||
# Create gauge chart for content quality
|
||||
fig = go.Figure(go.Indicator(
|
||||
mode="gauge+number",
|
||||
value=quality_score,
|
||||
domain={'x': [0, 1], 'y': [0, 1]},
|
||||
title={'text': "Content Quality Score"},
|
||||
gauge={
|
||||
'axis': {'range': [0, 10]},
|
||||
'bar': {'color': "#1877F2"},
|
||||
'steps': [
|
||||
{'range': [0, 3], 'color': "lightgray"},
|
||||
{'range': [3, 7], 'color': "gray"},
|
||||
{'range': [7, 10], 'color': "darkgray"}
|
||||
],
|
||||
'threshold': {
|
||||
'line': {'color': "red", 'width': 4},
|
||||
'thickness': 0.75,
|
||||
'value': 7
|
||||
}
|
||||
}
|
||||
))
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
st.markdown(f"**Feedback:** {quality_feedback}")
|
||||
|
||||
# Engagement Potential
|
||||
st.markdown("##### Engagement Potential")
|
||||
|
||||
engagement_score = analysis_results["engagement_potential"]["score"]
|
||||
engagement_feedback = analysis_results["engagement_potential"]["feedback"]
|
||||
|
||||
# Create gauge chart for engagement potential
|
||||
fig = go.Figure(go.Indicator(
|
||||
mode="gauge+number",
|
||||
value=engagement_score,
|
||||
domain={'x': [0, 1], 'y': [0, 1]},
|
||||
title={'text': "Engagement Potential Score"},
|
||||
gauge={
|
||||
'axis': {'range': [0, 10]},
|
||||
'bar': {'color': "#34A853"},
|
||||
'steps': [
|
||||
{'range': [0, 3], 'color': "lightgray"},
|
||||
{'range': [3, 7], 'color': "gray"},
|
||||
{'range': [7, 10], 'color': "darkgray"}
|
||||
],
|
||||
'threshold': {
|
||||
'line': {'color': "red", 'width': 4},
|
||||
'thickness': 0.75,
|
||||
'value': 7
|
||||
}
|
||||
}
|
||||
))
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
st.markdown(f"**Feedback:** {engagement_feedback}")
|
||||
|
||||
# Strengths
|
||||
st.markdown("##### Key Strengths")
|
||||
|
||||
for strength in analysis_results["strengths"]:
|
||||
st.markdown(f"- {strength}")
|
||||
|
||||
# Areas for Improvement
|
||||
st.markdown("##### Areas for Improvement")
|
||||
|
||||
for improvement in analysis_results["improvements"]:
|
||||
st.markdown(f"- {improvement}")
|
||||
|
||||
# Suggested Optimizations
|
||||
st.markdown("##### Suggested Optimizations")
|
||||
|
||||
for optimization in analysis_results["optimizations"]:
|
||||
st.markdown(f"- {optimization}")
|
||||
|
||||
def visualize_performance_metrics(metrics: Dict[str, Any]):
|
||||
"""Visualize performance metrics."""
|
||||
|
||||
# Create metrics chart
|
||||
metric_names = ["Likes", "Comments", "Shares", "Reach", "Impressions", "Clicks"]
|
||||
metric_values = [
|
||||
metrics["likes"],
|
||||
metrics["comments"],
|
||||
metrics["shares"],
|
||||
metrics["reach"],
|
||||
metrics["impressions"],
|
||||
metrics["clicks"]
|
||||
]
|
||||
|
||||
fig = go.Figure(data=[
|
||||
go.Bar(
|
||||
x=metric_names,
|
||||
y=metric_values,
|
||||
marker_color=["#1877F2", "#34A853", "#EA4335", "#FBBC05", "#4285F4", "#46BDC6"]
|
||||
)
|
||||
])
|
||||
|
||||
fig.update_layout(
|
||||
title="Performance Metrics",
|
||||
xaxis_title="Metric",
|
||||
yaxis_title="Count"
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
# Engagement Rate Gauge
|
||||
fig = go.Figure(go.Indicator(
|
||||
mode="gauge+number",
|
||||
value=metrics["engagement_rate"],
|
||||
domain={'x': [0, 1], 'y': [0, 1]},
|
||||
title={'text': "Engagement Rate"},
|
||||
gauge={
|
||||
'axis': {'range': [0, 10]},
|
||||
'bar': {'color': "#1877F2"},
|
||||
'steps': [
|
||||
{'range': [0, 1], 'color': "lightgray"},
|
||||
{'range': [1, 3], 'color': "gray"},
|
||||
{'range': [3, 10], 'color': "darkgray"}
|
||||
],
|
||||
'threshold': {
|
||||
'line': {'color': "red", 'width': 4},
|
||||
'thickness': 0.75,
|
||||
'value': 3
|
||||
}
|
||||
}
|
||||
))
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
def generate_improvement_suggestions(
|
||||
content: str,
|
||||
content_type: str,
|
||||
metrics: Dict[str, Any],
|
||||
demographics: Dict[str, Dict[str, Any]]
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""Generate improvement suggestions based on content analysis and metrics."""
|
||||
|
||||
# Prepare prompt for improvement suggestions
|
||||
prompt = f"""
|
||||
Based on the following Facebook {content_type} content and performance metrics, provide specific improvement suggestions:
|
||||
|
||||
Content: "{content}"
|
||||
|
||||
Metrics:
|
||||
- Likes: {metrics['likes']}
|
||||
- Comments: {metrics['comments']}
|
||||
- Shares: {metrics['shares']}
|
||||
- Reach: {metrics['reach']}
|
||||
- Impressions: {metrics['impressions']}
|
||||
- Clicks: {metrics['clicks']}
|
||||
- Engagement Rate: {metrics['engagement_rate']}%
|
||||
|
||||
Audience Demographics:
|
||||
- Age Groups: {demographics['age_groups']}
|
||||
- Gender: {demographics['gender']}
|
||||
- Top Locations: {demographics['location']}
|
||||
- Device Usage: {demographics['device']}
|
||||
|
||||
Please provide 5 specific, actionable improvement suggestions that would help increase engagement.
|
||||
Format your response as a JSON array of objects with the following structure:
|
||||
[
|
||||
{{
|
||||
"category": "<category>",
|
||||
"suggestion": "<detailed suggestion>",
|
||||
"expected_impact": "<expected impact on engagement>",
|
||||
"implementation": "<how to implement this suggestion>"
|
||||
}},
|
||||
...
|
||||
]
|
||||
"""
|
||||
|
||||
try:
|
||||
# Generate suggestions using LLM
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
# Parse JSON response
|
||||
suggestions = json.loads(response)
|
||||
|
||||
return suggestions
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating improvement suggestions: {e}")
|
||||
|
||||
# Return default suggestions
|
||||
return [
|
||||
{
|
||||
"category": "Content Structure",
|
||||
"suggestion": "Add a more compelling headline to grab attention in the first 3 seconds.",
|
||||
"expected_impact": "Increase initial engagement by 25%",
|
||||
"implementation": "Place the headline at the beginning of your post and make it bold or use emojis to stand out."
|
||||
},
|
||||
{
|
||||
"category": "Visual Elements",
|
||||
"suggestion": "Include high-quality images or videos that complement your message.",
|
||||
"expected_impact": "Increase engagement by 40%",
|
||||
"implementation": "Add relevant images or short videos that illustrate your main points."
|
||||
},
|
||||
{
|
||||
"category": "Call-to-Action",
|
||||
"suggestion": "Add a stronger, more specific call-to-action.",
|
||||
"expected_impact": "Increase click-through rate by 30%",
|
||||
"implementation": "End your post with a clear, action-oriented question or instruction."
|
||||
},
|
||||
{
|
||||
"category": "Posting Time",
|
||||
"suggestion": "Optimize your posting time based on audience activity.",
|
||||
"expected_impact": "Increase reach by 20%",
|
||||
"implementation": "Post during peak engagement times (Wednesdays at 11 AM) when your audience is most active."
|
||||
},
|
||||
{
|
||||
"category": "Hashtag Strategy",
|
||||
"suggestion": "Use a mix of popular and niche hashtags relevant to your content.",
|
||||
"expected_impact": "Increase discoverability by 35%",
|
||||
"implementation": "Research trending hashtags in your industry and include 3-5 relevant hashtags in your post."
|
||||
}
|
||||
]
|
||||
|
||||
def display_improvement_suggestions(suggestions: List[Dict[str, Any]]):
|
||||
"""Display improvement suggestions."""
|
||||
|
||||
for i, suggestion in enumerate(suggestions):
|
||||
with st.expander(f"{i+1}. {suggestion['category']}", expanded=True):
|
||||
st.markdown(f"**Suggestion:** {suggestion['suggestion']}")
|
||||
st.markdown(f"**Expected Impact:** {suggestion['expected_impact']}")
|
||||
st.markdown(f"**Implementation:** {suggestion['implementation']}")
|
||||
|
||||
def generate_ab_testing_suggestions(content: str, content_type: str) -> List[Dict[str, Any]]:
|
||||
"""Generate A/B testing suggestions."""
|
||||
|
||||
# Prepare prompt for A/B testing suggestions
|
||||
prompt = f"""
|
||||
Based on the following Facebook {content_type} content, provide specific A/B testing suggestions:
|
||||
|
||||
Content: "{content}"
|
||||
|
||||
Please provide 3 specific A/B testing ideas that would help optimize engagement.
|
||||
Format your response as a JSON array of objects with the following structure:
|
||||
[
|
||||
{{
|
||||
"element": "<element to test>",
|
||||
"variant_a": "<description of variant A>",
|
||||
"variant_b": "<description of variant B>",
|
||||
"metric": "<primary metric to measure>",
|
||||
"hypothesis": "<hypothesis about which variant will perform better>"
|
||||
}},
|
||||
...
|
||||
]
|
||||
"""
|
||||
|
||||
try:
|
||||
# Generate A/B testing suggestions using LLM
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
# Parse JSON response
|
||||
ab_testing_suggestions = json.loads(response)
|
||||
|
||||
return ab_testing_suggestions
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating A/B testing suggestions: {e}")
|
||||
|
||||
# Return default A/B testing suggestions
|
||||
return [
|
||||
{
|
||||
"element": "Headline",
|
||||
"variant_a": "Keep the current headline",
|
||||
"variant_b": "Use a more emotional or provocative headline",
|
||||
"metric": "Click-through rate",
|
||||
"hypothesis": "The emotional headline will increase click-through rate by 15%"
|
||||
},
|
||||
{
|
||||
"element": "Call-to-Action",
|
||||
"variant_a": "Use a question as the call-to-action",
|
||||
"variant_b": "Use a command as the call-to-action",
|
||||
"metric": "Engagement rate",
|
||||
"hypothesis": "The question format will increase engagement rate by 10%"
|
||||
},
|
||||
{
|
||||
"element": "Visual Style",
|
||||
"variant_a": "Use a single image",
|
||||
"variant_b": "Use a carousel of images",
|
||||
"metric": "Time spent viewing",
|
||||
"hypothesis": "The carousel will increase time spent viewing by 25%"
|
||||
}
|
||||
]
|
||||
|
||||
def display_ab_testing_suggestions(ab_testing_suggestions: List[Dict[str, Any]]):
|
||||
"""Display A/B testing suggestions."""
|
||||
|
||||
for i, suggestion in enumerate(ab_testing_suggestions):
|
||||
with st.expander(f"{i+1}. {suggestion['element']}", expanded=True):
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
st.markdown("**Variant A**")
|
||||
st.markdown(suggestion['variant_a'])
|
||||
|
||||
with col2:
|
||||
st.markdown("**Variant B**")
|
||||
st.markdown(suggestion['variant_b'])
|
||||
|
||||
st.markdown(f"**Primary Metric:** {suggestion['metric']}")
|
||||
st.markdown(f"**Hypothesis:** {suggestion['hypothesis']}")
|
||||
|
||||
# Add a button to create A/B test
|
||||
if st.button(f"Create A/B Test for {suggestion['element']}", key=f"ab_test_button_{i}"):
|
||||
st.success(f"A/B test for {suggestion['element']} created successfully!")
|
||||
@@ -1,162 +0,0 @@
|
||||
# Facebook Event Generator 📅
|
||||
|
||||
## Overview
|
||||
|
||||
The Facebook Event Generator is a powerful AI-powered tool designed to help content creators, event organizers, and businesses create engaging Facebook event descriptions. This tool leverages advanced AI to generate compelling event content, optimize engagement, and drive attendance.
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Event Details Management
|
||||
- **Event Type Selection**: Choose between Physical, Online, or Hybrid events
|
||||
- **Basic Information**: Name, category, date, time, and timezone
|
||||
- **Location Details**: Venue information for physical events
|
||||
- **Online Event Setup**: Platform selection and meeting details
|
||||
- **Custom Description Types**: Basic, Detailed, or Professional
|
||||
|
||||
### 2. Content Customization
|
||||
- **Content Style Options**: Professional, Casual, Formal, Engaging, Educational
|
||||
- **Content Elements**:
|
||||
- Agenda
|
||||
- Speakers
|
||||
- Benefits
|
||||
- Requirements
|
||||
- FAQ
|
||||
- Testimonials
|
||||
- Sponsors
|
||||
- Event Highlights
|
||||
|
||||
### 3. Media Options
|
||||
- **Cover Image Generation**: AI-powered image creation
|
||||
- **Style Selection**: Modern, Professional, Creative, Minimalist, Bold
|
||||
- **Brand Color Integration**: Custom color scheme support
|
||||
- **Image Quality Control**: Low, Medium, High options
|
||||
- **Aspect Ratio Options**: 16:9, 1:1, 4:3
|
||||
|
||||
### 4. Engagement Features
|
||||
- **Interactive Elements**:
|
||||
- Polls
|
||||
- Quizzes
|
||||
- Countdown timers
|
||||
- RSVP management
|
||||
- Reminders
|
||||
- Feedback forms
|
||||
- **Social Sharing**:
|
||||
- Hashtag suggestions
|
||||
- Social media links
|
||||
- Share buttons
|
||||
- Friend invitation options
|
||||
- **Custom Engagement Prompts**: AI-generated prompts to boost interaction
|
||||
|
||||
### 5. Preview & Export
|
||||
- **Live Preview**: See your event description as it will appear
|
||||
- **Export Options**:
|
||||
- Copy to clipboard
|
||||
- Download as text file
|
||||
- **Format Validation**: Ensure all required fields are completed
|
||||
|
||||
## How to Use
|
||||
|
||||
### Step 1: Access the Event Generator
|
||||
1. Navigate to the Facebook AI Writer dashboard
|
||||
2. Select the "Event Description Generator" card
|
||||
3. Click "Use Event Description Generator"
|
||||
|
||||
### Step 2: Enter Event Details
|
||||
1. Select event type (Physical/Online/Hybrid)
|
||||
2. Fill in basic information:
|
||||
- Event name
|
||||
- Category
|
||||
- Date and time
|
||||
- Timezone
|
||||
3. Add location details (for physical/hybrid events)
|
||||
4. Add online platform details (for online/hybrid events)
|
||||
|
||||
### Step 3: Customize Content
|
||||
1. Choose content style
|
||||
2. Select content elements to include
|
||||
3. Add key points and event goal
|
||||
4. Define target audience
|
||||
|
||||
### Step 4: Add Media
|
||||
1. Select cover image style
|
||||
2. Choose brand colors
|
||||
3. Set image quality and ratio
|
||||
4. Generate preview images
|
||||
|
||||
### Step 5: Configure Engagement
|
||||
1. Enable interactive elements
|
||||
2. Set up social sharing options
|
||||
3. Add custom engagement prompts
|
||||
4. Configure RSVP and reminder settings
|
||||
|
||||
### Step 6: Preview and Export
|
||||
1. Review generated content
|
||||
2. Make adjustments if needed
|
||||
3. Export in your preferred format
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Content Creation
|
||||
- Keep event names clear and engaging
|
||||
- Use specific dates and times
|
||||
- Include all essential event details
|
||||
- Add clear call-to-action
|
||||
- Use relevant hashtags
|
||||
|
||||
### Engagement
|
||||
- Enable RSVP functionality
|
||||
- Add interactive elements
|
||||
- Include social sharing options
|
||||
- Use engagement prompts
|
||||
- Set up reminders
|
||||
|
||||
### Media
|
||||
- Use high-quality images
|
||||
- Maintain brand consistency
|
||||
- Optimize for mobile viewing
|
||||
- Include visual hierarchy
|
||||
- Use appropriate aspect ratios
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
- Modern web browser
|
||||
- Internet connection
|
||||
- API keys for AI providers
|
||||
- Sufficient storage for media files
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
- **Content not generating**: Check required fields
|
||||
- **Images not appearing**: Verify API keys
|
||||
- **Export failures**: Check file permissions
|
||||
- **Validation errors**: Review input fields
|
||||
|
||||
### Getting Help
|
||||
For additional support:
|
||||
1. Check the documentation
|
||||
2. Contact support team
|
||||
3. Visit our help center
|
||||
4. Join our community forum
|
||||
|
||||
## Future Updates
|
||||
|
||||
### Planned Features
|
||||
- Advanced analytics
|
||||
- A/B testing
|
||||
- Multi-language support
|
||||
- Template library
|
||||
- Integration with calendar apps
|
||||
- Automated scheduling
|
||||
- Performance tracking
|
||||
- Custom branding options
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome feedback and contributions to improve the Event Generator. Please follow our contribution guidelines and submit pull requests to our repository.
|
||||
|
||||
## License
|
||||
|
||||
This tool is part of the ALwrity AI Writer suite and is subject to the same licensing terms.
|
||||
|
||||
---
|
||||
@@ -1,9 +0,0 @@
|
||||
"""
|
||||
Facebook Event Generator Module
|
||||
|
||||
This module provides functionality to generate engaging Facebook event descriptions.
|
||||
"""
|
||||
|
||||
from .event_generator import write_fb_event
|
||||
|
||||
__all__ = ['write_fb_event']
|
||||
@@ -1,776 +0,0 @@
|
||||
"""
|
||||
Facebook Event Generator Module
|
||||
|
||||
This module provides functionality to generate engaging Facebook event descriptions with various features
|
||||
and customization options.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
from datetime import datetime, date, time
|
||||
import json
|
||||
import os
|
||||
from typing import Dict, Any, List, Optional, Union, Tuple
|
||||
from loguru import logger
|
||||
import sys
|
||||
import base64
|
||||
from io import BytesIO
|
||||
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from .....gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
|
||||
|
||||
# Configure logging
|
||||
logger.remove()
|
||||
logger.add(sys.stdout,
|
||||
colorize=True,
|
||||
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
|
||||
)
|
||||
|
||||
def initialize_session_state():
|
||||
"""Initialize session state with default values."""
|
||||
if 'event_data' not in st.session_state:
|
||||
st.session_state.event_data = {
|
||||
'basic_info': {},
|
||||
'content': {},
|
||||
'media': {},
|
||||
'engagement': {},
|
||||
'analytics': {}
|
||||
}
|
||||
|
||||
# Initialize individual fields with default values that match selectbox options
|
||||
defaults = {
|
||||
'event_type': "Physical Event",
|
||||
'event_category': "Business",
|
||||
'timezone': "UTC",
|
||||
'platform': "Zoom",
|
||||
'description_type': "Basic",
|
||||
'content_style': "Professional",
|
||||
'cover_image_style': "Modern",
|
||||
'color_scheme': "#1877F2",
|
||||
'image_ratio': "16:9",
|
||||
'image_quality': "High",
|
||||
'event_name': "",
|
||||
'event_date': date.today(),
|
||||
'event_time': time(12, 0), # Default to noon
|
||||
'venue_name': "",
|
||||
'street_address': "",
|
||||
'city': "",
|
||||
'country': "",
|
||||
'meeting_link': "",
|
||||
'meeting_id': "",
|
||||
'passcode': "",
|
||||
'key_points': "",
|
||||
'target_audience': "",
|
||||
'event_goal': "",
|
||||
'engagement_prompts': ""
|
||||
}
|
||||
|
||||
for field, default_value in defaults.items():
|
||||
if field not in st.session_state:
|
||||
st.session_state[field] = default_value
|
||||
|
||||
def write_fb_event():
|
||||
"""Generate an engaging Facebook event description with various features and customization options."""
|
||||
|
||||
# Initialize session state
|
||||
initialize_session_state()
|
||||
|
||||
st.markdown("""
|
||||
### 📅 Facebook Event Generator
|
||||
Create compelling event descriptions that drive attendance and engagement. Customize your event
|
||||
with various features and get AI-powered suggestions for optimal performance.
|
||||
""")
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3, tab4, tab5 = st.tabs(["Event Details", "Content & Media", "Engagement", "Analytics", "Preview & Export"])
|
||||
|
||||
with tab1:
|
||||
render_event_details_tab()
|
||||
|
||||
with tab2:
|
||||
render_content_media_tab()
|
||||
|
||||
with tab3:
|
||||
render_engagement_tab()
|
||||
|
||||
with tab4:
|
||||
render_analytics_tab()
|
||||
|
||||
with tab5:
|
||||
render_preview_export_tab()
|
||||
|
||||
def render_event_details_tab():
|
||||
"""Render the event details tab with input fields."""
|
||||
|
||||
# Basic Event Information
|
||||
st.markdown("#### Basic Event Information")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
event_types = ["Physical Event", "Online Event", "Hybrid Event"]
|
||||
event_type = st.selectbox(
|
||||
"Event Type",
|
||||
options=event_types,
|
||||
index=event_types.index(st.session_state.event_type) if st.session_state.event_type in event_types else 0,
|
||||
help="Select the type of event you're creating",
|
||||
key="event_type"
|
||||
)
|
||||
|
||||
event_name = st.text_input(
|
||||
"Event Name",
|
||||
value=st.session_state.event_name,
|
||||
help="Enter a catchy and descriptive name for your event",
|
||||
key="event_name"
|
||||
)
|
||||
|
||||
event_categories = ["Business", "Education", "Entertainment", "Sports", "Community", "Other"]
|
||||
event_category = st.selectbox(
|
||||
"Event Category",
|
||||
options=event_categories,
|
||||
index=event_categories.index(st.session_state.event_category) if st.session_state.event_category in event_categories else 0,
|
||||
help="Select the category that best describes your event",
|
||||
key="event_category"
|
||||
)
|
||||
|
||||
with col2:
|
||||
# Handle date input without conflicting with session state
|
||||
if "event_date" not in st.session_state:
|
||||
st.session_state.event_date = date.today()
|
||||
|
||||
event_date = st.date_input(
|
||||
"Event Date",
|
||||
min_value=date.today(),
|
||||
help="Select the date of your event",
|
||||
key="event_date"
|
||||
)
|
||||
|
||||
# Handle time input without conflicting with session state
|
||||
if "event_time" not in st.session_state:
|
||||
st.session_state.event_time = time(12, 0)
|
||||
|
||||
event_time = st.time_input(
|
||||
"Event Time",
|
||||
help="Select the time of your event",
|
||||
key="event_time"
|
||||
)
|
||||
|
||||
timezones = ["UTC", "EST", "PST", "GMT", "IST"]
|
||||
timezone = st.selectbox(
|
||||
"Timezone",
|
||||
options=timezones,
|
||||
index=timezones.index(st.session_state.timezone) if st.session_state.timezone in timezones else 0,
|
||||
help="Select the timezone for your event",
|
||||
key="timezone"
|
||||
)
|
||||
|
||||
# Location Details
|
||||
st.markdown("#### Location Details")
|
||||
|
||||
if event_type in ["Physical Event", "Hybrid Event"]:
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
venue_name = st.text_input(
|
||||
"Venue Name",
|
||||
value=st.session_state.venue_name,
|
||||
help="Enter the name of the venue",
|
||||
key="venue_name"
|
||||
)
|
||||
|
||||
street_address = st.text_input(
|
||||
"Street Address",
|
||||
value=st.session_state.street_address,
|
||||
help="Enter the street address",
|
||||
key="street_address"
|
||||
)
|
||||
|
||||
with col2:
|
||||
city = st.text_input(
|
||||
"City",
|
||||
value=st.session_state.city,
|
||||
help="Enter the city",
|
||||
key="city"
|
||||
)
|
||||
|
||||
country = st.text_input(
|
||||
"Country",
|
||||
value=st.session_state.country,
|
||||
help="Enter the country",
|
||||
key="country"
|
||||
)
|
||||
|
||||
if event_type in ["Online Event", "Hybrid Event"]:
|
||||
st.markdown("#### Online Event Details")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
platforms = ["Zoom", "Google Meet", "Microsoft Teams", "Facebook Live", "Other"]
|
||||
platform = st.selectbox(
|
||||
"Platform",
|
||||
options=platforms,
|
||||
index=platforms.index(st.session_state.platform) if st.session_state.platform in platforms else 0,
|
||||
help="Select the platform for your online event",
|
||||
key="platform"
|
||||
)
|
||||
|
||||
meeting_link = st.text_input(
|
||||
"Meeting Link",
|
||||
value=st.session_state.meeting_link,
|
||||
help="Enter the meeting link (optional)",
|
||||
key="meeting_link"
|
||||
)
|
||||
|
||||
with col2:
|
||||
meeting_id = st.text_input(
|
||||
"Meeting ID",
|
||||
value=st.session_state.meeting_id,
|
||||
help="Enter the meeting ID (optional)",
|
||||
key="meeting_id"
|
||||
)
|
||||
|
||||
passcode = st.text_input(
|
||||
"Passcode",
|
||||
value=st.session_state.passcode,
|
||||
help="Enter the passcode (optional)",
|
||||
key="passcode"
|
||||
)
|
||||
|
||||
# Event Description
|
||||
st.markdown("#### Event Description")
|
||||
|
||||
description_types = ["Basic", "Detailed", "Professional"]
|
||||
description_type = st.radio(
|
||||
"Description Type",
|
||||
options=description_types,
|
||||
index=description_types.index(st.session_state.description_type) if st.session_state.description_type in description_types else 0,
|
||||
help="Select the level of detail for your event description",
|
||||
key="description_type"
|
||||
)
|
||||
|
||||
key_points = st.text_area(
|
||||
"Key Points to Include",
|
||||
value=st.session_state.key_points,
|
||||
help="Enter key points that should be included in the event description",
|
||||
height=100,
|
||||
key="key_points"
|
||||
)
|
||||
|
||||
target_audience = st.text_input(
|
||||
"Target Audience",
|
||||
value=st.session_state.target_audience,
|
||||
help="Describe your target audience",
|
||||
key="target_audience"
|
||||
)
|
||||
|
||||
event_goal = st.text_area(
|
||||
"Event Goal",
|
||||
value=st.session_state.event_goal,
|
||||
help="What do you want to achieve with this event?",
|
||||
height=100,
|
||||
key="event_goal"
|
||||
)
|
||||
|
||||
def render_content_media_tab():
|
||||
"""Render the content and media tab with customization options."""
|
||||
|
||||
st.markdown("#### Content Customization")
|
||||
|
||||
# Template Selection
|
||||
st.markdown("##### Template Selection")
|
||||
|
||||
template_type = st.selectbox(
|
||||
"Template Type",
|
||||
["Custom", "Conference", "Workshop", "Webinar", "Networking", "Product Launch", "Fundraiser"],
|
||||
help="Select a template type for your event"
|
||||
)
|
||||
|
||||
# Content Style - Move this after template selection
|
||||
content_styles = ["Professional", "Casual", "Formal", "Engaging", "Educational"]
|
||||
default_style = "Professional"
|
||||
|
||||
# Set default style based on template
|
||||
if template_type != "Custom":
|
||||
if template_type == "Conference":
|
||||
default_style = "Professional"
|
||||
elif template_type == "Workshop":
|
||||
default_style = "Educational"
|
||||
elif template_type == "Webinar":
|
||||
default_style = "Professional"
|
||||
elif template_type == "Networking":
|
||||
default_style = "Casual"
|
||||
elif template_type == "Product Launch":
|
||||
default_style = "Engaging"
|
||||
elif template_type == "Fundraiser":
|
||||
default_style = "Engaging"
|
||||
|
||||
content_style = st.selectbox(
|
||||
"Content Style",
|
||||
content_styles,
|
||||
index=content_styles.index(default_style),
|
||||
help="Select the style of your event description",
|
||||
key="content_style"
|
||||
)
|
||||
|
||||
# Content Elements
|
||||
st.markdown("##### Content Elements")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
include_agenda = st.checkbox("Include Agenda", value=True)
|
||||
include_speakers = st.checkbox("Include Speakers", value=True)
|
||||
include_benefits = st.checkbox("Include Benefits", value=True)
|
||||
include_requirements = st.checkbox("Include Requirements", value=True)
|
||||
|
||||
with col2:
|
||||
include_faq = st.checkbox("Include FAQ", value=True)
|
||||
include_testimonials = st.checkbox("Include Testimonials", value=True)
|
||||
include_sponsors = st.checkbox("Include Sponsors", value=True)
|
||||
include_highlights = st.checkbox("Include Event Highlights", value=True)
|
||||
|
||||
# Media Options
|
||||
st.markdown("#### Media Options")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
cover_image_style = st.selectbox(
|
||||
"Cover Image Style",
|
||||
["Modern", "Professional", "Creative", "Minimalist", "Bold"],
|
||||
help="Select the style for your event cover image",
|
||||
key="cover_image_style"
|
||||
)
|
||||
|
||||
color_scheme = st.color_picker(
|
||||
"Brand Color",
|
||||
"#1877F2",
|
||||
help="Select your brand color for the event",
|
||||
key="color_scheme"
|
||||
)
|
||||
|
||||
with col2:
|
||||
image_ratio = st.selectbox(
|
||||
"Image Ratio",
|
||||
["16:9", "1:1", "4:3"],
|
||||
help="Select the aspect ratio for your images",
|
||||
key="image_ratio"
|
||||
)
|
||||
|
||||
image_quality = st.select_slider(
|
||||
"Image Quality",
|
||||
options=["Low", "Medium", "High"],
|
||||
value="High",
|
||||
help="Select the quality for generated images",
|
||||
key="image_quality"
|
||||
)
|
||||
|
||||
def render_engagement_tab():
|
||||
"""Render the engagement tab with interactive elements."""
|
||||
|
||||
st.markdown("#### Engagement Features")
|
||||
|
||||
# Interactive Elements
|
||||
st.markdown("##### Interactive Elements")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
# Enhanced Poll Options
|
||||
use_poll = st.checkbox("Add Poll", value=False)
|
||||
if use_poll:
|
||||
poll_type = st.selectbox(
|
||||
"Poll Type",
|
||||
["Multiple Choice", "Rating", "Open-ended", "Ranking"]
|
||||
)
|
||||
poll_questions = st.text_area(
|
||||
"Poll Questions",
|
||||
help="Enter poll questions (one per line)",
|
||||
height=100
|
||||
)
|
||||
poll_duration = st.number_input(
|
||||
"Poll Duration (days)",
|
||||
min_value=1,
|
||||
max_value=30,
|
||||
value=7
|
||||
)
|
||||
|
||||
# Enhanced Quiz Options
|
||||
use_quiz = st.checkbox("Add Quiz", value=False)
|
||||
if use_quiz:
|
||||
quiz_type = st.selectbox(
|
||||
"Quiz Type",
|
||||
["Trivia", "Personality", "Knowledge Check"]
|
||||
)
|
||||
quiz_questions = st.text_area(
|
||||
"Quiz Questions",
|
||||
help="Enter quiz questions (one per line)",
|
||||
height=100
|
||||
)
|
||||
quiz_rewards = st.text_input(
|
||||
"Quiz Rewards",
|
||||
help="Enter rewards for quiz completion"
|
||||
)
|
||||
|
||||
use_countdown = st.checkbox("Add Countdown", value=False)
|
||||
|
||||
with col2:
|
||||
# Enhanced RSVP Options
|
||||
use_rsvp = st.checkbox("Enable RSVP", value=True)
|
||||
if use_rsvp:
|
||||
rsvp_options = st.multiselect(
|
||||
"RSVP Options",
|
||||
["Attending", "Maybe", "Not Attending", "Bring a Guest"]
|
||||
)
|
||||
rsvp_limit = st.number_input(
|
||||
"RSVP Limit",
|
||||
min_value=0,
|
||||
value=0,
|
||||
help="0 for unlimited"
|
||||
)
|
||||
rsvp_deadline = st.date_input(
|
||||
"RSVP Deadline",
|
||||
min_value=date.today()
|
||||
)
|
||||
|
||||
use_reminder = st.checkbox("Enable Reminders", value=True)
|
||||
if use_reminder:
|
||||
reminder_times = st.multiselect(
|
||||
"Reminder Times",
|
||||
["1 day before", "1 hour before", "15 minutes before", "Custom"]
|
||||
)
|
||||
if "Custom" in reminder_times:
|
||||
custom_reminder = st.text_input(
|
||||
"Custom Reminder Time",
|
||||
help="Format: X days/hours/minutes before"
|
||||
)
|
||||
|
||||
use_feedback = st.checkbox("Enable Feedback Form", value=True)
|
||||
|
||||
# Social Sharing
|
||||
st.markdown("##### Social Sharing")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
include_hashtags = st.checkbox("Include Hashtags", value=True)
|
||||
if include_hashtags:
|
||||
hashtag_count = st.slider(
|
||||
"Number of Hashtags",
|
||||
min_value=1,
|
||||
max_value=10,
|
||||
value=5
|
||||
)
|
||||
custom_hashtags = st.text_input(
|
||||
"Custom Hashtags",
|
||||
help="Enter custom hashtags (comma separated)"
|
||||
)
|
||||
|
||||
include_social_links = st.checkbox("Include Social Links", value=True)
|
||||
|
||||
with col2:
|
||||
include_share_buttons = st.checkbox("Include Share Buttons", value=True)
|
||||
include_invite_friends = st.checkbox("Include Invite Friends", value=True)
|
||||
|
||||
# Engagement Prompts
|
||||
st.markdown("##### Engagement Prompts")
|
||||
|
||||
engagement_prompts = st.text_area(
|
||||
"Custom Engagement Prompts",
|
||||
help="Enter custom prompts to encourage engagement",
|
||||
height=100,
|
||||
key="engagement_prompts"
|
||||
)
|
||||
|
||||
# Language Options
|
||||
st.markdown("##### Language Options")
|
||||
|
||||
language = st.selectbox(
|
||||
"Event Language",
|
||||
["English", "Spanish", "French", "German", "Italian", "Portuguese", "Chinese", "Japanese", "Korean", "Other"]
|
||||
)
|
||||
|
||||
if language != "English":
|
||||
st.info(f"Event description will be generated in {language}. You can still input details in English.")
|
||||
|
||||
def render_analytics_tab():
|
||||
"""Render the analytics tab with insights and predictions."""
|
||||
|
||||
st.markdown("#### Analytics & Insights")
|
||||
|
||||
# Engagement Prediction
|
||||
st.markdown("##### Engagement Prediction")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
st.markdown("**Predicted Engagement Metrics**")
|
||||
|
||||
# Generate mock predictions based on input
|
||||
if st.session_state.event_name and st.session_state.target_audience:
|
||||
predicted_rsvp = min(100, max(10, len(st.session_state.event_name) * 5))
|
||||
predicted_views = predicted_rsvp * 10
|
||||
predicted_engagement = min(100, max(20, predicted_rsvp * 0.8))
|
||||
|
||||
st.metric("Predicted RSVPs", f"{predicted_rsvp}")
|
||||
st.metric("Predicted Views", f"{predicted_views}")
|
||||
st.metric("Predicted Engagement Rate", f"{predicted_engagement}%")
|
||||
else:
|
||||
st.info("Fill in event details to see engagement predictions")
|
||||
|
||||
with col2:
|
||||
st.markdown("**Engagement Factors**")
|
||||
|
||||
factors = {
|
||||
"Event Name": 85,
|
||||
"Description Quality": 90,
|
||||
"Visual Appeal": 75,
|
||||
"Timing": 80,
|
||||
"Target Audience Match": 95
|
||||
}
|
||||
|
||||
for factor, score in factors.items():
|
||||
st.progress(score / 100)
|
||||
st.text(f"{factor}: {score}%")
|
||||
|
||||
# Best Practices
|
||||
st.markdown("##### Best Practices")
|
||||
|
||||
best_practices = [
|
||||
"Use clear, action-oriented language in your event title",
|
||||
"Include all essential details in the first 3 sentences",
|
||||
"Add visual elements to increase engagement",
|
||||
"Use hashtags strategically (3-5 is optimal)",
|
||||
"Include a clear call-to-action",
|
||||
"Optimize for mobile viewing",
|
||||
"Post at optimal times (typically 1-3pm on weekdays)"
|
||||
]
|
||||
|
||||
for practice in best_practices:
|
||||
st.markdown(f"✅ {practice}")
|
||||
|
||||
# A/B Testing Suggestions
|
||||
st.markdown("##### A/B Testing Suggestions")
|
||||
|
||||
if st.button("Generate A/B Testing Ideas"):
|
||||
st.markdown("**Title Variations:**")
|
||||
st.markdown(f"1. {st.session_state.event_name}")
|
||||
st.markdown(f"2. {st.session_state.event_name} - Don't Miss Out!")
|
||||
st.markdown(f"3. Join Us: {st.session_state.event_name}")
|
||||
|
||||
st.markdown("**Description Variations:**")
|
||||
st.markdown("1. Focus on benefits and outcomes")
|
||||
st.markdown("2. Focus on problem-solving and solutions")
|
||||
st.markdown("3. Focus on community and networking")
|
||||
|
||||
st.markdown("**Visual Variations:**")
|
||||
st.markdown("1. Use brand colors prominently")
|
||||
st.markdown("2. Use contrasting colors for attention")
|
||||
st.markdown("3. Use minimal design with focus on text")
|
||||
|
||||
def render_preview_export_tab():
|
||||
"""Render the preview and export tab."""
|
||||
|
||||
st.markdown("#### Preview & Export")
|
||||
|
||||
# Preview Options
|
||||
preview_type = st.radio(
|
||||
"Preview Type",
|
||||
["Mobile", "Desktop", "Social Cards", "All"]
|
||||
)
|
||||
|
||||
# Generate Event Button
|
||||
if st.button("🚀 Generate Event Description", key="generate_event"):
|
||||
with st.spinner("Generating your event description..."):
|
||||
# Validate required fields
|
||||
if not validate_event_fields():
|
||||
return
|
||||
|
||||
# Generate event description
|
||||
event_description = generate_event_description()
|
||||
|
||||
# Store in session state
|
||||
st.session_state.event_description = event_description
|
||||
|
||||
# Display preview based on selection
|
||||
if preview_type == "Mobile" or preview_type == "All":
|
||||
st.markdown("##### Mobile Preview")
|
||||
st.markdown("""
|
||||
<div style="border: 1px solid #ddd; border-radius: 10px; padding: 15px; max-width: 375px; margin: 0 auto; background-color: #f9f9f9;">
|
||||
<h3 style="margin-top: 0;">{}</h3>
|
||||
<p style="color: #666;">{} at {}</p>
|
||||
<div style="margin: 15px 0;">
|
||||
{}
|
||||
</div>
|
||||
</div>
|
||||
""".format(
|
||||
st.session_state.event_name,
|
||||
st.session_state.event_date.strftime("%B %d, %Y"),
|
||||
st.session_state.event_time.strftime("%I:%M %p"),
|
||||
event_description
|
||||
), unsafe_allow_html=True)
|
||||
|
||||
if preview_type == "Desktop" or preview_type == "All":
|
||||
st.markdown("##### Desktop Preview")
|
||||
st.markdown("""
|
||||
<div style="border: 1px solid #ddd; border-radius: 10px; padding: 20px; max-width: 600px; margin: 0 auto; background-color: #f9f9f9;">
|
||||
<h2 style="margin-top: 0;">{}</h2>
|
||||
<p style="color: #666;">{} at {}</p>
|
||||
<div style="margin: 20px 0;">
|
||||
{}
|
||||
</div>
|
||||
</div>
|
||||
""".format(
|
||||
st.session_state.event_name,
|
||||
st.session_state.event_date.strftime("%B %d, %Y"),
|
||||
st.session_state.event_time.strftime("%I:%M %p"),
|
||||
event_description
|
||||
), unsafe_allow_html=True)
|
||||
|
||||
if preview_type == "Social Cards" or preview_type == "All":
|
||||
st.markdown("##### Social Cards Preview")
|
||||
st.markdown("""
|
||||
<div style="border: 1px solid #ddd; border-radius: 10px; padding: 15px; max-width: 500px; margin: 0 auto; background-color: #f9f9f9;">
|
||||
<h3 style="margin-top: 0;">{}</h3>
|
||||
<p style="color: #666;">{} at {}</p>
|
||||
<div style="margin: 15px 0;">
|
||||
{}
|
||||
</div>
|
||||
</div>
|
||||
""".format(
|
||||
st.session_state.event_name,
|
||||
st.session_state.event_date.strftime("%B %d, %Y"),
|
||||
st.session_state.event_time.strftime("%I:%M %p"),
|
||||
event_description[:200] + "..." if len(event_description) > 200 else event_description
|
||||
), unsafe_allow_html=True)
|
||||
|
||||
# Export options
|
||||
st.markdown("#### Export Options")
|
||||
|
||||
col1, col2, col3 = st.columns(3)
|
||||
|
||||
with col1:
|
||||
if st.button("📋 Copy to Clipboard"):
|
||||
st.code(event_description)
|
||||
st.success("Event description copied to clipboard!")
|
||||
|
||||
with col2:
|
||||
if st.button("💾 Download as Text"):
|
||||
download_event_description(event_description)
|
||||
|
||||
with col3:
|
||||
if st.button("📅 Export to Calendar"):
|
||||
st.info("Calendar export feature coming soon!")
|
||||
|
||||
def validate_event_fields() -> bool:
|
||||
"""Validate required event fields with enhanced validation."""
|
||||
validation_rules = {
|
||||
"Event Name": {
|
||||
"required": True,
|
||||
"min_length": 5,
|
||||
"max_length": 100,
|
||||
"type": str
|
||||
},
|
||||
"Event Date": {
|
||||
"required": True,
|
||||
"min_date": date.today(),
|
||||
"type": Union[date, type(None)]
|
||||
},
|
||||
"Target Audience": {
|
||||
"required": True,
|
||||
"min_length": 10,
|
||||
"type": str
|
||||
},
|
||||
"Event Goal": {
|
||||
"required": True,
|
||||
"min_length": 20,
|
||||
"type": str
|
||||
}
|
||||
}
|
||||
|
||||
errors = []
|
||||
for field, rules in validation_rules.items():
|
||||
field_key = field.lower().replace(" ", "_")
|
||||
value = st.session_state.get(field_key)
|
||||
|
||||
# Skip validation if field is not required and value is empty
|
||||
if not rules["required"] and (value is None or value == ""):
|
||||
continue
|
||||
|
||||
# Type validation
|
||||
if "type" in rules and value is not None:
|
||||
expected_type = rules["type"]
|
||||
if not isinstance(value, expected_type):
|
||||
errors.append(f"{field} must be of type {expected_type}")
|
||||
continue
|
||||
|
||||
# Required field validation
|
||||
if rules["required"] and (value is None or value == ""):
|
||||
errors.append(f"{field} is required")
|
||||
continue
|
||||
|
||||
# Length validation for strings
|
||||
if isinstance(value, str):
|
||||
if "min_length" in rules and len(value) < rules["min_length"]:
|
||||
errors.append(f"{field} must be at least {rules['min_length']} characters")
|
||||
if "max_length" in rules and len(value) > rules["max_length"]:
|
||||
errors.append(f"{field} must be less than {rules['max_length']} characters")
|
||||
|
||||
# Date validation
|
||||
if isinstance(value, date):
|
||||
if "min_date" in rules and value < rules["min_date"]:
|
||||
errors.append(f"{field} must be in the future")
|
||||
|
||||
if errors:
|
||||
st.error("\n".join(errors))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def generate_event_description() -> str:
|
||||
"""Generate the event description using AI with enhanced features."""
|
||||
prompt = f"""
|
||||
Create a compelling Facebook event description for:
|
||||
|
||||
Event Name: {st.session_state.get('event_name', '')}
|
||||
Event Type: {st.session_state.get('event_type', '')}
|
||||
Event Category: {st.session_state.get('event_category', '')}
|
||||
Date & Time: {st.session_state.get('event_date', '')} at {st.session_state.get('event_time', '')}
|
||||
Target Audience: {st.session_state.get('target_audience', '')}
|
||||
Event Goal: {st.session_state.get('event_goal', '')}
|
||||
|
||||
Key Points to Include: {st.session_state.get('key_points', '')}
|
||||
|
||||
Style: {st.session_state.get('content_style', '')}
|
||||
|
||||
Additional Requirements:
|
||||
1. Include SEO-optimized keywords
|
||||
2. Add emoji suggestions for key points
|
||||
3. Include trending hashtags in the event category
|
||||
4. Add engagement hooks at strategic points
|
||||
5. Include social proof elements
|
||||
6. Add urgency triggers
|
||||
7. Include mobile-optimized formatting
|
||||
8. Add accessibility considerations
|
||||
|
||||
Format the description with:
|
||||
- Engaging opening
|
||||
- Clear event details
|
||||
- Key benefits
|
||||
- Call to action
|
||||
- Relevant hashtags
|
||||
"""
|
||||
|
||||
try:
|
||||
response = llm_text_gen(prompt)
|
||||
return response
|
||||
except Exception as err:
|
||||
st.error(f"An error occurred while generating the event description: {err}")
|
||||
return ""
|
||||
|
||||
def download_event_description(content: str):
|
||||
"""Download the event description as a text file."""
|
||||
# Create a download link
|
||||
b64 = base64.b64encode(content.encode()).decode()
|
||||
href = f'<a href="data:file/txt;base64,{b64}" download="event_description.txt">Download Event Description</a>'
|
||||
st.markdown(href, unsafe_allow_html=True)
|
||||
@@ -1,164 +0,0 @@
|
||||
# Facebook Carousel Generator 🔄
|
||||
|
||||
Welcome to the Facebook Carousel Generator! This powerful tool helps you create engaging, professional-looking carousel posts for Facebook with AI-powered content and visuals.
|
||||
|
||||
## What is a Facebook Carousel? 🤔
|
||||
|
||||
A Facebook carousel is a post format that allows you to showcase up to 10 images or videos in a single post, each with its own caption. Users can swipe through the content, making it perfect for:
|
||||
- Showcasing multiple products
|
||||
- Telling a story
|
||||
- Sharing step-by-step tutorials
|
||||
- Highlighting features and benefits
|
||||
- Displaying before-and-after transformations
|
||||
|
||||
## Features ✨
|
||||
|
||||
### 1. Content Setup 📝
|
||||
- **Business Profile**: Customize content for your specific industry
|
||||
- **Target Audience**: Define who you want to reach
|
||||
- **Purpose Selection**: Choose from multiple carousel purposes:
|
||||
- Product Showcase
|
||||
- How-to Guide
|
||||
- Before and After
|
||||
- Features/Benefits
|
||||
- Customer Success Stories
|
||||
- Product Collection
|
||||
- Service Overview
|
||||
- Educational Series
|
||||
- Brand Story
|
||||
|
||||
### 2. Carousel Structure 🏗️
|
||||
Choose from various storytelling formats:
|
||||
- Progressive Story
|
||||
- Feature Showcase
|
||||
- Step-by-Step Guide
|
||||
- Problem-Solution
|
||||
- Collection Display
|
||||
- Before-After Series
|
||||
- FAQ Format
|
||||
- Tips & Tricks
|
||||
|
||||
### 3. Visual Elements 🎨
|
||||
Customize your carousel's look:
|
||||
- Visual styles (Modern, Bold, Minimalist, etc.)
|
||||
- Color schemes
|
||||
- Brand color integration
|
||||
- Image styles
|
||||
- Text overlays
|
||||
- Font selections
|
||||
- Composition options
|
||||
|
||||
### 4. AI-Powered Generation 🤖
|
||||
The tool automatically creates:
|
||||
- Engaging captions
|
||||
- Slide content
|
||||
- Image suggestions
|
||||
- Hashtag recommendations
|
||||
- Engagement prompts
|
||||
|
||||
## How to Use 📱
|
||||
|
||||
### Step 1: Content Setup
|
||||
1. Enter your business type and target audience
|
||||
2. Select your carousel purpose
|
||||
3. Choose your brand voice
|
||||
4. Enter your key message
|
||||
5. Select number of slides (2-10)
|
||||
6. Pick your preferred carousel structure
|
||||
|
||||
### Step 2: Customize Content
|
||||
Select what to include:
|
||||
- Statistics/Facts
|
||||
- Testimonials
|
||||
- Pricing
|
||||
- Call-to-Action
|
||||
- Hashtags
|
||||
- Emojis
|
||||
- Questions
|
||||
- Bullet Points
|
||||
- Numbered Lists
|
||||
|
||||
### Step 3: Visual Design
|
||||
1. Choose your visual style
|
||||
2. Select color scheme
|
||||
3. Pick image style
|
||||
4. Configure text overlays (optional)
|
||||
5. Customize composition
|
||||
|
||||
### Step 4: Preview & Export
|
||||
View your carousel in:
|
||||
- Mobile preview
|
||||
- Desktop preview
|
||||
- Content overview
|
||||
- Download options:
|
||||
- Complete ZIP package
|
||||
- Individual files
|
||||
- With posting guidelines
|
||||
|
||||
## Best Practices 💡
|
||||
|
||||
### Carousel Tips
|
||||
1. **Keep it Consistent**: Maintain visual consistency across all slides
|
||||
2. **Start Strong**: Put your best image first to grab attention
|
||||
3. **Tell a Story**: Make slides flow naturally from one to the next
|
||||
4. **Clear CTAs**: Include clear call-to-actions
|
||||
5. **Mobile-First**: Design with mobile viewing in mind
|
||||
|
||||
### Posting Tips
|
||||
1. **Best Times**: Post between 1-4 PM on weekdays
|
||||
2. **Hashtags**: Use all provided hashtags for maximum reach
|
||||
3. **Engagement**: Respond to comments within the first hour
|
||||
4. **Cross-Promote**: Share to Stories after posting
|
||||
5. **Monitor**: Track performance for the first 24 hours
|
||||
|
||||
## Export Options 💾
|
||||
|
||||
### 1. Complete Package (ZIP)
|
||||
Includes:
|
||||
- All carousel images
|
||||
- Main caption
|
||||
- Individual slide captions
|
||||
- Hashtags file
|
||||
- Engagement prompts
|
||||
- Posting guidelines
|
||||
- Metadata
|
||||
|
||||
### 2. Individual Files
|
||||
Download separately:
|
||||
- Individual images
|
||||
- Caption text
|
||||
- Hashtags list
|
||||
- Engagement prompts
|
||||
|
||||
### 3. Posting Guidelines
|
||||
Receive detailed instructions on:
|
||||
- How to upload your carousel
|
||||
- Best posting practices
|
||||
- Engagement strategies
|
||||
- Performance monitoring tips
|
||||
|
||||
## Need Help? 🆘
|
||||
|
||||
If you encounter any issues or have questions:
|
||||
1. Check the preview before generating final images
|
||||
2. Ensure all required fields are filled
|
||||
3. Try different visual styles if the first attempt isn't perfect
|
||||
4. Experiment with different carousel structures
|
||||
|
||||
## Pro Tips 🌟
|
||||
|
||||
1. **Planning**: Plan your carousel story before starting
|
||||
2. **Branding**: Use your brand colors for consistency
|
||||
3. **Testing**: Preview on both mobile and desktop
|
||||
4. **Engagement**: Use the provided engagement prompts
|
||||
5. **Analytics**: Save successful carousels as templates
|
||||
|
||||
## Technical Requirements 🔧
|
||||
|
||||
- Stable internet connection
|
||||
- Web browser (Chrome, Firefox, Safari, or Edge)
|
||||
- Facebook Business Page (for posting)
|
||||
|
||||
Remember: The better the input, the better the output! Take time to fill in all relevant information for the best results.
|
||||
|
||||
Happy creating! 🎨✨
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,145 +0,0 @@
|
||||
# Facebook Reel Generator
|
||||
|
||||
## Overview
|
||||
|
||||
The Facebook Reel Generator is a powerful AI-powered tool designed to help content creators, marketers, and businesses create engaging Facebook Reels content. This tool leverages advanced AI to generate creative scripts, visual concepts, and content strategies optimized for Facebook's short-form video platform.
|
||||
|
||||
## Features
|
||||
|
||||
### Current Features
|
||||
|
||||
#### 1. Reel Content Generation
|
||||
- **Script Generation**: Create complete scripts for Facebook Reels with hooks, main content, and calls-to-action
|
||||
- **Content Structure**: Automatically formats content with proper pacing for short-form video
|
||||
- **Brand Voice Customization**: Adapt content to match your brand's tone and style
|
||||
- **Target Audience Optimization**: Tailor content specifically for your target demographic
|
||||
- **Purpose-Driven Content**: Generate content aligned with specific marketing goals (awareness, engagement, conversion, etc.)
|
||||
|
||||
#### 2. Visual Elements
|
||||
- **Image Generation**: Create custom images for your Reels using AI image generation
|
||||
- **Visual Style Options**: Choose from various visual styles (modern, minimalist, bold, etc.)
|
||||
- **Aspect Ratio Optimization**: Generate images in the optimal 9:16 aspect ratio for Reels
|
||||
- **Image Quality Settings**: Control the quality and detail level of generated images
|
||||
|
||||
#### 3. Advanced Options
|
||||
- **Content Length Control**: Specify preferred length for your Reel content
|
||||
- **Language Style Selection**: Choose from formal, casual, humorous, or other language styles
|
||||
- **AI Provider Selection**: Choose between different AI providers for content generation
|
||||
- **Hashtag Suggestions**: Get relevant hashtag recommendations for your Reels
|
||||
|
||||
### Coming Soon Features
|
||||
|
||||
#### 1. Music Integration
|
||||
- **Trending Music Suggestions**: Get recommendations for popular music tracks
|
||||
- **Music Mood Matching**: Find music that matches your content's emotional tone
|
||||
- **Copyright-Safe Options**: Access royalty-free music suggestions
|
||||
|
||||
#### 2. Video Script Generation
|
||||
- **Shot-by-Shot Breakdown**: Get detailed visual direction for each segment
|
||||
- **Transition Suggestions**: Receive creative transition ideas between scenes
|
||||
- **Visual Effects Recommendations**: Get ideas for filters and effects to enhance your Reel
|
||||
|
||||
#### 3. Performance Optimization
|
||||
- **Trend Analysis**: Identify current trends in your niche for Reel content
|
||||
- **Engagement Prediction**: Get insights on potential performance of your content
|
||||
- **A/B Testing Suggestions**: Receive variations of content to test different approaches
|
||||
|
||||
## How to Use
|
||||
|
||||
### Step 1: Access the Reel Generator
|
||||
1. Navigate to the Facebook AI Writer dashboard
|
||||
2. Select the "FB Reel Generator" card
|
||||
3. Click "Use FB Reel Generator"
|
||||
|
||||
### Step 2: Configure Your Reel Content
|
||||
1. Fill in the basic information:
|
||||
- Business type
|
||||
- Target audience
|
||||
- Reel purpose
|
||||
- Brand voice
|
||||
- Key message
|
||||
- Call to action
|
||||
2. Select content preferences:
|
||||
- Include hashtags
|
||||
- Include hooks
|
||||
- Include trending topics
|
||||
3. Click "Generate Reel Content"
|
||||
|
||||
### Step 3: Customize Visual Elements
|
||||
1. Once your content is generated, navigate to the "Visual Elements" tab
|
||||
2. Select your preferred visual style
|
||||
3. Choose the aspect ratio (9:16 recommended for Reels)
|
||||
4. Adjust image quality settings
|
||||
5. Click "Generate Images"
|
||||
|
||||
### Step 4: Fine-tune with Advanced Options
|
||||
1. Navigate to the "Advanced Options" tab
|
||||
2. Adjust content length preferences
|
||||
3. Select language style
|
||||
4. Choose your preferred AI provider
|
||||
5. Click "Apply Advanced Settings"
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Content Creation
|
||||
- Keep your key message concise and focused
|
||||
- Use action-oriented language in your call to action
|
||||
- Be specific about your target audience to get more relevant content
|
||||
- Experiment with different brand voices to find what resonates with your audience
|
||||
|
||||
### Visual Elements
|
||||
- Use the 9:16 aspect ratio for optimal display on mobile devices
|
||||
- Select visual styles that align with your brand identity
|
||||
- Consider using higher quality settings for more professional-looking images
|
||||
|
||||
### Performance Optimization
|
||||
- Regularly update your content based on performance data
|
||||
- Test different hooks and openings to see what captures attention
|
||||
- Use the suggested hashtags to increase discoverability
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
- A modern web browser (Chrome, Firefox, Safari, or Edge)
|
||||
- Internet connection
|
||||
- API keys for AI providers (OpenAI, Google Gemini, etc.)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
- **Content not generating**: Ensure all required fields are filled out
|
||||
- **Images not appearing**: Check your internet connection and API key status
|
||||
- **Error messages**: Verify that your API keys are valid and have sufficient credits
|
||||
|
||||
### Getting Help
|
||||
If you encounter any issues not covered in this guide, please contact support or check our documentation for additional resources.
|
||||
|
||||
## Future Roadmap
|
||||
|
||||
### Phase 1 (Current)
|
||||
- Basic content generation
|
||||
- Image generation
|
||||
- Advanced customization options
|
||||
|
||||
### Phase 2 (Coming Soon)
|
||||
- Music integration
|
||||
- Video script generation
|
||||
- Performance analytics
|
||||
|
||||
### Phase 3 (Future)
|
||||
- AI-powered video editing suggestions
|
||||
- Audience sentiment analysis
|
||||
- Competitor content analysis
|
||||
- Automated content scheduling
|
||||
- Multi-platform adaptation (Instagram Reels, TikTok)
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome feedback and contributions to improve the Facebook Reel Generator. If you have suggestions for new features or improvements, please reach out to our development team.
|
||||
|
||||
## License
|
||||
|
||||
This tool is part of the ALwrity AI Writer suite and is subject to the same licensing terms.
|
||||
|
||||
---
|
||||
|
||||
*Last updated: April 2025*
|
||||
@@ -1,902 +0,0 @@
|
||||
"""
|
||||
Facebook Reel Generator Module
|
||||
|
||||
This module provides functionality to generate Facebook Reel content using AI.
|
||||
It leverages text and image generation capabilities to create engaging reel content.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import os
|
||||
import sys
|
||||
from loguru import logger
|
||||
from typing import Dict, Any, List, Optional
|
||||
from datetime import datetime
|
||||
|
||||
# Import text generation
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
|
||||
# Import image generation
|
||||
from .....gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
|
||||
|
||||
# Configure logging
|
||||
logger.remove()
|
||||
logger.add(sys.stdout,
|
||||
colorize=True,
|
||||
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
|
||||
)
|
||||
|
||||
def write_fb_reel():
|
||||
"""
|
||||
Main function to render the Facebook Reel Generator UI and handle the generation process.
|
||||
"""
|
||||
# Add back to dashboard button with minimal top margin
|
||||
st.markdown("""
|
||||
<div style='margin-top: 1rem; margin-bottom: 1rem;'>
|
||||
<a href="/" class="streamlit-button" style='text-decoration: none; color: white; background-color: #1877F2; padding: 0.5rem 1rem; border-radius: 0.5rem;'>← Back to Dashboard</a>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Main title card with improved spacing
|
||||
st.markdown("""
|
||||
<div style='background-color: #f0f2f6; padding: 1.5rem; border-radius: 5px; margin-bottom: 1.5rem;'>
|
||||
<div style='display: flex; align-items: center; justify-content: center; margin-bottom: 0.5rem;'>
|
||||
<span style='font-size: 2rem; margin-right: 0.5rem;'>🎥</span>
|
||||
<h1 style='color: #1877F2; margin: 0;'>Facebook Reel Generator</h1>
|
||||
</div>
|
||||
<p style='text-align: center; margin: 0;'>Create engaging Facebook Reels with AI-powered content</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3 = st.tabs(["Reel Content", "Visual Elements", "Advanced Options"])
|
||||
|
||||
with tab1:
|
||||
render_reel_content_tab()
|
||||
|
||||
with tab2:
|
||||
render_visual_elements_tab()
|
||||
|
||||
with tab3:
|
||||
render_advanced_options_tab()
|
||||
|
||||
def render_reel_content_tab():
|
||||
"""Render the Reel Content tab with input fields and generation options."""
|
||||
st.markdown("### Reel Content Settings")
|
||||
|
||||
# Create columns for input fields
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
business_type = st.text_input(
|
||||
"Business/Industry Type",
|
||||
placeholder="e.g., Fashion, Food, Fitness, Tech",
|
||||
help="The type of business or industry you're creating content for"
|
||||
)
|
||||
|
||||
target_audience = st.text_input(
|
||||
"Target Audience",
|
||||
placeholder="e.g., Young professionals, Parents, Fitness enthusiasts",
|
||||
help="Who is your content aimed at?"
|
||||
)
|
||||
|
||||
reel_purpose = st.selectbox(
|
||||
"Reel Purpose",
|
||||
options=[
|
||||
"Product Showcase",
|
||||
"Tutorial/How-to",
|
||||
"Behind the Scenes",
|
||||
"Customer Testimonials",
|
||||
"Brand Story",
|
||||
"Promotion/Offer",
|
||||
"Educational Content",
|
||||
"Entertainment"
|
||||
],
|
||||
help="What is the main purpose of your reel?"
|
||||
)
|
||||
|
||||
with col2:
|
||||
brand_voice = st.selectbox(
|
||||
"Brand Voice/Tone",
|
||||
options=[
|
||||
"Professional",
|
||||
"Casual/Friendly",
|
||||
"Humorous",
|
||||
"Inspirational",
|
||||
"Educational",
|
||||
"Luxury/Elegant",
|
||||
"Energetic",
|
||||
"Relaxed"
|
||||
],
|
||||
help="The tone and voice that represents your brand"
|
||||
)
|
||||
|
||||
key_message = st.text_area(
|
||||
"Key Message",
|
||||
placeholder="What's the main message you want to convey in your reel?",
|
||||
help="The primary message or takeaway for your audience"
|
||||
)
|
||||
|
||||
call_to_action = st.selectbox(
|
||||
"Call to Action",
|
||||
options=[
|
||||
"Follow Us",
|
||||
"Shop Now",
|
||||
"Learn More",
|
||||
"Sign Up",
|
||||
"Share",
|
||||
"Comment",
|
||||
"Save for Later",
|
||||
"Custom"
|
||||
],
|
||||
help="What action do you want viewers to take after watching?"
|
||||
)
|
||||
|
||||
if call_to_action == "Custom":
|
||||
custom_cta = st.text_input(
|
||||
"Custom Call to Action",
|
||||
placeholder="Enter your custom call to action"
|
||||
)
|
||||
else:
|
||||
custom_cta = ""
|
||||
|
||||
# Additional content options
|
||||
st.markdown("### Content Preferences")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
include_hashtags = st.checkbox("Include Hashtag Suggestions", value=True)
|
||||
include_hook = st.checkbox("Include Hook/Opening", value=True)
|
||||
include_transitions = st.checkbox("Include Transition Suggestions", value=True)
|
||||
|
||||
with col2:
|
||||
include_text_overlays = st.checkbox("Include Text Overlay Suggestions", value=True)
|
||||
include_engagement_tips = st.checkbox("Include Engagement Tips", value=True)
|
||||
include_trending_topics = st.checkbox("Include Trending Topics", value=True)
|
||||
|
||||
# Generate button
|
||||
if st.button("Generate Reel Content", type="primary"):
|
||||
if not business_type or not target_audience or not key_message:
|
||||
st.error("Please fill in the required fields: Business Type, Target Audience, and Key Message")
|
||||
return
|
||||
|
||||
with st.spinner("Generating your Facebook Reel content..."):
|
||||
# Generate the reel content
|
||||
reel_content = generate_reel_content(
|
||||
business_type=business_type,
|
||||
target_audience=target_audience,
|
||||
reel_purpose=reel_purpose,
|
||||
brand_voice=brand_voice,
|
||||
key_message=key_message,
|
||||
call_to_action=call_to_action,
|
||||
custom_cta=custom_cta,
|
||||
include_hashtags=include_hashtags,
|
||||
include_hook=include_hook,
|
||||
include_transitions=include_transitions,
|
||||
include_text_overlays=include_text_overlays,
|
||||
include_engagement_tips=include_engagement_tips,
|
||||
include_trending_topics=include_trending_topics
|
||||
)
|
||||
|
||||
# Display the generated content
|
||||
if reel_content:
|
||||
st.markdown("### Generated Reel Content")
|
||||
|
||||
# Create a container with a nice background for the content
|
||||
st.markdown("""
|
||||
<div style='background-color: #f8f9fa; padding: 20px; border-radius: 10px; border-left: 5px solid #1877F2; margin-bottom: 20px;'>
|
||||
<h4 style='color: #1877F2;'>Your Facebook Reel Script</h4>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Parse and display the content in a structured way
|
||||
display_reel_content(reel_content)
|
||||
|
||||
# Add a download button for the content
|
||||
st.download_button(
|
||||
label="Download Reel Content",
|
||||
data=reel_content,
|
||||
file_name=f"facebook_reel_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt",
|
||||
mime="text/plain"
|
||||
)
|
||||
|
||||
# Store the content in session state for the visual elements tab
|
||||
st.session_state['reel_content'] = reel_content
|
||||
else:
|
||||
st.error("Failed to generate reel content. Please try again.")
|
||||
|
||||
def render_visual_elements_tab():
|
||||
"""Render the Visual Elements tab for generating images and visual content."""
|
||||
st.markdown("### Visual Elements for Your Reel")
|
||||
|
||||
# Check if reel content has been generated
|
||||
if 'reel_content' not in st.session_state:
|
||||
st.info("Please generate reel content in the 'Reel Content' tab first.")
|
||||
return
|
||||
|
||||
st.markdown("""
|
||||
<div style='background-color: #f8f9fa; padding: 10px; border-radius: 5px; margin-bottom: 10px;'>
|
||||
<p><strong>Note:</strong> This feature generates visual elements for your reel. Music and video elements are coming soon.</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Visual element options
|
||||
st.markdown("#### Generate Visual Elements")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
visual_style = st.selectbox(
|
||||
"Visual Style",
|
||||
options=[
|
||||
"Modern and Clean",
|
||||
"Bold and Vibrant",
|
||||
"Minimalist",
|
||||
"Playful and Fun",
|
||||
"Professional",
|
||||
"Lifestyle",
|
||||
"Product-Focused",
|
||||
"Custom"
|
||||
],
|
||||
help="The overall visual style for your reel"
|
||||
)
|
||||
|
||||
if visual_style == "Custom":
|
||||
custom_style = st.text_input(
|
||||
"Custom Visual Style",
|
||||
placeholder="Describe your desired visual style"
|
||||
)
|
||||
else:
|
||||
custom_style = ""
|
||||
|
||||
num_images = st.slider(
|
||||
"Number of Images to Generate",
|
||||
min_value=1,
|
||||
max_value=5,
|
||||
value=3,
|
||||
help="How many visual elements would you like to generate?"
|
||||
)
|
||||
|
||||
with col2:
|
||||
image_aspect_ratio = st.selectbox(
|
||||
"Image Aspect Ratio",
|
||||
options=[
|
||||
"9:16 (Vertical - Reel)",
|
||||
"1:1 (Square)",
|
||||
"16:9 (Horizontal)",
|
||||
"4:5 (Instagram Portrait)"
|
||||
],
|
||||
help="The aspect ratio for your visual elements"
|
||||
)
|
||||
|
||||
image_quality = st.select_slider(
|
||||
"Image Quality",
|
||||
options=["Basic", "Standard", "High", "Premium"],
|
||||
value="Standard",
|
||||
help="The quality level for generated images"
|
||||
)
|
||||
|
||||
# Image generation prompt customization
|
||||
st.markdown("#### Customize Image Generation")
|
||||
|
||||
image_prompt_style = st.radio(
|
||||
"Image Prompt Style",
|
||||
options=["Automatic", "Custom"],
|
||||
help="Choose how to generate the image prompts"
|
||||
)
|
||||
|
||||
if image_prompt_style == "Custom":
|
||||
custom_image_prompt = st.text_area(
|
||||
"Custom Image Prompt",
|
||||
placeholder="Enter a custom prompt for image generation",
|
||||
help="Describe what you want the image to look like"
|
||||
)
|
||||
else:
|
||||
custom_image_prompt = ""
|
||||
|
||||
# Generate images button
|
||||
if st.button("Generate Visual Elements", type="primary"):
|
||||
with st.spinner("Generating visual elements for your reel..."):
|
||||
# Generate images based on the reel content
|
||||
images = generate_reel_images(
|
||||
reel_content=st.session_state['reel_content'],
|
||||
visual_style=visual_style,
|
||||
custom_style=custom_style if visual_style == "Custom" else None,
|
||||
num_images=num_images,
|
||||
image_aspect_ratio=image_aspect_ratio,
|
||||
image_quality=image_quality,
|
||||
custom_image_prompt=custom_image_prompt if image_prompt_style == "Custom" else None
|
||||
)
|
||||
|
||||
# Display the generated images
|
||||
if images:
|
||||
st.markdown("### Generated Visual Elements")
|
||||
|
||||
# Display images in a grid
|
||||
cols = st.columns(min(3, len(images)))
|
||||
for i, image_path in enumerate(images):
|
||||
with cols[i % len(cols)]:
|
||||
st.image(image_path, use_container_width=True)
|
||||
st.download_button(
|
||||
label=f"Download Image {i+1}",
|
||||
data=open(image_path, "rb").read(),
|
||||
file_name=f"reel_image_{i+1}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png",
|
||||
mime="image/png"
|
||||
)
|
||||
else:
|
||||
st.error("Failed to generate visual elements. Please try again.")
|
||||
|
||||
# Coming soon features
|
||||
st.markdown("### Coming Soon Features")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
st.markdown("""
|
||||
<div style='background-color: #e9ecef; padding: 15px; border-radius: 5px; margin-bottom: 10px;'>
|
||||
<h4>🎵 Music Suggestions</h4>
|
||||
<p>AI-powered music recommendations that match your reel's mood and content.</p>
|
||||
<span style='background-color: #6c757d; color: white; padding: 2px 8px; border-radius: 10px; font-size: 0.8em;'>Coming Soon</span>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
with col2:
|
||||
st.markdown("""
|
||||
<div style='background-color: #e9ecef; padding: 15px; border-radius: 5px; margin-bottom: 10px;'>
|
||||
<h4>🎬 Video Elements</h4>
|
||||
<p>Generate video clips, transitions, and effects to enhance your reel.</p>
|
||||
<span style='background-color: #6c757d; color: white; padding: 2px 8px; border-radius: 10px; font-size: 0.8em;'>Coming Soon</span>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
def render_advanced_options_tab():
|
||||
"""Render the Advanced Options tab for additional customization."""
|
||||
st.markdown("### Advanced Options")
|
||||
|
||||
# Check if reel content has been generated
|
||||
if 'reel_content' not in st.session_state:
|
||||
st.info("Please generate reel content in the 'Reel Content' tab first.")
|
||||
return
|
||||
|
||||
st.markdown("""
|
||||
<div style='background-color: #f8f9fa; padding: 10px; border-radius: 5px; margin-bottom: 10px;'>
|
||||
<p><strong>Note:</strong> These advanced options allow for more customization of your reel content.</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Advanced content options
|
||||
st.markdown("#### Content Customization")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
content_length = st.select_slider(
|
||||
"Content Length",
|
||||
options=["Short (15s)", "Medium (30s)", "Long (60s)"],
|
||||
value="Medium (30s)",
|
||||
help="The target length for your reel content"
|
||||
)
|
||||
|
||||
language_style = st.selectbox(
|
||||
"Language Style",
|
||||
options=[
|
||||
"Simple and Clear",
|
||||
"Professional",
|
||||
"Casual",
|
||||
"Technical",
|
||||
"Persuasive",
|
||||
"Storytelling"
|
||||
],
|
||||
help="The language style for your content"
|
||||
)
|
||||
|
||||
with col2:
|
||||
include_stats = st.checkbox("Include Statistics/Facts", value=False)
|
||||
include_quotes = st.checkbox("Include Quote Suggestions", value=False)
|
||||
include_emoji = st.checkbox("Include Emoji Suggestions", value=True)
|
||||
|
||||
# AI model options
|
||||
st.markdown("#### AI Model Options")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
creativity_level = st.select_slider(
|
||||
"Creativity Level",
|
||||
options=["Conservative", "Balanced", "Creative", "Very Creative"],
|
||||
value="Balanced",
|
||||
help="How creative should the AI be in generating content"
|
||||
)
|
||||
|
||||
with col2:
|
||||
ai_provider = st.selectbox(
|
||||
"AI Provider",
|
||||
options=["Auto-Select", "OpenAI", "Google Gemini", "Anthropic Claude"],
|
||||
help="Which AI provider to use for content generation"
|
||||
)
|
||||
|
||||
# Generate with advanced options button
|
||||
if st.button("Regenerate with Advanced Options", type="primary"):
|
||||
with st.spinner("Regenerating your Facebook Reel content with advanced options..."):
|
||||
# Get the original content parameters from session state
|
||||
original_params = st.session_state.get('reel_params', {})
|
||||
|
||||
# Update with advanced options
|
||||
advanced_params = {
|
||||
**original_params,
|
||||
'content_length': content_length,
|
||||
'language_style': language_style,
|
||||
'include_stats': include_stats,
|
||||
'include_quotes': include_quotes,
|
||||
'include_emoji': include_emoji,
|
||||
'creativity_level': creativity_level,
|
||||
'ai_provider': ai_provider
|
||||
}
|
||||
|
||||
# Generate the reel content with advanced options
|
||||
reel_content = generate_reel_content_advanced(advanced_params)
|
||||
|
||||
# Display the generated content
|
||||
if reel_content:
|
||||
st.markdown("### Regenerated Reel Content")
|
||||
|
||||
# Create a container with a nice background for the content
|
||||
st.markdown("""
|
||||
<div style='background-color: #f8f9fa; padding: 20px; border-radius: 10px; border-left: 5px solid #1877F2; margin-bottom: 20px;'>
|
||||
<h4 style='color: #1877F2;'>Your Facebook Reel Script</h4>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Parse and display the content in a structured way
|
||||
display_reel_content(reel_content)
|
||||
|
||||
# Add a download button for the content
|
||||
st.download_button(
|
||||
label="Download Reel Content",
|
||||
data=reel_content,
|
||||
file_name=f"facebook_reel_advanced_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt",
|
||||
mime="text/plain"
|
||||
)
|
||||
|
||||
# Update the content in session state
|
||||
st.session_state['reel_content'] = reel_content
|
||||
else:
|
||||
st.error("Failed to regenerate reel content. Please try again.")
|
||||
|
||||
def generate_reel_content(
|
||||
business_type: str,
|
||||
target_audience: str,
|
||||
reel_purpose: str,
|
||||
brand_voice: str,
|
||||
key_message: str,
|
||||
call_to_action: str,
|
||||
custom_cta: str = "",
|
||||
include_hashtags: bool = True,
|
||||
include_hook: bool = True,
|
||||
include_transitions: bool = True,
|
||||
include_text_overlays: bool = True,
|
||||
include_engagement_tips: bool = True,
|
||||
include_trending_topics: bool = True
|
||||
) -> str:
|
||||
"""
|
||||
Generate Facebook Reel content based on user inputs.
|
||||
|
||||
Args:
|
||||
business_type: The type of business or industry
|
||||
target_audience: The target audience for the reel
|
||||
reel_purpose: The purpose of the reel
|
||||
brand_voice: The brand voice or tone
|
||||
key_message: The key message to convey
|
||||
call_to_action: The call to action
|
||||
custom_cta: Custom call to action text if "Custom" is selected
|
||||
include_hashtags: Whether to include hashtag suggestions
|
||||
include_hook: Whether to include a hook/opening
|
||||
include_transitions: Whether to include transition suggestions
|
||||
include_text_overlays: Whether to include text overlay suggestions
|
||||
include_engagement_tips: Whether to include engagement tips
|
||||
include_trending_topics: Whether to include trending topics
|
||||
|
||||
Returns:
|
||||
str: The generated reel content
|
||||
"""
|
||||
try:
|
||||
# Store parameters in session state for advanced options
|
||||
st.session_state['reel_params'] = {
|
||||
'business_type': business_type,
|
||||
'target_audience': target_audience,
|
||||
'reel_purpose': reel_purpose,
|
||||
'brand_voice': brand_voice,
|
||||
'key_message': key_message,
|
||||
'call_to_action': call_to_action,
|
||||
'custom_cta': custom_cta,
|
||||
'include_hashtags': include_hashtags,
|
||||
'include_hook': include_hook,
|
||||
'include_transitions': include_transitions,
|
||||
'include_text_overlays': include_text_overlays,
|
||||
'include_engagement_tips': include_engagement_tips,
|
||||
'include_trending_topics': include_trending_topics
|
||||
}
|
||||
|
||||
# Construct the prompt for the AI
|
||||
prompt = f"""
|
||||
Create a detailed Facebook Reel script for a {business_type} business targeting {target_audience}.
|
||||
|
||||
The purpose of this reel is: {reel_purpose}
|
||||
The brand voice/tone should be: {brand_voice}
|
||||
The key message to convey is: {key_message}
|
||||
The call to action should be: {call_to_action}{f" - {custom_cta}" if custom_cta else ""}
|
||||
|
||||
Please provide a complete Facebook Reel script with the following elements:
|
||||
|
||||
1. A hook (first 3 seconds) that grabs attention
|
||||
2. Main content (15-30 seconds) that delivers the key message
|
||||
3. A strong call-to-action at the end
|
||||
|
||||
Additional elements to include:
|
||||
{f"- Hashtag suggestions relevant to the content and industry" if include_hashtags else ""}
|
||||
{f"- Text overlay suggestions for key points" if include_text_overlays else ""}
|
||||
{f"- Transition suggestions between scenes" if include_transitions else ""}
|
||||
{f"- Engagement tips to encourage interaction" if include_engagement_tips else ""}
|
||||
{f"- Trending topics that could be incorporated" if include_trending_topics else ""}
|
||||
|
||||
Format the output as a structured script with clear sections and timing suggestions.
|
||||
"""
|
||||
|
||||
# Generate the content using the AI
|
||||
logger.info(f"[generate_reel_content] Generating reel content for {business_type}")
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
if response:
|
||||
logger.info(f"[generate_reel_content] Successfully generated reel content")
|
||||
return response
|
||||
else:
|
||||
logger.error(f"[generate_reel_content] Failed to generate reel content")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[generate_reel_content] Error generating reel content: {str(e)}")
|
||||
return None
|
||||
|
||||
def generate_reel_content_advanced(params: Dict[str, Any]) -> str:
|
||||
"""
|
||||
Generate Facebook Reel content with advanced options.
|
||||
|
||||
Args:
|
||||
params: Dictionary of parameters for content generation
|
||||
|
||||
Returns:
|
||||
str: The generated reel content
|
||||
"""
|
||||
try:
|
||||
# Extract parameters
|
||||
business_type = params.get('business_type', '')
|
||||
target_audience = params.get('target_audience', '')
|
||||
reel_purpose = params.get('reel_purpose', '')
|
||||
brand_voice = params.get('brand_voice', '')
|
||||
key_message = params.get('key_message', '')
|
||||
call_to_action = params.get('call_to_action', '')
|
||||
custom_cta = params.get('custom_cta', '')
|
||||
content_length = params.get('content_length', 'Medium (30s)')
|
||||
language_style = params.get('language_style', 'Simple and Clear')
|
||||
include_stats = params.get('include_stats', False)
|
||||
include_quotes = params.get('include_quotes', False)
|
||||
include_emoji = params.get('include_emoji', True)
|
||||
creativity_level = params.get('creativity_level', 'Balanced')
|
||||
ai_provider = params.get('ai_provider', 'Auto-Select')
|
||||
|
||||
# Construct the advanced prompt
|
||||
prompt = f"""
|
||||
Create a detailed Facebook Reel script for a {business_type} business targeting {target_audience}.
|
||||
|
||||
The purpose of this reel is: {reel_purpose}
|
||||
The brand voice/tone should be: {brand_voice}
|
||||
The key message to convey is: {key_message}
|
||||
The call to action should be: {call_to_action}{f" - {custom_cta}" if custom_cta else ""}
|
||||
|
||||
Advanced requirements:
|
||||
- Content length: {content_length}
|
||||
- Language style: {language_style}
|
||||
- Creativity level: {creativity_level}
|
||||
{f"- Include relevant statistics or facts to support the message" if include_stats else ""}
|
||||
{f"- Include quote suggestions that could be used in the reel" if include_quotes else ""}
|
||||
{f"- Include emoji suggestions for text overlays" if include_emoji else ""}
|
||||
|
||||
Please provide a complete Facebook Reel script with the following elements:
|
||||
|
||||
1. A hook (first 3 seconds) that grabs attention
|
||||
2. Main content that delivers the key message
|
||||
3. A strong call-to-action at the end
|
||||
|
||||
Format the output as a structured script with clear sections and timing suggestions.
|
||||
"""
|
||||
|
||||
# Generate the content using the AI
|
||||
logger.info(f"[generate_reel_content_advanced] Generating advanced reel content for {business_type}")
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
if response:
|
||||
logger.info(f"[generate_reel_content_advanced] Successfully generated advanced reel content")
|
||||
return response
|
||||
else:
|
||||
logger.error(f"[generate_reel_content_advanced] Failed to generate advanced reel content")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[generate_reel_content_advanced] Error generating advanced reel content: {str(e)}")
|
||||
return None
|
||||
|
||||
def generate_reel_images(
|
||||
reel_content: str,
|
||||
visual_style: str,
|
||||
custom_style: Optional[str] = None,
|
||||
num_images: int = 3,
|
||||
image_aspect_ratio: str = "9:16 (Vertical - Reel)",
|
||||
image_quality: str = "Standard",
|
||||
custom_image_prompt: Optional[str] = None
|
||||
) -> List[str]:
|
||||
"""
|
||||
Generate images for a Facebook Reel based on the content.
|
||||
|
||||
Args:
|
||||
reel_content: The generated reel content
|
||||
visual_style: The visual style for the images
|
||||
custom_style: Custom style description if "Custom" is selected
|
||||
num_images: Number of images to generate
|
||||
image_aspect_ratio: The aspect ratio for the images
|
||||
image_quality: The quality level for the images
|
||||
custom_image_prompt: Custom prompt for image generation
|
||||
|
||||
Returns:
|
||||
List[str]: List of paths to the generated images
|
||||
"""
|
||||
try:
|
||||
logger.info(f"[generate_reel_images] Generating {num_images} images for reel")
|
||||
|
||||
# Extract key elements from the reel content
|
||||
prompt = f"""
|
||||
Based on the following Facebook Reel content, extract {num_images} key visual elements or scenes that would make compelling images.
|
||||
For each element, provide a detailed description that would work well for AI image generation.
|
||||
|
||||
Reel Content:
|
||||
{reel_content}
|
||||
|
||||
For each visual element, provide:
|
||||
1. A descriptive title
|
||||
2. A detailed image generation prompt that includes:
|
||||
- The main subject
|
||||
- The setting/background
|
||||
- The mood/atmosphere
|
||||
- The style ({visual_style}{f" - {custom_style}" if custom_style else ""})
|
||||
- The aspect ratio ({image_aspect_ratio})
|
||||
- The quality level ({image_quality})
|
||||
|
||||
Format each element as:
|
||||
TITLE: [title]
|
||||
PROMPT: [detailed prompt]
|
||||
|
||||
Generate exactly {num_images} elements.
|
||||
"""
|
||||
|
||||
# Generate the image prompts using the AI
|
||||
logger.info(f"[generate_reel_images] Generating image prompts")
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
if not response:
|
||||
logger.error(f"[generate_reel_images] Failed to generate image prompts")
|
||||
return []
|
||||
|
||||
# Parse the response to extract the image prompts
|
||||
image_prompts = []
|
||||
current_title = ""
|
||||
current_prompt = ""
|
||||
|
||||
for line in response.split('\n'):
|
||||
if line.startswith("TITLE:"):
|
||||
if current_title and current_prompt:
|
||||
image_prompts.append((current_title, current_prompt))
|
||||
current_title = line.replace("TITLE:", "").strip()
|
||||
current_prompt = ""
|
||||
elif line.startswith("PROMPT:"):
|
||||
current_prompt = line.replace("PROMPT:", "").strip()
|
||||
elif current_prompt and line.strip():
|
||||
current_prompt += " " + line.strip()
|
||||
|
||||
# Add the last prompt if there is one
|
||||
if current_title and current_prompt:
|
||||
image_prompts.append((current_title, current_prompt))
|
||||
|
||||
# If we don't have enough prompts, generate generic ones
|
||||
while len(image_prompts) < num_images:
|
||||
image_prompts.append((f"Generic Image {len(image_prompts)+1}",
|
||||
f"A visually appealing image related to {visual_style} style for a Facebook Reel"))
|
||||
|
||||
# Generate the images
|
||||
image_paths = []
|
||||
for i, (title, prompt) in enumerate(image_prompts[:num_images]):
|
||||
# Use custom prompt if provided
|
||||
if custom_image_prompt and i == 0:
|
||||
prompt = custom_image_prompt
|
||||
|
||||
logger.info(f"[generate_reel_images] Generating image {i+1}: {title}")
|
||||
image_path = generate_image(prompt)
|
||||
|
||||
if image_path:
|
||||
image_paths.append(image_path)
|
||||
logger.info(f"[generate_reel_images] Successfully generated image {i+1}")
|
||||
else:
|
||||
logger.error(f"[generate_reel_images] Failed to generate image {i+1}")
|
||||
|
||||
return image_paths
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[generate_reel_images] Error generating reel images: {str(e)}")
|
||||
return []
|
||||
|
||||
def display_reel_content(content: str):
|
||||
"""
|
||||
Display the reel content in a structured and visually appealing way.
|
||||
|
||||
Args:
|
||||
content: The generated reel content
|
||||
"""
|
||||
# Check if the content contains markdown code blocks
|
||||
if "```markdown" in content:
|
||||
# Extract the content from the markdown code block
|
||||
try:
|
||||
# Find the start and end of the markdown block
|
||||
start_idx = content.find("```markdown") + len("```markdown")
|
||||
end_idx = content.find("```", start_idx)
|
||||
if end_idx == -1: # If no closing markdown block found
|
||||
end_idx = len(content)
|
||||
|
||||
# Extract the markdown content
|
||||
markdown_content = content[start_idx:end_idx].strip()
|
||||
|
||||
# Split the content into sections
|
||||
sections = markdown_content.split('\n\n')
|
||||
|
||||
# Create tabs for different sections
|
||||
if len(sections) > 1:
|
||||
tabs = st.tabs(["Full Script", "Hook", "Main Content", "Call to Action", "Additional Elements"])
|
||||
|
||||
with tabs[0]: # Full Script
|
||||
st.markdown(markdown_content)
|
||||
|
||||
# Try to identify and display other sections
|
||||
hook_section = ""
|
||||
main_content = ""
|
||||
cta_section = ""
|
||||
additional_elements = ""
|
||||
|
||||
for section in sections:
|
||||
section_lower = section.lower()
|
||||
if "hook" in section_lower or "opening" in section_lower or "first 3 seconds" in section_lower or "0-3 seconds" in section_lower:
|
||||
hook_section = section
|
||||
elif "main content" in section_lower or "key message" in section_lower or "15-30 seconds" in section_lower:
|
||||
main_content = section
|
||||
elif "call to action" in section_lower or "cta" in section_lower or "end" in section_lower:
|
||||
cta_section = section
|
||||
elif "hashtag" in section_lower or "text overlay" in section_lower or "transition" in section_lower or "engagement" in section_lower or "trending" in section_lower or "additional" in section_lower:
|
||||
additional_elements += section + "\n\n"
|
||||
|
||||
with tabs[1]: # Hook
|
||||
if hook_section:
|
||||
st.markdown(hook_section)
|
||||
else:
|
||||
st.info("No specific hook section identified in the content.")
|
||||
|
||||
with tabs[2]: # Main Content
|
||||
if main_content:
|
||||
st.markdown(main_content)
|
||||
else:
|
||||
st.info("No specific main content section identified in the content.")
|
||||
|
||||
with tabs[3]: # Call to Action
|
||||
if cta_section:
|
||||
st.markdown(cta_section)
|
||||
else:
|
||||
st.info("No specific call to action section identified in the content.")
|
||||
|
||||
with tabs[4]: # Additional Elements
|
||||
if additional_elements:
|
||||
st.markdown(additional_elements)
|
||||
else:
|
||||
st.info("No additional elements identified in the content.")
|
||||
else:
|
||||
# If we can't split into sections, just display the content
|
||||
st.markdown(markdown_content)
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing markdown content: {str(e)}")
|
||||
# Fallback to displaying the raw content
|
||||
st.markdown(content)
|
||||
else:
|
||||
# If no markdown code block, use the original approach
|
||||
# Split the content into sections
|
||||
sections = content.split('\n\n')
|
||||
|
||||
# Create tabs for different sections
|
||||
if len(sections) > 1:
|
||||
tabs = st.tabs(["Full Script", "Hook", "Main Content", "Call to Action", "Additional Elements"])
|
||||
|
||||
with tabs[0]: # Full Script
|
||||
# Replace newlines with HTML line breaks
|
||||
formatted_content = content.replace('\n', '<br>')
|
||||
st.markdown(f"""
|
||||
<div style='background-color: white; padding: 15px; border-radius: 5px; border: 1px solid #e0e0e0;'>
|
||||
{formatted_content}
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Try to identify and display other sections
|
||||
hook_section = ""
|
||||
main_content = ""
|
||||
cta_section = ""
|
||||
additional_elements = ""
|
||||
|
||||
for section in sections:
|
||||
section_lower = section.lower()
|
||||
if "hook" in section_lower or "opening" in section_lower or "first 3 seconds" in section_lower or "0-3 seconds" in section_lower:
|
||||
hook_section = section
|
||||
elif "main content" in section_lower or "key message" in section_lower or "15-30 seconds" in section_lower:
|
||||
main_content = section
|
||||
elif "call to action" in section_lower or "cta" in section_lower or "end" in section_lower:
|
||||
cta_section = section
|
||||
elif "hashtag" in section_lower or "text overlay" in section_lower or "transition" in section_lower or "engagement" in section_lower or "trending" in section_lower or "additional" in section_lower:
|
||||
additional_elements += section + "\n\n"
|
||||
|
||||
with tabs[1]: # Hook
|
||||
if hook_section:
|
||||
# Replace newlines with HTML line breaks
|
||||
formatted_hook = hook_section.replace('\n', '<br>')
|
||||
st.markdown(f"""
|
||||
<div style='background-color: white; padding: 15px; border-radius: 5px; border: 1px solid #e0e0e0;'>
|
||||
{formatted_hook}
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
else:
|
||||
st.info("No specific hook section identified in the content.")
|
||||
|
||||
with tabs[2]: # Main Content
|
||||
if main_content:
|
||||
# Replace newlines with HTML line breaks
|
||||
formatted_main = main_content.replace('\n', '<br>')
|
||||
st.markdown(f"""
|
||||
<div style='background-color: white; padding: 15px; border-radius: 5px; border: 1px solid #e0e0e0;'>
|
||||
{formatted_main}
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
else:
|
||||
st.info("No specific main content section identified in the content.")
|
||||
|
||||
with tabs[3]: # Call to Action
|
||||
if cta_section:
|
||||
# Replace newlines with HTML line breaks
|
||||
formatted_cta = cta_section.replace('\n', '<br>')
|
||||
st.markdown(f"""
|
||||
<div style='background-color: white; padding: 15px; border-radius: 5px; border: 1px solid #e0e0e0;'>
|
||||
{formatted_cta}
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
else:
|
||||
st.info("No specific call to action section identified in the content.")
|
||||
|
||||
with tabs[4]: # Additional Elements
|
||||
if additional_elements:
|
||||
# Replace newlines with HTML line breaks
|
||||
formatted_additional = additional_elements.replace('\n', '<br>')
|
||||
st.markdown(f"""
|
||||
<div style='background-color: white; padding: 15px; border-radius: 5px; border: 1px solid #e0e0e0;'>
|
||||
{formatted_additional}
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
else:
|
||||
st.info("No additional elements identified in the content.")
|
||||
else:
|
||||
# If we can't split into sections, just display the content
|
||||
# Replace newlines with HTML line breaks
|
||||
formatted_content = content.replace('\n', '<br>')
|
||||
st.markdown(f"""
|
||||
<div style='background-color: white; padding: 15px; border-radius: 5px; border: 1px solid #e0e0e0;'>
|
||||
{formatted_content}
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
@@ -1,124 +0,0 @@
|
||||
# Facebook Group Post Generator
|
||||
|
||||
## Overview
|
||||
The Facebook Group Post Generator is a powerful tool designed to help content creators and community managers create engaging posts for Facebook Groups. It provides a comprehensive interface for crafting community-focused content that drives discussion and fosters engagement within Facebook Groups.
|
||||
|
||||
## Features
|
||||
|
||||
### Content & Media Management
|
||||
- **Multiple Post Types**: Create discussions, questions, announcements, resources, or event posts
|
||||
- **Rich Media Support**: Add images, videos, documents, or links to your posts
|
||||
- **AI-Powered Content Generation**: Generate engaging content based on your specifications
|
||||
- **Content Customization**: Fine-tune your post content with various formatting options
|
||||
|
||||
### Interactive Elements
|
||||
- **Poll Creation**: Create polls with up to 4 options to gather member opinions
|
||||
- **Question Features**: Add questions to encourage member responses
|
||||
- **Announcement Toggle**: Mark important posts as announcements for better visibility
|
||||
- **Media Attachments**: Support for various media types to enhance post engagement
|
||||
|
||||
### Engagement Optimization
|
||||
- **Target Audience Selection**: Customize posts for specific member segments
|
||||
- **Tone Customization**: Choose from professional, casual, friendly, formal, or humorous tones
|
||||
- **Call-to-Action Options**: Select from various actions to encourage member participation
|
||||
- **Engagement Prompts**: Add prompts to stimulate discussion and comments
|
||||
|
||||
### Preview & Export
|
||||
- **Live Preview**: See how your post will appear before publishing
|
||||
- **Export Options**: Copy to clipboard or download as text file
|
||||
- **Format Validation**: Ensure your post meets Facebook's requirements
|
||||
- **Timestamp Tracking**: Keep track of when posts were created
|
||||
|
||||
## How to Use
|
||||
|
||||
1. **Access the Generator**
|
||||
- Navigate to the Facebook Group Post Generator in the AI Writer dashboard
|
||||
- Select "Create New Post" to start
|
||||
|
||||
2. **Configure Post Settings**
|
||||
- Choose your post type
|
||||
- Add your content or let AI generate it
|
||||
- Select media options if needed
|
||||
|
||||
3. **Add Interactive Elements**
|
||||
- Create polls or questions
|
||||
- Set announcement status
|
||||
- Configure engagement settings
|
||||
|
||||
4. **Generate and Export**
|
||||
- Click "Generate Group Post" to create your content
|
||||
- Preview the generated post
|
||||
- Export or copy the content
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Content Creation
|
||||
- Keep posts concise and focused
|
||||
- Use clear, engaging language
|
||||
- Include relevant hashtags
|
||||
- Add visual elements when appropriate
|
||||
|
||||
### Engagement
|
||||
- Ask open-ended questions
|
||||
- Create polls for member input
|
||||
- Use appropriate tone for your audience
|
||||
- Include clear calls-to-action
|
||||
|
||||
### Media Usage
|
||||
- Optimize images for Facebook
|
||||
- Keep videos short and engaging
|
||||
- Use high-quality media
|
||||
- Include alt text for accessibility
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
- Python 3.7+
|
||||
- Streamlit
|
||||
- Required Python packages:
|
||||
- streamlit
|
||||
- typing
|
||||
- datetime
|
||||
- json
|
||||
- logging
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
1. **Content Generation Fails**
|
||||
- Check your internet connection
|
||||
- Verify input parameters
|
||||
- Try reducing content length
|
||||
|
||||
2. **Media Upload Issues**
|
||||
- Ensure file size is within limits
|
||||
- Check file format compatibility
|
||||
- Verify file permissions
|
||||
|
||||
3. **Export Problems**
|
||||
- Check available disk space
|
||||
- Verify write permissions
|
||||
- Ensure proper file naming
|
||||
|
||||
## Future Updates
|
||||
|
||||
- Enhanced AI content generation
|
||||
- Additional media type support
|
||||
- Advanced analytics integration
|
||||
- Template library
|
||||
- Bulk post scheduling
|
||||
- Multi-language support
|
||||
- Advanced engagement metrics
|
||||
- A/B testing capabilities
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions to improve the Facebook Group Post Generator. Please follow these steps:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
This module is licensed under the MIT License. See the LICENSE file for details.
|
||||
@@ -1,11 +0,0 @@
|
||||
"""
|
||||
Facebook Group Post Generator Module
|
||||
|
||||
This module provides functionality to generate engaging posts for Facebook Groups.
|
||||
It helps content creators create community-focused content that drives engagement
|
||||
and fosters discussion within Facebook Groups.
|
||||
"""
|
||||
|
||||
from .group_post_generator import write_fb_group_post
|
||||
|
||||
__all__ = ['write_fb_group_post']
|
||||
@@ -1,327 +0,0 @@
|
||||
"""
|
||||
Facebook Group Post Generator Module
|
||||
|
||||
This module provides functionality to generate engaging posts for Facebook Groups.
|
||||
It helps content creators create community-focused content that drives engagement
|
||||
and fosters discussion within Facebook Groups.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Optional, Union, Tuple
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
|
||||
# Set up logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def write_fb_group_post():
|
||||
"""
|
||||
Generate a Facebook Group post with various customization options.
|
||||
|
||||
This function provides a comprehensive interface for creating engaging
|
||||
Facebook Group posts with features like:
|
||||
- Content customization
|
||||
- Polls and questions
|
||||
- Announcements
|
||||
- Media attachments
|
||||
- Engagement prompts
|
||||
"""
|
||||
|
||||
st.title("Facebook Group Post Generator")
|
||||
st.markdown("""
|
||||
Create engaging posts for your Facebook Groups that drive discussion and community engagement.
|
||||
Customize your content, add interactive elements, and optimize for maximum impact.
|
||||
""")
|
||||
|
||||
# Initialize session state for form data
|
||||
if 'group_post_data' not in st.session_state:
|
||||
st.session_state.group_post_data = {
|
||||
'post_type': 'discussion',
|
||||
'content': '',
|
||||
'media_type': 'none',
|
||||
'poll_options': [],
|
||||
'question': '',
|
||||
'is_announcement': False,
|
||||
'engagement_prompt': '',
|
||||
'hashtags': [],
|
||||
'target_audience': 'all',
|
||||
'post_tone': 'professional',
|
||||
'call_to_action': 'discuss'
|
||||
}
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3, tab4 = st.tabs([
|
||||
"Content & Media",
|
||||
"Interactive Elements",
|
||||
"Engagement",
|
||||
"Preview & Export"
|
||||
])
|
||||
|
||||
with tab1:
|
||||
render_content_media_tab()
|
||||
|
||||
with tab2:
|
||||
render_interactive_elements_tab()
|
||||
|
||||
with tab3:
|
||||
render_engagement_tab()
|
||||
|
||||
with tab4:
|
||||
render_preview_export_tab()
|
||||
|
||||
# Generate button
|
||||
if st.button("Generate Group Post", type="primary"):
|
||||
if validate_group_post_fields():
|
||||
with st.spinner("Generating your group post..."):
|
||||
post_content = generate_group_post()
|
||||
if post_content:
|
||||
st.session_state.group_post_data['generated_content'] = post_content
|
||||
st.success("Group post generated successfully!")
|
||||
st.session_state.show_preview = True
|
||||
|
||||
def render_content_media_tab():
|
||||
"""Render the content and media input fields."""
|
||||
|
||||
st.header("Content & Media")
|
||||
|
||||
# Post Type Selection
|
||||
post_type = st.selectbox(
|
||||
"Post Type",
|
||||
options=['discussion', 'question', 'announcement', 'resource', 'event'],
|
||||
index=['discussion', 'question', 'announcement', 'resource', 'event'].index(
|
||||
st.session_state.group_post_data['post_type']
|
||||
),
|
||||
help="Choose the type of post you want to create"
|
||||
)
|
||||
st.session_state.group_post_data['post_type'] = post_type
|
||||
|
||||
# Content Input
|
||||
content = st.text_area(
|
||||
"Post Content",
|
||||
value=st.session_state.group_post_data['content'],
|
||||
height=200,
|
||||
help="Write your post content or leave blank for AI generation"
|
||||
)
|
||||
st.session_state.group_post_data['content'] = content
|
||||
|
||||
# Media Options
|
||||
media_type = st.selectbox(
|
||||
"Media Type",
|
||||
options=['none', 'image', 'video', 'document', 'link'],
|
||||
index=['none', 'image', 'video', 'document', 'link'].index(
|
||||
st.session_state.group_post_data['media_type']
|
||||
),
|
||||
help="Add media to your post"
|
||||
)
|
||||
st.session_state.group_post_data['media_type'] = media_type
|
||||
|
||||
if media_type != 'none':
|
||||
if media_type == 'image':
|
||||
st.file_uploader("Upload Image", type=['jpg', 'jpeg', 'png'])
|
||||
elif media_type == 'video':
|
||||
st.file_uploader("Upload Video", type=['mp4', 'mov'])
|
||||
elif media_type == 'document':
|
||||
st.file_uploader("Upload Document", type=['pdf', 'doc', 'docx'])
|
||||
elif media_type == 'link':
|
||||
st.text_input("Enter URL", help="Paste the URL you want to share")
|
||||
|
||||
def render_interactive_elements_tab():
|
||||
"""Render the interactive elements options."""
|
||||
|
||||
st.header("Interactive Elements")
|
||||
|
||||
# Poll Creation
|
||||
if st.checkbox("Add Poll", help="Create a poll for group members"):
|
||||
poll_question = st.text_input("Poll Question")
|
||||
poll_options = []
|
||||
for i in range(4):
|
||||
option = st.text_input(f"Option {i+1}")
|
||||
if option:
|
||||
poll_options.append(option)
|
||||
st.session_state.group_post_data['poll_options'] = poll_options
|
||||
|
||||
# Question Creation
|
||||
if st.checkbox("Add Question", help="Ask a question to group members"):
|
||||
question = st.text_input("Your Question")
|
||||
st.session_state.group_post_data['question'] = question
|
||||
|
||||
# Announcement Toggle
|
||||
is_announcement = st.checkbox(
|
||||
"Mark as Announcement",
|
||||
value=st.session_state.group_post_data['is_announcement'],
|
||||
help="Pin this post as an announcement in the group"
|
||||
)
|
||||
st.session_state.group_post_data['is_announcement'] = is_announcement
|
||||
|
||||
def render_engagement_tab():
|
||||
"""Render the engagement options."""
|
||||
|
||||
st.header("Engagement Settings")
|
||||
|
||||
# Engagement Prompt
|
||||
engagement_prompt = st.text_area(
|
||||
"Engagement Prompt",
|
||||
value=st.session_state.group_post_data['engagement_prompt'],
|
||||
help="Add a prompt to encourage comments and discussion"
|
||||
)
|
||||
st.session_state.group_post_data['engagement_prompt'] = engagement_prompt
|
||||
|
||||
# Target Audience
|
||||
target_audience = st.selectbox(
|
||||
"Target Audience",
|
||||
options=['all', 'new_members', 'active_members', 'specific_role'],
|
||||
index=['all', 'new_members', 'active_members', 'specific_role'].index(
|
||||
st.session_state.group_post_data['target_audience']
|
||||
),
|
||||
help="Select who this post is primarily for"
|
||||
)
|
||||
st.session_state.group_post_data['target_audience'] = target_audience
|
||||
|
||||
# Post Tone
|
||||
post_tone = st.selectbox(
|
||||
"Post Tone",
|
||||
options=['professional', 'casual', 'friendly', 'formal', 'humorous'],
|
||||
index=['professional', 'casual', 'friendly', 'formal', 'humorous'].index(
|
||||
st.session_state.group_post_data['post_tone']
|
||||
),
|
||||
help="Choose the tone for your post"
|
||||
)
|
||||
st.session_state.group_post_data['post_tone'] = post_tone
|
||||
|
||||
# Call to Action
|
||||
call_to_action = st.selectbox(
|
||||
"Call to Action",
|
||||
options=['discuss', 'share', 'learn', 'participate', 'feedback'],
|
||||
index=['discuss', 'share', 'learn', 'participate', 'feedback'].index(
|
||||
st.session_state.group_post_data['call_to_action']
|
||||
),
|
||||
help="What action do you want members to take?"
|
||||
)
|
||||
st.session_state.group_post_data['call_to_action'] = call_to_action
|
||||
|
||||
def render_preview_export_tab():
|
||||
"""Render the preview and export options."""
|
||||
|
||||
st.header("Preview & Export")
|
||||
|
||||
if 'generated_content' in st.session_state.group_post_data:
|
||||
st.subheader("Generated Post")
|
||||
st.markdown(st.session_state.group_post_data['generated_content'])
|
||||
|
||||
# Export options
|
||||
st.subheader("Export Options")
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
if st.button("Copy to Clipboard"):
|
||||
st.code(st.session_state.group_post_data['generated_content'])
|
||||
|
||||
with col2:
|
||||
if st.button("Download as Text"):
|
||||
download_group_post(st.session_state.group_post_data['generated_content'])
|
||||
|
||||
def validate_group_post_fields() -> bool:
|
||||
"""Validate the group post fields."""
|
||||
|
||||
data = st.session_state.group_post_data
|
||||
|
||||
# Basic validation rules
|
||||
validation_rules = {
|
||||
'post_type': {'required': True, 'type': str},
|
||||
'content': {'required': False, 'type': str},
|
||||
'media_type': {'required': True, 'type': str},
|
||||
'poll_options': {'required': False, 'type': list},
|
||||
'question': {'required': False, 'type': str},
|
||||
'is_announcement': {'required': True, 'type': bool},
|
||||
'engagement_prompt': {'required': False, 'type': str},
|
||||
'target_audience': {'required': True, 'type': str},
|
||||
'post_tone': {'required': True, 'type': str},
|
||||
'call_to_action': {'required': True, 'type': str}
|
||||
}
|
||||
|
||||
errors = []
|
||||
|
||||
for field, rules in validation_rules.items():
|
||||
value = data.get(field)
|
||||
|
||||
# Skip validation for optional fields if empty
|
||||
if not rules['required'] and not value:
|
||||
continue
|
||||
|
||||
# Type validation
|
||||
if value and not isinstance(value, rules['type']):
|
||||
errors.append(f"{field.replace('_', ' ').title()} must be of type {rules['type'].__name__}")
|
||||
continue
|
||||
|
||||
# Required field validation
|
||||
if rules['required'] and not value:
|
||||
errors.append(f"{field.replace('_', ' ').title()} is required")
|
||||
|
||||
if errors:
|
||||
for error in errors:
|
||||
st.error(error)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def generate_group_post() -> Optional[str]:
|
||||
"""Generate the group post content using AI."""
|
||||
|
||||
try:
|
||||
data = st.session_state.group_post_data
|
||||
|
||||
# Prepare the prompt for the LLM
|
||||
prompt = f"""
|
||||
Create a Facebook Group post with the following specifications:
|
||||
|
||||
Post Type: {data['post_type']}
|
||||
Content: {data['content'] if data['content'] else 'Generate engaging content'}
|
||||
Media Type: {data['media_type']}
|
||||
Target Audience: {data['target_audience']}
|
||||
Post Tone: {data['post_tone']}
|
||||
Call to Action: {data['call_to_action']}
|
||||
|
||||
Additional Elements:
|
||||
- Poll Options: {', '.join(data['poll_options']) if data['poll_options'] else 'None'}
|
||||
- Question: {data['question'] if data['question'] else 'None'}
|
||||
- Is Announcement: {data['is_announcement']}
|
||||
- Engagement Prompt: {data['engagement_prompt'] if data['engagement_prompt'] else 'None'}
|
||||
|
||||
The post should be engaging, community-focused, and encourage discussion.
|
||||
Include appropriate formatting, emojis, and hashtags where relevant.
|
||||
"""
|
||||
|
||||
# Get response from LLM
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
if response:
|
||||
return response
|
||||
else:
|
||||
st.error("Failed to generate group post content. Please try again.")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating group post: {str(e)}")
|
||||
st.error("An error occurred while generating the group post. Please try again.")
|
||||
return None
|
||||
|
||||
def download_group_post(content: str):
|
||||
"""Download the generated group post as a text file."""
|
||||
|
||||
try:
|
||||
# Create a timestamp for the filename
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"facebook_group_post_{timestamp}.txt"
|
||||
|
||||
# Create the download button
|
||||
st.download_button(
|
||||
label="Download Post",
|
||||
data=content,
|
||||
file_name=filename,
|
||||
mime="text/plain"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error downloading group post: {str(e)}")
|
||||
st.error("An error occurred while downloading the post. Please try again.")
|
||||
@@ -1,145 +0,0 @@
|
||||
# Facebook Hashtag Generator
|
||||
|
||||
A powerful tool for generating optimized hashtags for your Facebook content. This module helps content creators maximize their reach and engagement through strategic hashtag selection and placement.
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Smart Hashtag Generation
|
||||
- AI-powered hashtag suggestions based on content analysis
|
||||
- Industry-specific hashtag recommendations
|
||||
- Mix of trending and niche hashtags
|
||||
- Customizable number of hashtags
|
||||
- Content type-specific optimization
|
||||
|
||||
### 2. Performance Predictions
|
||||
- Reach estimates for each hashtag
|
||||
- Engagement rate predictions
|
||||
- Competition level analysis
|
||||
- Visual performance metrics
|
||||
- Best performing hashtag combinations
|
||||
|
||||
### 3. Hashtag Library
|
||||
- Save and organize your hashtags
|
||||
- Create custom collections
|
||||
- Quick access to frequently used hashtags
|
||||
- Easy management of hashtag sets
|
||||
- Import/export functionality
|
||||
|
||||
### 4. Placement Optimization
|
||||
- Smart placement suggestions
|
||||
- Integration within content
|
||||
- End-of-post placement
|
||||
- Mixed placement strategies
|
||||
- Preview of hashtag placement
|
||||
|
||||
## How to Use
|
||||
|
||||
1. **Generate Hashtags**
|
||||
- Enter your content or topic
|
||||
- Select your industry
|
||||
- Choose content type
|
||||
- Set hashtag preferences
|
||||
- Click "Generate Hashtags"
|
||||
|
||||
2. **Manage Library**
|
||||
- Save generated hashtags
|
||||
- Create collections
|
||||
- Add custom hashtags
|
||||
- Remove unused hashtags
|
||||
- Organize by category
|
||||
|
||||
3. **View Insights**
|
||||
- Check performance metrics
|
||||
- Analyze reach predictions
|
||||
- Review engagement rates
|
||||
- Compare competition levels
|
||||
- Get optimal combinations
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Content Analysis
|
||||
- Provide detailed content description
|
||||
- Include key topics and themes
|
||||
- Mention target audience
|
||||
- Specify content goals
|
||||
- Add relevant context
|
||||
|
||||
### Hashtag Selection
|
||||
- Mix popular and niche hashtags
|
||||
- Use industry-specific tags
|
||||
- Include trending hashtags
|
||||
- Avoid overused combinations
|
||||
- Test different variations
|
||||
|
||||
### Placement Strategy
|
||||
- Natural integration
|
||||
- Strategic positioning
|
||||
- Readability focus
|
||||
- Engagement optimization
|
||||
- Mobile-friendly format
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
- Python 3.7+
|
||||
- Streamlit
|
||||
- Required Python packages:
|
||||
- streamlit
|
||||
- loguru
|
||||
- typing
|
||||
- json
|
||||
- re
|
||||
- random
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
1. **Generation Failures**
|
||||
- Check content input
|
||||
- Verify industry selection
|
||||
- Ensure internet connection
|
||||
- Clear browser cache
|
||||
- Restart application
|
||||
|
||||
2. **Performance Issues**
|
||||
- Reduce hashtag count
|
||||
- Clear saved hashtags
|
||||
- Update browser
|
||||
- Check system resources
|
||||
- Contact support
|
||||
|
||||
### Error Messages
|
||||
- "Please enter content" - Add content description
|
||||
- "Invalid industry" - Select from dropdown
|
||||
- "Generation failed" - Try again or use defaults
|
||||
- "Save failed" - Check storage permissions
|
||||
- "Display error" - Refresh page
|
||||
|
||||
## Future Updates
|
||||
|
||||
### Planned Features
|
||||
- Advanced analytics
|
||||
- Competitor analysis
|
||||
- Hashtag tracking
|
||||
- Performance history
|
||||
- Bulk generation
|
||||
- API integration
|
||||
- Custom algorithms
|
||||
- Multi-language support
|
||||
- Export options
|
||||
- Collaboration tools
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions to improve the Hashtag Generator:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Submit a pull request
|
||||
5. Follow coding standards
|
||||
6. Add tests
|
||||
7. Update documentation
|
||||
|
||||
## License
|
||||
|
||||
This module is part of the AI Writer suite and is subject to the same licensing terms. See the main LICENSE file for details.
|
||||
@@ -1,9 +0,0 @@
|
||||
"""
|
||||
Facebook Hashtag Generator Module
|
||||
|
||||
This module provides functionality to generate optimized hashtags for Facebook content.
|
||||
"""
|
||||
|
||||
from .hashtag_generator import write_fb_hashtags
|
||||
|
||||
__all__ = ['write_fb_hashtags']
|
||||
@@ -1,567 +0,0 @@
|
||||
"""
|
||||
Facebook Hashtag Generator Module
|
||||
|
||||
This module provides functionality to generate relevant and trending hashtags for Facebook content.
|
||||
It analyzes content, suggests optimal hashtag combinations, and provides performance predictions.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import json
|
||||
import random
|
||||
import re
|
||||
from typing import List, Dict, Any, Tuple, Optional
|
||||
from loguru import logger
|
||||
import sys
|
||||
import base64
|
||||
from io import BytesIO
|
||||
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
|
||||
# Configure logging
|
||||
logger.remove()
|
||||
logger.add(sys.stdout,
|
||||
colorize=True,
|
||||
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
|
||||
)
|
||||
|
||||
def initialize_session_state():
|
||||
"""Initialize session state with default values."""
|
||||
if 'hashtag_data' not in st.session_state:
|
||||
st.session_state.hashtag_data = {
|
||||
'content': "",
|
||||
'industry': "",
|
||||
'content_type': "Post",
|
||||
'hashtag_count': 5,
|
||||
'include_trending': True,
|
||||
'include_niche': True,
|
||||
'generated_hashtags': [],
|
||||
'performance_predictions': {},
|
||||
'saved_hashtags': []
|
||||
}
|
||||
|
||||
def write_fb_hashtags():
|
||||
"""Generate relevant and trending hashtags for Facebook content."""
|
||||
|
||||
# Initialize session state
|
||||
initialize_session_state()
|
||||
|
||||
st.markdown("""
|
||||
### #️⃣ Facebook Hashtag Generator
|
||||
Create optimized hashtag combinations that maximize your content's reach and engagement.
|
||||
Our AI analyzes your content and suggests the perfect hashtags for your Facebook posts.
|
||||
""")
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3 = st.tabs(["Generate Hashtags", "Hashtag Library", "Performance Insights"])
|
||||
|
||||
with tab1:
|
||||
render_generate_tab()
|
||||
|
||||
with tab2:
|
||||
render_library_tab()
|
||||
|
||||
with tab3:
|
||||
render_insights_tab()
|
||||
|
||||
def render_generate_tab():
|
||||
"""Render the hashtag generation tab with input fields."""
|
||||
|
||||
# Content Input
|
||||
st.markdown("#### Content for Hashtag Analysis")
|
||||
|
||||
content = st.text_area(
|
||||
"Enter your content or describe what you're posting about",
|
||||
value=st.session_state.hashtag_data['content'],
|
||||
height=150,
|
||||
help="Enter the text content or describe the topic of your Facebook post",
|
||||
key="content_input"
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.hashtag_data['content'] = content
|
||||
|
||||
# Industry and Content Type
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
industries = [
|
||||
"Technology", "Health & Wellness", "Fashion", "Food & Beverage",
|
||||
"Travel", "Education", "Finance", "Entertainment", "Fitness",
|
||||
"Beauty", "Home & Garden", "Automotive", "Real Estate", "Business",
|
||||
"Art & Design", "Sports", "Parenting", "Pets", "Other"
|
||||
]
|
||||
|
||||
industry = st.selectbox(
|
||||
"Industry",
|
||||
options=industries,
|
||||
index=industries.index(st.session_state.hashtag_data['industry']) if st.session_state.hashtag_data['industry'] in industries else 0,
|
||||
help="Select your industry for more relevant hashtag suggestions",
|
||||
key="industry_select"
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.hashtag_data['industry'] = industry
|
||||
|
||||
with col2:
|
||||
content_types = ["Post", "Story", "Reel", "Carousel", "Event", "Group Post"]
|
||||
|
||||
content_type = st.selectbox(
|
||||
"Content Type",
|
||||
options=content_types,
|
||||
index=content_types.index(st.session_state.hashtag_data['content_type']) if st.session_state.hashtag_data['content_type'] in content_types else 0,
|
||||
help="Select the type of content you're creating",
|
||||
key="content_type_select"
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.hashtag_data['content_type'] = content_type
|
||||
|
||||
# Hashtag Preferences
|
||||
st.markdown("#### Hashtag Preferences")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
hashtag_count = st.slider(
|
||||
"Number of Hashtags",
|
||||
min_value=1,
|
||||
max_value=30,
|
||||
value=st.session_state.hashtag_data['hashtag_count'],
|
||||
help="Select how many hashtags you want to generate",
|
||||
key="hashtag_count_slider"
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.hashtag_data['hashtag_count'] = hashtag_count
|
||||
|
||||
include_trending = st.checkbox(
|
||||
"Include Trending Hashtags",
|
||||
value=st.session_state.hashtag_data['include_trending'],
|
||||
help="Include currently trending hashtags in suggestions",
|
||||
key="include_trending_checkbox"
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.hashtag_data['include_trending'] = include_trending
|
||||
|
||||
with col2:
|
||||
include_niche = st.checkbox(
|
||||
"Include Niche Hashtags",
|
||||
value=st.session_state.hashtag_data['include_niche'],
|
||||
help="Include niche, industry-specific hashtags",
|
||||
key="include_niche_checkbox"
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.hashtag_data['include_niche'] = include_niche
|
||||
|
||||
hashtag_placement = st.radio(
|
||||
"Hashtag Placement",
|
||||
["End of Post", "Throughout Content", "Both"],
|
||||
index=0,
|
||||
help="Select where you want to place the hashtags",
|
||||
key="hashtag_placement_radio"
|
||||
)
|
||||
|
||||
# Generate Button
|
||||
if st.button("Generate Hashtags", key="generate_hashtags_button"):
|
||||
if not content:
|
||||
st.warning("Please enter some content to generate hashtags.")
|
||||
else:
|
||||
with st.spinner("Generating optimized hashtags..."):
|
||||
# Generate hashtags
|
||||
generated_hashtags, performance_predictions = generate_hashtags(
|
||||
content,
|
||||
industry,
|
||||
content_type,
|
||||
hashtag_count,
|
||||
include_trending,
|
||||
include_niche
|
||||
)
|
||||
|
||||
# Update session state
|
||||
st.session_state.hashtag_data['generated_hashtags'] = generated_hashtags
|
||||
st.session_state.hashtag_data['performance_predictions'] = performance_predictions
|
||||
|
||||
# Display results
|
||||
display_hashtag_results(generated_hashtags, performance_predictions, hashtag_placement)
|
||||
|
||||
def render_library_tab():
|
||||
"""Render the hashtag library tab."""
|
||||
|
||||
st.markdown("#### Hashtag Library")
|
||||
|
||||
# Initialize saved hashtags if not exists
|
||||
if 'saved_hashtags' not in st.session_state.hashtag_data:
|
||||
st.session_state.hashtag_data['saved_hashtags'] = []
|
||||
|
||||
# Create collections
|
||||
collections = ["Favorites", "Industry", "Campaign", "Custom"]
|
||||
|
||||
selected_collection = st.selectbox(
|
||||
"Select Collection",
|
||||
options=collections,
|
||||
index=0,
|
||||
help="Select a hashtag collection to view or edit",
|
||||
key="collection_select"
|
||||
)
|
||||
|
||||
# Display saved hashtags
|
||||
if st.session_state.hashtag_data['saved_hashtags']:
|
||||
st.markdown(f"**{selected_collection} Collection**")
|
||||
|
||||
for i, hashtag in enumerate(st.session_state.hashtag_data['saved_hashtags']):
|
||||
col1, col2 = st.columns([3, 1])
|
||||
|
||||
with col1:
|
||||
st.write(f"#{hashtag}")
|
||||
|
||||
with col2:
|
||||
if st.button("Remove", key=f"remove_{i}"):
|
||||
st.session_state.hashtag_data['saved_hashtags'].remove(hashtag)
|
||||
st.rerun()
|
||||
else:
|
||||
st.info("Your hashtag library is empty. Generate hashtags and save them to build your library.")
|
||||
|
||||
# Add new hashtag
|
||||
st.markdown("#### Add New Hashtag")
|
||||
|
||||
col1, col2 = st.columns([3, 1])
|
||||
|
||||
with col1:
|
||||
new_hashtag = st.text_input(
|
||||
"Enter hashtag (without #)",
|
||||
value="",
|
||||
help="Enter a hashtag to add to your library",
|
||||
key="new_hashtag_input"
|
||||
)
|
||||
|
||||
with col2:
|
||||
if st.button("Add", key="add_hashtag_button"):
|
||||
if new_hashtag:
|
||||
# Remove # if present
|
||||
new_hashtag = new_hashtag.replace("#", "")
|
||||
|
||||
# Add to saved hashtags
|
||||
if new_hashtag not in st.session_state.hashtag_data['saved_hashtags']:
|
||||
st.session_state.hashtag_data['saved_hashtags'].append(new_hashtag)
|
||||
st.success(f"Added #{new_hashtag} to your library.")
|
||||
else:
|
||||
st.warning(f"#{new_hashtag} is already in your library.")
|
||||
else:
|
||||
st.warning("Please enter a hashtag.")
|
||||
|
||||
def render_insights_tab():
|
||||
"""Render the performance insights tab."""
|
||||
|
||||
st.markdown("#### Hashtag Performance Insights")
|
||||
|
||||
# Check if we have generated hashtags
|
||||
if not st.session_state.hashtag_data['generated_hashtags']:
|
||||
st.info("Generate hashtags first to see performance insights.")
|
||||
return
|
||||
|
||||
# Display performance metrics
|
||||
st.markdown("##### Performance Predictions")
|
||||
|
||||
performance_predictions = st.session_state.hashtag_data['performance_predictions']
|
||||
|
||||
# Create a bar chart for reach predictions
|
||||
reach_data = {hashtag: data['reach'] for hashtag, data in performance_predictions.items()}
|
||||
|
||||
if reach_data:
|
||||
st.bar_chart(reach_data)
|
||||
|
||||
# Display detailed metrics
|
||||
st.markdown("##### Detailed Metrics")
|
||||
|
||||
for hashtag, metrics in performance_predictions.items():
|
||||
with st.expander(f"#{hashtag}"):
|
||||
col1, col2, col3 = st.columns(3)
|
||||
|
||||
with col1:
|
||||
st.metric("Reach", f"{metrics['reach']:,}")
|
||||
|
||||
with col2:
|
||||
st.metric("Engagement", f"{metrics['engagement']}%")
|
||||
|
||||
with col3:
|
||||
st.metric("Competition", metrics['competition'])
|
||||
|
||||
# Hashtag recommendations
|
||||
st.markdown("##### Recommendations")
|
||||
|
||||
# Find best performing hashtags
|
||||
best_hashtags = sorted(
|
||||
performance_predictions.items(),
|
||||
key=lambda x: x[1]['reach'],
|
||||
reverse=True
|
||||
)[:3]
|
||||
|
||||
st.markdown("**Best Performing Hashtags:**")
|
||||
for hashtag, metrics in best_hashtags:
|
||||
st.write(f"#{hashtag} - Reach: {metrics['reach']:,}, Engagement: {metrics['engagement']}%")
|
||||
|
||||
# Optimal combination
|
||||
st.markdown("**Optimal Hashtag Combination:**")
|
||||
optimal_combination = " ".join([f"#{hashtag}" for hashtag, _ in best_hashtags])
|
||||
st.code(optimal_combination)
|
||||
|
||||
# Copy button
|
||||
if st.button("Copy Optimal Combination", key="copy_optimal_button"):
|
||||
st.code(optimal_combination)
|
||||
st.success("Copied to clipboard!")
|
||||
|
||||
def generate_hashtags(
|
||||
content: str,
|
||||
industry: str,
|
||||
content_type: str,
|
||||
hashtag_count: int,
|
||||
include_trending: bool,
|
||||
include_niche: bool
|
||||
) -> Tuple[List[str], Dict[str, Dict[str, Any]]]:
|
||||
"""Generate hashtags based on content and preferences."""
|
||||
|
||||
# Prepare the prompt for the AI
|
||||
prompt = f"""
|
||||
Generate {hashtag_count} relevant and effective hashtags for a Facebook {content_type} in the {industry} industry.
|
||||
|
||||
Content or topic: {content}
|
||||
|
||||
Requirements:
|
||||
- Include a mix of popular and niche hashtags
|
||||
- Focus on hashtags that drive engagement and reach
|
||||
- Ensure hashtags are relevant to the content and industry
|
||||
- Format as a comma-separated list without the # symbol
|
||||
- Include {hashtag_count} hashtags total
|
||||
"""
|
||||
|
||||
if include_trending:
|
||||
prompt += "- Include some currently trending hashtags in this industry\n"
|
||||
|
||||
if include_niche:
|
||||
prompt += "- Include niche, industry-specific hashtags that have less competition\n"
|
||||
|
||||
prompt += """
|
||||
For each hashtag, also provide a performance prediction in this format:
|
||||
[hashtag_name]: [reach_number], [engagement_percentage], [competition_level]
|
||||
|
||||
Example:
|
||||
digitalmarketing: 50000, 3.2, Medium
|
||||
socialmediamarketing: 75000, 2.8, High
|
||||
"""
|
||||
|
||||
try:
|
||||
# Generate hashtags using AI
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
# Parse the response
|
||||
hashtags = []
|
||||
performance_predictions = {}
|
||||
|
||||
# Extract hashtags and performance data
|
||||
lines = response.strip().split('\n')
|
||||
for line in lines:
|
||||
if ':' in line:
|
||||
parts = line.split(':')
|
||||
if len(parts) == 2:
|
||||
hashtag = parts[0].strip()
|
||||
metrics = parts[1].strip().split(',')
|
||||
|
||||
if len(metrics) >= 3:
|
||||
try:
|
||||
reach = int(metrics[0].strip())
|
||||
engagement = float(metrics[1].strip().replace('%', ''))
|
||||
competition = metrics[2].strip()
|
||||
|
||||
hashtags.append(hashtag)
|
||||
performance_predictions[hashtag] = {
|
||||
'reach': reach,
|
||||
'engagement': engagement,
|
||||
'competition': competition
|
||||
}
|
||||
except (ValueError, IndexError):
|
||||
# Skip malformed entries
|
||||
continue
|
||||
|
||||
# If we couldn't parse the response properly, generate some default hashtags
|
||||
if not hashtags:
|
||||
hashtags = generate_default_hashtags(content, industry, hashtag_count)
|
||||
performance_predictions = generate_default_predictions(hashtags)
|
||||
|
||||
return hashtags, performance_predictions
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating hashtags: {e}")
|
||||
# Generate default hashtags as fallback
|
||||
hashtags = generate_default_hashtags(content, industry, hashtag_count)
|
||||
performance_predictions = generate_default_predictions(hashtags)
|
||||
return hashtags, performance_predictions
|
||||
|
||||
def generate_default_hashtags(content: str, industry: str, count: int) -> List[str]:
|
||||
"""Generate default hashtags when AI generation fails."""
|
||||
|
||||
# Extract keywords from content
|
||||
keywords = re.findall(r'\b\w+\b', content.lower())
|
||||
keywords = [k for k in keywords if len(k) > 3] # Filter out short words
|
||||
|
||||
# Industry-specific hashtags
|
||||
industry_hashtags = {
|
||||
"Technology": ["tech", "innovation", "digital", "future", "ai", "technews", "startup"],
|
||||
"Health & Wellness": ["health", "wellness", "fitness", "healthy", "wellbeing", "mindfulness"],
|
||||
"Fashion": ["fashion", "style", "trend", "outfit", "fashionista", "accessories"],
|
||||
"Food & Beverage": ["food", "foodie", "recipe", "cooking", "delicious", "foodporn"],
|
||||
"Travel": ["travel", "wanderlust", "adventure", "explore", "travelgram", "vacation"],
|
||||
"Education": ["education", "learning", "knowledge", "study", "student", "academic"],
|
||||
"Finance": ["finance", "money", "investing", "financial", "business", "wealth"],
|
||||
"Entertainment": ["entertainment", "fun", "music", "movie", "tv", "celebrity"],
|
||||
"Fitness": ["fitness", "workout", "gym", "exercise", "health", "training"],
|
||||
"Beauty": ["beauty", "makeup", "skincare", "beautytips", "glam", "beautylover"],
|
||||
"Home & Garden": ["home", "garden", "decor", "interior", "diy", "homemade"],
|
||||
"Automotive": ["car", "automotive", "vehicle", "driving", "cars", "auto"],
|
||||
"Real Estate": ["realestate", "property", "home", "housing", "realtor", "investment"],
|
||||
"Business": ["business", "entrepreneur", "success", "marketing", "smallbusiness", "startup"],
|
||||
"Art & Design": ["art", "design", "creative", "artist", "illustration", "designer"],
|
||||
"Sports": ["sports", "athlete", "game", "team", "competition", "winning"],
|
||||
"Parenting": ["parenting", "family", "kids", "children", "mom", "dad"],
|
||||
"Pets": ["pets", "dog", "cat", "animal", "petlover", "adoption"],
|
||||
"Other": ["trending", "viral", "popular", "mustsee", "recommended", "best"]
|
||||
}
|
||||
|
||||
# Get industry hashtags
|
||||
industry_tags = industry_hashtags.get(industry, industry_hashtags["Other"])
|
||||
|
||||
# Combine keywords and industry hashtags
|
||||
all_hashtags = list(set(keywords + industry_tags))
|
||||
|
||||
# Shuffle and select
|
||||
random.shuffle(all_hashtags)
|
||||
selected_hashtags = all_hashtags[:count]
|
||||
|
||||
return selected_hashtags
|
||||
|
||||
def generate_default_predictions(hashtags: List[str]) -> Dict[str, Dict[str, Any]]:
|
||||
"""Generate default performance predictions for hashtags."""
|
||||
|
||||
predictions = {}
|
||||
|
||||
for hashtag in hashtags:
|
||||
# Generate random but realistic predictions
|
||||
reach = random.randint(1000, 100000)
|
||||
engagement = round(random.uniform(0.5, 5.0), 1)
|
||||
competition = random.choice(["Low", "Medium", "High"])
|
||||
|
||||
predictions[hashtag] = {
|
||||
'reach': reach,
|
||||
'engagement': engagement,
|
||||
'competition': competition
|
||||
}
|
||||
|
||||
return predictions
|
||||
|
||||
def display_hashtag_results(
|
||||
hashtags: List[str],
|
||||
performance_predictions: Dict[str, Dict[str, Any]],
|
||||
placement: str
|
||||
):
|
||||
"""Display the generated hashtags and performance predictions."""
|
||||
|
||||
st.markdown("#### Generated Hashtags")
|
||||
|
||||
# Display hashtags
|
||||
hashtag_text = " ".join([f"#{hashtag}" for hashtag in hashtags])
|
||||
st.code(hashtag_text)
|
||||
|
||||
# Copy button
|
||||
if st.button("Copy All Hashtags", key="copy_hashtags_button"):
|
||||
st.code(hashtag_text)
|
||||
st.success("Copied to clipboard!")
|
||||
|
||||
# Save button
|
||||
if st.button("Save to Library", key="save_hashtags_button"):
|
||||
for hashtag in hashtags:
|
||||
if hashtag not in st.session_state.hashtag_data['saved_hashtags']:
|
||||
st.session_state.hashtag_data['saved_hashtags'].append(hashtag)
|
||||
st.success("Hashtags saved to your library!")
|
||||
|
||||
# Display placement suggestion
|
||||
st.markdown("#### Recommended Placement")
|
||||
|
||||
if placement == "End of Post":
|
||||
st.markdown("""
|
||||
**Place these hashtags at the end of your post:**
|
||||
|
||||
Add a line break after your content, then add the hashtags.
|
||||
""")
|
||||
st.code(hashtag_text)
|
||||
|
||||
elif placement == "Throughout Content":
|
||||
st.markdown("""
|
||||
**Weave these hashtags throughout your content:**
|
||||
|
||||
Integrate hashtags naturally within your sentences where they make sense.
|
||||
""")
|
||||
|
||||
# Create a sample with hashtags integrated
|
||||
sample_content = st.session_state.hashtag_data['content']
|
||||
words = sample_content.split()
|
||||
|
||||
# Insert hashtags at random positions
|
||||
for hashtag in hashtags[:3]: # Use first 3 hashtags
|
||||
if len(words) > 5:
|
||||
pos = random.randint(0, len(words) - 1)
|
||||
words.insert(pos, f"#{hashtag}")
|
||||
|
||||
sample_with_hashtags = " ".join(words)
|
||||
st.code(sample_with_hashtags)
|
||||
|
||||
else: # Both
|
||||
st.markdown("""
|
||||
**Use a combination of both approaches:**
|
||||
|
||||
1. Weave some hashtags naturally within your content
|
||||
2. Add the remaining hashtags at the end
|
||||
""")
|
||||
|
||||
# Create a sample with some hashtags integrated
|
||||
sample_content = st.session_state.hashtag_data['content']
|
||||
words = sample_content.split()
|
||||
|
||||
# Insert some hashtags at random positions
|
||||
for hashtag in hashtags[:2]: # Use first 2 hashtags
|
||||
if len(words) > 5:
|
||||
pos = random.randint(0, len(words) - 1)
|
||||
words.insert(pos, f"#{hashtag}")
|
||||
|
||||
sample_with_hashtags = " ".join(words)
|
||||
st.code(sample_with_hashtags)
|
||||
|
||||
# Add remaining hashtags at the end
|
||||
remaining_hashtags = " ".join([f"#{hashtag}" for hashtag in hashtags[2:]])
|
||||
st.markdown("**Add these at the end:**")
|
||||
st.code(remaining_hashtags)
|
||||
|
||||
# Display performance insights
|
||||
st.markdown("#### Performance Insights")
|
||||
|
||||
# Create a bar chart for reach predictions
|
||||
reach_data = {hashtag: data['reach'] for hashtag, data in performance_predictions.items()}
|
||||
|
||||
if reach_data:
|
||||
st.bar_chart(reach_data)
|
||||
|
||||
# Display detailed metrics
|
||||
st.markdown("##### Detailed Metrics")
|
||||
|
||||
for hashtag, metrics in performance_predictions.items():
|
||||
with st.expander(f"#{hashtag}"):
|
||||
col1, col2, col3 = st.columns(3)
|
||||
|
||||
with col1:
|
||||
st.metric("Reach", f"{metrics['reach']:,}")
|
||||
|
||||
with col2:
|
||||
st.metric("Engagement", f"{metrics['engagement']}%")
|
||||
|
||||
with col3:
|
||||
st.metric("Competition", metrics['competition'])
|
||||
@@ -1,133 +0,0 @@
|
||||
# Facebook Page About Generator
|
||||
|
||||
## Overview
|
||||
The Facebook Page About Generator is a powerful tool designed to help businesses and organizations create professional and engaging About sections for their Facebook Pages. It provides a comprehensive interface for crafting compelling content that effectively communicates brand identity, mission, and value proposition to visitors.
|
||||
|
||||
## Features
|
||||
|
||||
### Basic Information Management
|
||||
- **Business Details**: Input business name, industry, founding date, location, and contact information
|
||||
- **Mission Statement**: Create a concise and impactful mission statement
|
||||
- **Website Integration**: Add website URL and other online presence links
|
||||
- **Contact Information**: Include phone, email, and physical address
|
||||
|
||||
### Brand Voice & Tone
|
||||
- **Tone Selection**: Choose from professional, friendly, casual, formal, or humorous tones
|
||||
- **Brand Personality**: Define key personality traits that reflect your brand
|
||||
- **Target Audience**: Specify your primary audience demographics and interests
|
||||
- **Brand Values**: Highlight core values that guide your business
|
||||
|
||||
### Key Sections
|
||||
- **About Us/Our Story**: Share your company's history and journey
|
||||
- **Products/Services**: Highlight your offerings and their benefits
|
||||
- **Unique Selling Proposition**: Communicate what sets you apart
|
||||
- **Team/Leadership**: Showcase key team members and leadership
|
||||
- **Awards/Recognition**: Display achievements and accolades
|
||||
- **Customer Testimonials**: Share positive feedback from clients
|
||||
- **Call-to-Action**: Encourage visitors to take specific actions
|
||||
|
||||
### Preview & Export
|
||||
- **Live Preview**: See how your About section will appear before publishing
|
||||
- **Export Options**: Copy to clipboard or download as text file
|
||||
- **Format Validation**: Ensure your content meets Facebook's requirements
|
||||
- **SEO Optimization**: Get suggestions for better visibility
|
||||
|
||||
## How to Use
|
||||
|
||||
1. **Access the Generator**
|
||||
- Navigate to the Facebook Page About Generator in the AI Writer dashboard
|
||||
- Select "Create New About Section" to start
|
||||
|
||||
2. **Configure Basic Information**
|
||||
- Enter your business details
|
||||
- Define your mission statement
|
||||
- Add contact information
|
||||
|
||||
3. **Set Brand Voice & Tone**
|
||||
- Choose your preferred tone
|
||||
- Define brand personality traits
|
||||
- Specify target audience
|
||||
- List core brand values
|
||||
|
||||
4. **Customize Key Sections**
|
||||
- Toggle sections you want to include
|
||||
- Add custom content or generate with AI
|
||||
- Review and edit generated content
|
||||
|
||||
5. **Preview and Export**
|
||||
- Review the complete About section
|
||||
- Make final adjustments
|
||||
- Export or copy the content
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Content Creation
|
||||
- Keep descriptions concise and focused
|
||||
- Use clear, engaging language
|
||||
- Highlight unique aspects of your business
|
||||
- Include relevant keywords for SEO
|
||||
|
||||
### Brand Voice
|
||||
- Maintain consistent tone throughout
|
||||
- Align with your overall brand identity
|
||||
- Use language that resonates with your target audience
|
||||
- Avoid jargon unless industry-specific
|
||||
|
||||
### Section Organization
|
||||
- Prioritize most important information first
|
||||
- Use formatting for better readability
|
||||
- Include visual elements when appropriate
|
||||
- End with a clear call-to-action
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
- Python 3.7+
|
||||
- Streamlit
|
||||
- Required Python packages:
|
||||
- streamlit
|
||||
- typing
|
||||
- datetime
|
||||
- json
|
||||
- logging
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
1. **Content Generation Fails**
|
||||
- Check your internet connection
|
||||
- Verify input parameters
|
||||
- Try reducing content length
|
||||
|
||||
2. **Export Problems**
|
||||
- Check available disk space
|
||||
- Verify write permissions
|
||||
- Ensure proper file naming
|
||||
|
||||
3. **Preview Issues**
|
||||
- Clear browser cache
|
||||
- Check for formatting errors
|
||||
- Verify all required fields are filled
|
||||
|
||||
## Future Updates
|
||||
|
||||
- Enhanced AI content generation
|
||||
- Industry-specific templates
|
||||
- Multi-language support
|
||||
- Advanced SEO recommendations
|
||||
- Integration with other social platforms
|
||||
- Analytics for About section performance
|
||||
- A/B testing capabilities
|
||||
- Custom section creation
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions to improve the Facebook Page About Generator. Please follow these steps:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
This module is licensed under the MIT License. See the LICENSE file for details.
|
||||
@@ -1,11 +0,0 @@
|
||||
"""
|
||||
Facebook Page About Generator Module
|
||||
|
||||
This module provides functionality to generate professional and engaging About sections
|
||||
for Facebook Pages. It helps businesses create compelling content that effectively
|
||||
communicates their brand identity, mission, and value proposition to visitors.
|
||||
"""
|
||||
|
||||
from .page_about_generator import write_fb_page_about
|
||||
|
||||
__all__ = ['write_fb_page_about']
|
||||
@@ -1,649 +0,0 @@
|
||||
"""
|
||||
Facebook Page About Generator Module
|
||||
|
||||
This module provides functionality to generate professional and engaging About sections
|
||||
for Facebook Pages. It helps businesses create compelling content that effectively
|
||||
communicates their brand identity, mission, and value proposition to visitors.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Optional, Union, Tuple
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
|
||||
# Set up logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def write_fb_page_about():
|
||||
"""
|
||||
Generate a Facebook Page About section with various customization options.
|
||||
|
||||
This function provides a comprehensive interface for creating professional
|
||||
and engaging About sections for Facebook Pages with features like:
|
||||
- Basic information management
|
||||
- Brand voice and tone customization
|
||||
- Key sections configuration
|
||||
- Preview and export options
|
||||
"""
|
||||
|
||||
st.title("Facebook Page About Generator")
|
||||
st.markdown("""
|
||||
Create professional and engaging About sections for your Facebook Pages that effectively
|
||||
communicate your brand identity, mission, and value proposition to visitors.
|
||||
""")
|
||||
|
||||
# Initialize session state for form data
|
||||
if 'page_about_data' not in st.session_state:
|
||||
st.session_state.page_about_data = {
|
||||
# Basic Information
|
||||
'business_name': '',
|
||||
'industry': '',
|
||||
'founded_date': '',
|
||||
'location': '',
|
||||
'website': '',
|
||||
'phone': '',
|
||||
'email': '',
|
||||
'address': '',
|
||||
'mission_statement': '',
|
||||
|
||||
# Brand Voice & Tone
|
||||
'tone': 'professional',
|
||||
'brand_personality': [],
|
||||
'target_audience': '',
|
||||
'brand_values': [],
|
||||
|
||||
# Key Sections
|
||||
'include_about_us': True,
|
||||
'about_us_content': '',
|
||||
'include_products': True,
|
||||
'products_content': '',
|
||||
'include_usp': True,
|
||||
'usp_content': '',
|
||||
'include_team': False,
|
||||
'team_content': '',
|
||||
'include_awards': False,
|
||||
'awards_content': '',
|
||||
'include_testimonials': False,
|
||||
'testimonials_content': '',
|
||||
'include_cta': True,
|
||||
'cta_content': '',
|
||||
|
||||
# Content Length
|
||||
'content_length': 'standard',
|
||||
|
||||
# Generated Content
|
||||
'generated_content': '',
|
||||
'show_preview': False
|
||||
}
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3, tab4 = st.tabs([
|
||||
"Basic Information",
|
||||
"Brand Voice & Tone",
|
||||
"Key Sections",
|
||||
"Preview & Export"
|
||||
])
|
||||
|
||||
with tab1:
|
||||
render_basic_info_tab()
|
||||
|
||||
with tab2:
|
||||
render_brand_voice_tab()
|
||||
|
||||
with tab3:
|
||||
render_key_sections_tab()
|
||||
|
||||
with tab4:
|
||||
render_preview_export_tab()
|
||||
|
||||
# Generate button
|
||||
if st.button("Generate About Section", type="primary"):
|
||||
if validate_page_about_fields():
|
||||
with st.spinner("Generating your About section..."):
|
||||
about_content = generate_page_about()
|
||||
if about_content:
|
||||
st.session_state.page_about_data['generated_content'] = about_content
|
||||
st.success("About section generated successfully!")
|
||||
st.session_state.page_about_data['show_preview'] = True
|
||||
st.rerun()
|
||||
|
||||
def render_basic_info_tab():
|
||||
"""Render the basic information input fields."""
|
||||
|
||||
st.header("Basic Information")
|
||||
|
||||
# Business Name
|
||||
business_name = st.text_input(
|
||||
"Business/Organization Name",
|
||||
value=st.session_state.page_about_data['business_name'],
|
||||
help="Enter your business or organization name"
|
||||
)
|
||||
st.session_state.page_about_data['business_name'] = business_name
|
||||
|
||||
# Industry
|
||||
industry = st.text_input(
|
||||
"Industry/Category",
|
||||
value=st.session_state.page_about_data['industry'],
|
||||
help="Enter your industry or business category"
|
||||
)
|
||||
st.session_state.page_about_data['industry'] = industry
|
||||
|
||||
# Founded Date
|
||||
founded_date = st.text_input(
|
||||
"Founded Date",
|
||||
value=st.session_state.page_about_data['founded_date'],
|
||||
help="Enter when your business was founded (e.g., '2010' or 'January 2010')"
|
||||
)
|
||||
st.session_state.page_about_data['founded_date'] = founded_date
|
||||
|
||||
# Location
|
||||
location = st.text_input(
|
||||
"Location",
|
||||
value=st.session_state.page_about_data['location'],
|
||||
help="Enter your business location (city, state, country)"
|
||||
)
|
||||
st.session_state.page_about_data['location'] = location
|
||||
|
||||
# Website
|
||||
website = st.text_input(
|
||||
"Website URL",
|
||||
value=st.session_state.page_about_data['website'],
|
||||
help="Enter your website URL"
|
||||
)
|
||||
st.session_state.page_about_data['website'] = website
|
||||
|
||||
# Contact Information
|
||||
st.subheader("Contact Information")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
phone = st.text_input(
|
||||
"Phone Number",
|
||||
value=st.session_state.page_about_data['phone'],
|
||||
help="Enter your business phone number"
|
||||
)
|
||||
st.session_state.page_about_data['phone'] = phone
|
||||
|
||||
email = st.text_input(
|
||||
"Email Address",
|
||||
value=st.session_state.page_about_data['email'],
|
||||
help="Enter your business email address"
|
||||
)
|
||||
st.session_state.page_about_data['email'] = email
|
||||
|
||||
with col2:
|
||||
address = st.text_area(
|
||||
"Physical Address",
|
||||
value=st.session_state.page_about_data['address'],
|
||||
help="Enter your business physical address",
|
||||
height=100
|
||||
)
|
||||
st.session_state.page_about_data['address'] = address
|
||||
|
||||
# Mission Statement
|
||||
mission_statement = st.text_area(
|
||||
"Mission Statement",
|
||||
value=st.session_state.page_about_data['mission_statement'],
|
||||
help="Enter your business mission statement (1-2 sentences)",
|
||||
height=100
|
||||
)
|
||||
st.session_state.page_about_data['mission_statement'] = mission_statement
|
||||
|
||||
def render_brand_voice_tab():
|
||||
"""Render the brand voice and tone selection fields."""
|
||||
|
||||
st.header("Brand Voice & Tone")
|
||||
|
||||
# Tone Selection
|
||||
tone = st.selectbox(
|
||||
"Select Tone",
|
||||
options=['professional', 'friendly', 'casual', 'formal', 'humorous'],
|
||||
index=['professional', 'friendly', 'casual', 'formal', 'humorous'].index(
|
||||
st.session_state.page_about_data['tone']
|
||||
),
|
||||
help="Choose the tone for your About section"
|
||||
)
|
||||
st.session_state.page_about_data['tone'] = tone
|
||||
|
||||
# Brand Personality Traits
|
||||
st.subheader("Brand Personality Traits")
|
||||
|
||||
personality_options = [
|
||||
'Innovative', 'Reliable', 'Creative', 'Professional', 'Friendly',
|
||||
'Authoritative', 'Empathetic', 'Ambitious', 'Authentic', 'Dynamic',
|
||||
'Trustworthy', 'Passionate', 'Efficient', 'Eco-friendly', 'Luxurious'
|
||||
]
|
||||
|
||||
# Initialize brand_personality in session state if not present
|
||||
if 'brand_personality' not in st.session_state.page_about_data:
|
||||
st.session_state.page_about_data['brand_personality'] = []
|
||||
|
||||
# Create a multi-select for brand personality traits
|
||||
selected_traits = st.multiselect(
|
||||
"Select Brand Personality Traits (up to 5)",
|
||||
options=personality_options,
|
||||
default=st.session_state.page_about_data['brand_personality'],
|
||||
help="Choose up to 5 traits that best describe your brand personality"
|
||||
)
|
||||
|
||||
# Limit to 5 traits
|
||||
if len(selected_traits) > 5:
|
||||
st.warning("You can only select up to 5 traits. The first 5 will be used.")
|
||||
selected_traits = selected_traits[:5]
|
||||
|
||||
st.session_state.page_about_data['brand_personality'] = selected_traits
|
||||
|
||||
# Target Audience
|
||||
target_audience = st.text_area(
|
||||
"Target Audience",
|
||||
value=st.session_state.page_about_data['target_audience'],
|
||||
help="Describe your target audience (demographics, interests, needs)",
|
||||
height=100
|
||||
)
|
||||
st.session_state.page_about_data['target_audience'] = target_audience
|
||||
|
||||
# Brand Values
|
||||
st.subheader("Brand Values")
|
||||
|
||||
# Initialize brand_values in session state if not present
|
||||
if 'brand_values' not in st.session_state.page_about_data:
|
||||
st.session_state.page_about_data['brand_values'] = []
|
||||
|
||||
# Create a dynamic list for brand values
|
||||
brand_values = st.session_state.page_about_data['brand_values']
|
||||
|
||||
# Add new value
|
||||
new_value = st.text_input("Add a brand value", key="new_brand_value")
|
||||
if st.button("Add Value") and new_value:
|
||||
if new_value not in brand_values:
|
||||
brand_values.append(new_value)
|
||||
st.session_state.page_about_data['brand_values'] = brand_values
|
||||
st.rerun()
|
||||
|
||||
# Display and allow removal of existing values
|
||||
if brand_values:
|
||||
st.write("Current Brand Values:")
|
||||
for i, value in enumerate(brand_values):
|
||||
col1, col2 = st.columns([4, 1])
|
||||
with col1:
|
||||
st.write(f"{i+1}. {value}")
|
||||
with col2:
|
||||
if st.button("Remove", key=f"remove_value_{i}"):
|
||||
brand_values.pop(i)
|
||||
st.session_state.page_about_data['brand_values'] = brand_values
|
||||
st.rerun()
|
||||
else:
|
||||
st.info("No brand values added yet. Add at least one brand value.")
|
||||
|
||||
def render_key_sections_tab():
|
||||
"""Render the key sections configuration fields."""
|
||||
|
||||
st.header("Key Sections")
|
||||
|
||||
# Content Length
|
||||
content_length = st.selectbox(
|
||||
"Content Length",
|
||||
options=['brief', 'standard', 'detailed'],
|
||||
index=['brief', 'standard', 'detailed'].index(
|
||||
st.session_state.page_about_data['content_length']
|
||||
),
|
||||
help="Choose the length of the generated content"
|
||||
)
|
||||
st.session_state.page_about_data['content_length'] = content_length
|
||||
|
||||
# About Us Section
|
||||
st.subheader("About Us/Our Story")
|
||||
include_about_us = st.checkbox(
|
||||
"Include About Us Section",
|
||||
value=st.session_state.page_about_data['include_about_us'],
|
||||
help="Include a section about your company's history and journey"
|
||||
)
|
||||
st.session_state.page_about_data['include_about_us'] = include_about_us
|
||||
|
||||
if include_about_us:
|
||||
about_us_content = st.text_area(
|
||||
"Custom About Us Content (optional)",
|
||||
value=st.session_state.page_about_data['about_us_content'],
|
||||
help="Enter custom content or leave blank for AI generation",
|
||||
height=150
|
||||
)
|
||||
st.session_state.page_about_data['about_us_content'] = about_us_content
|
||||
|
||||
# Products/Services Section
|
||||
st.subheader("Products/Services")
|
||||
include_products = st.checkbox(
|
||||
"Include Products/Services Section",
|
||||
value=st.session_state.page_about_data['include_products'],
|
||||
help="Include a section about your products or services"
|
||||
)
|
||||
st.session_state.page_about_data['include_products'] = include_products
|
||||
|
||||
if include_products:
|
||||
products_content = st.text_area(
|
||||
"Custom Products/Services Content (optional)",
|
||||
value=st.session_state.page_about_data['products_content'],
|
||||
help="Enter custom content or leave blank for AI generation",
|
||||
height=150
|
||||
)
|
||||
st.session_state.page_about_data['products_content'] = products_content
|
||||
|
||||
# Unique Selling Proposition Section
|
||||
st.subheader("Unique Selling Proposition")
|
||||
include_usp = st.checkbox(
|
||||
"Include USP Section",
|
||||
value=st.session_state.page_about_data['include_usp'],
|
||||
help="Include a section highlighting what sets you apart"
|
||||
)
|
||||
st.session_state.page_about_data['include_usp'] = include_usp
|
||||
|
||||
if include_usp:
|
||||
usp_content = st.text_area(
|
||||
"Custom USP Content (optional)",
|
||||
value=st.session_state.page_about_data['usp_content'],
|
||||
help="Enter custom content or leave blank for AI generation",
|
||||
height=150
|
||||
)
|
||||
st.session_state.page_about_data['usp_content'] = usp_content
|
||||
|
||||
# Team/Leadership Section
|
||||
st.subheader("Team/Leadership")
|
||||
include_team = st.checkbox(
|
||||
"Include Team/Leadership Section",
|
||||
value=st.session_state.page_about_data['include_team'],
|
||||
help="Include a section about your team or leadership"
|
||||
)
|
||||
st.session_state.page_about_data['include_team'] = include_team
|
||||
|
||||
if include_team:
|
||||
team_content = st.text_area(
|
||||
"Custom Team/Leadership Content (optional)",
|
||||
value=st.session_state.page_about_data['team_content'],
|
||||
help="Enter custom content or leave blank for AI generation",
|
||||
height=150
|
||||
)
|
||||
st.session_state.page_about_data['team_content'] = team_content
|
||||
|
||||
# Awards/Recognition Section
|
||||
st.subheader("Awards/Recognition")
|
||||
include_awards = st.checkbox(
|
||||
"Include Awards/Recognition Section",
|
||||
value=st.session_state.page_about_data['include_awards'],
|
||||
help="Include a section about your awards and recognition"
|
||||
)
|
||||
st.session_state.page_about_data['include_awards'] = include_awards
|
||||
|
||||
if include_awards:
|
||||
awards_content = st.text_area(
|
||||
"Custom Awards/Recognition Content (optional)",
|
||||
value=st.session_state.page_about_data['awards_content'],
|
||||
help="Enter custom content or leave blank for AI generation",
|
||||
height=150
|
||||
)
|
||||
st.session_state.page_about_data['awards_content'] = awards_content
|
||||
|
||||
# Customer Testimonials Section
|
||||
st.subheader("Customer Testimonials")
|
||||
include_testimonials = st.checkbox(
|
||||
"Include Customer Testimonials Section",
|
||||
value=st.session_state.page_about_data['include_testimonials'],
|
||||
help="Include a section with customer testimonials"
|
||||
)
|
||||
st.session_state.page_about_data['include_testimonials'] = include_testimonials
|
||||
|
||||
if include_testimonials:
|
||||
testimonials_content = st.text_area(
|
||||
"Custom Testimonials Content (optional)",
|
||||
value=st.session_state.page_about_data['testimonials_content'],
|
||||
help="Enter custom content or leave blank for AI generation",
|
||||
height=150
|
||||
)
|
||||
st.session_state.page_about_data['testimonials_content'] = testimonials_content
|
||||
|
||||
# Call-to-Action Section
|
||||
st.subheader("Call-to-Action")
|
||||
include_cta = st.checkbox(
|
||||
"Include Call-to-Action Section",
|
||||
value=st.session_state.page_about_data['include_cta'],
|
||||
help="Include a call-to-action to encourage visitors to take specific actions"
|
||||
)
|
||||
st.session_state.page_about_data['include_cta'] = include_cta
|
||||
|
||||
if include_cta:
|
||||
cta_content = st.text_area(
|
||||
"Custom Call-to-Action Content (optional)",
|
||||
value=st.session_state.page_about_data['cta_content'],
|
||||
help="Enter custom content or leave blank for AI generation",
|
||||
height=150
|
||||
)
|
||||
st.session_state.page_about_data['cta_content'] = cta_content
|
||||
|
||||
def render_preview_export_tab():
|
||||
"""Render the preview and export options."""
|
||||
|
||||
st.header("Preview & Export")
|
||||
|
||||
# Show preview if content has been generated
|
||||
if st.session_state.page_about_data['show_preview'] and st.session_state.page_about_data['generated_content']:
|
||||
st.subheader("Preview")
|
||||
|
||||
# Toggle between mobile and desktop view
|
||||
view_mode = st.radio("View Mode", ["Desktop", "Mobile"])
|
||||
|
||||
if view_mode == "Desktop":
|
||||
st.markdown("""
|
||||
<div style='background-color: #f0f2f6; padding: 20px; border-radius: 10px;'>
|
||||
<h2 style='color: #1877F2;'>About</h2>
|
||||
<div style='white-space: pre-wrap;'>
|
||||
""", unsafe_allow_html=True)
|
||||
st.write(st.session_state.page_about_data['generated_content'])
|
||||
st.markdown("</div></div>", unsafe_allow_html=True)
|
||||
else:
|
||||
st.markdown("""
|
||||
<div style='max-width: 375px; margin: 0 auto; background-color: #f0f2f6; padding: 15px; border-radius: 10px;'>
|
||||
<h2 style='color: #1877F2; font-size: 18px;'>About</h2>
|
||||
<div style='white-space: pre-wrap; font-size: 14px;'>
|
||||
""", unsafe_allow_html=True)
|
||||
st.write(st.session_state.page_about_data['generated_content'])
|
||||
st.markdown("</div></div>", unsafe_allow_html=True)
|
||||
|
||||
# SEO Score
|
||||
seo_score = calculate_seo_score(st.session_state.page_about_data['generated_content'])
|
||||
st.subheader(f"SEO Score: {seo_score}/10")
|
||||
|
||||
if seo_score < 7:
|
||||
st.warning("Your About section could benefit from SEO improvements. Consider adding more keywords and optimizing your content.")
|
||||
|
||||
# Export options
|
||||
st.subheader("Export Options")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
if st.button("Copy to Clipboard"):
|
||||
st.code(st.session_state.page_about_data['generated_content'], language=None)
|
||||
st.success("Content copied to clipboard!")
|
||||
|
||||
with col2:
|
||||
if st.button("Download as Text"):
|
||||
download_page_about(st.session_state.page_about_data['generated_content'])
|
||||
else:
|
||||
st.info("Generate your About section to see a preview and export options.")
|
||||
|
||||
def validate_page_about_fields() -> bool:
|
||||
"""Validate the required fields for the page about generator."""
|
||||
|
||||
data = st.session_state.page_about_data
|
||||
|
||||
# Check required fields
|
||||
if not data['business_name']:
|
||||
st.error("Business/Organization Name is required.")
|
||||
return False
|
||||
|
||||
if not data['industry']:
|
||||
st.error("Industry/Category is required.")
|
||||
return False
|
||||
|
||||
if not data['mission_statement']:
|
||||
st.error("Mission Statement is required.")
|
||||
return False
|
||||
|
||||
if not data['target_audience']:
|
||||
st.error("Target Audience is required.")
|
||||
return False
|
||||
|
||||
if not data['brand_personality']:
|
||||
st.error("At least one Brand Personality Trait is required.")
|
||||
return False
|
||||
|
||||
if not data['brand_values']:
|
||||
st.error("At least one Brand Value is required.")
|
||||
return False
|
||||
|
||||
# Check if at least one section is included
|
||||
sections_included = (
|
||||
data['include_about_us'] or
|
||||
data['include_products'] or
|
||||
data['include_usp'] or
|
||||
data['include_team'] or
|
||||
data['include_awards'] or
|
||||
data['include_testimonials'] or
|
||||
data['include_cta']
|
||||
)
|
||||
|
||||
if not sections_included:
|
||||
st.error("At least one section must be included.")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def generate_page_about() -> Optional[str]:
|
||||
"""Generate the page about content using AI."""
|
||||
|
||||
try:
|
||||
data = st.session_state.page_about_data
|
||||
|
||||
# Prepare the prompt for the LLM
|
||||
prompt = f"""
|
||||
Create a Facebook Page About section for {data['business_name']}, a {data['industry']} business.
|
||||
|
||||
Basic Information:
|
||||
- Founded: {data['founded_date']}
|
||||
- Location: {data['location']}
|
||||
- Website: {data['website']}
|
||||
- Mission Statement: {data['mission_statement']}
|
||||
|
||||
Brand Voice & Tone:
|
||||
- Tone: {data['tone']}
|
||||
- Brand Personality Traits: {', '.join(data['brand_personality'])}
|
||||
- Target Audience: {data['target_audience']}
|
||||
- Brand Values: {', '.join(data['brand_values'])}
|
||||
|
||||
Content Length: {data['content_length']}
|
||||
|
||||
Include the following sections:
|
||||
"""
|
||||
|
||||
# Add sections to include
|
||||
if data['include_about_us']:
|
||||
prompt += f"""
|
||||
- About Us/Our Story: {data['about_us_content'] if data['about_us_content'] else 'Generate engaging content about the company history and journey'}
|
||||
"""
|
||||
|
||||
if data['include_products']:
|
||||
prompt += f"""
|
||||
- Products/Services: {data['products_content'] if data['products_content'] else 'Generate engaging content about the products or services offered'}
|
||||
"""
|
||||
|
||||
if data['include_usp']:
|
||||
prompt += f"""
|
||||
- Unique Selling Proposition: {data['usp_content'] if data['usp_content'] else 'Generate engaging content about what sets the business apart'}
|
||||
"""
|
||||
|
||||
if data['include_team']:
|
||||
prompt += f"""
|
||||
- Team/Leadership: {data['team_content'] if data['team_content'] else 'Generate engaging content about the team or leadership'}
|
||||
"""
|
||||
|
||||
if data['include_awards']:
|
||||
prompt += f"""
|
||||
- Awards/Recognition: {data['awards_content'] if data['awards_content'] else 'Generate engaging content about awards and recognition'}
|
||||
"""
|
||||
|
||||
if data['include_testimonials']:
|
||||
prompt += f"""
|
||||
- Customer Testimonials: {data['testimonials_content'] if data['testimonials_content'] else 'Generate engaging content with customer testimonials'}
|
||||
"""
|
||||
|
||||
if data['include_cta']:
|
||||
prompt += f"""
|
||||
- Call-to-Action: {data['cta_content'] if data['cta_content'] else 'Generate an engaging call-to-action'}
|
||||
"""
|
||||
|
||||
prompt += """
|
||||
The About section should be well-structured, engaging, and optimized for Facebook.
|
||||
Use appropriate formatting, emojis, and line breaks for better readability.
|
||||
Make sure the tone is consistent with the selected brand voice.
|
||||
Include relevant keywords for SEO optimization.
|
||||
"""
|
||||
|
||||
# Get response from LLM
|
||||
response = llm_text_gen(prompt)
|
||||
|
||||
if response:
|
||||
return response
|
||||
else:
|
||||
st.error("Failed to generate About section content. Please try again.")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating About section: {str(e)}")
|
||||
st.error("An error occurred while generating the About section. Please try again.")
|
||||
return None
|
||||
|
||||
def calculate_seo_score(content: str) -> int:
|
||||
"""Calculate a simple SEO score for the content."""
|
||||
|
||||
score = 5 # Start with a base score
|
||||
|
||||
# Check for keywords (simple implementation)
|
||||
keywords = ['about', 'mission', 'vision', 'values', 'services', 'products', 'team', 'contact']
|
||||
for keyword in keywords:
|
||||
if keyword.lower() in content.lower():
|
||||
score += 0.5
|
||||
|
||||
# Check for formatting
|
||||
if '\n\n' in content: # Paragraph breaks
|
||||
score += 1
|
||||
|
||||
if '*' in content or '_' in content: # Bold or italic formatting
|
||||
score += 1
|
||||
|
||||
# Check for length
|
||||
if len(content) > 500:
|
||||
score += 1
|
||||
|
||||
# Cap the score at 10
|
||||
return min(score, 10)
|
||||
|
||||
def download_page_about(content: str):
|
||||
"""Download the About section content as a text file."""
|
||||
|
||||
try:
|
||||
# Create a timestamp for the filename
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"facebook_page_about_{timestamp}.txt"
|
||||
|
||||
# Create a download button
|
||||
st.download_button(
|
||||
label="Download Text File",
|
||||
data=content,
|
||||
file_name=filename,
|
||||
mime="text/plain"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error downloading About section: {str(e)}")
|
||||
st.error("An error occurred while downloading the About section. Please try again.")
|
||||
@@ -1,231 +0,0 @@
|
||||
"""
|
||||
Facebook Post Generator Module
|
||||
|
||||
This module provides functionality to generate engaging Facebook posts with various features
|
||||
and optimization options.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
from ....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from ....gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
|
||||
|
||||
|
||||
def write_fb_post():
|
||||
"""Generate an engaging Facebook post with various features and optimization options."""
|
||||
|
||||
st.markdown("""
|
||||
### 📝 Facebook Post Generator
|
||||
Create engaging Facebook posts that drive engagement and reach. Customize your post with various features
|
||||
and get AI-powered suggestions for optimal performance.
|
||||
""")
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3 = st.tabs(["Post Content", "Media & Links", "Preview & Analytics"])
|
||||
|
||||
with tab1:
|
||||
# Basic post information
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
post_goal_options = [
|
||||
"Promote a product/service",
|
||||
"Share valuable content",
|
||||
"Increase engagement",
|
||||
"Build brand awareness",
|
||||
"Drive website traffic",
|
||||
"Generate leads",
|
||||
"Announce news/updates",
|
||||
"Customize"
|
||||
]
|
||||
post_goal = st.selectbox(
|
||||
"🎯 **What is the goal of your post?**",
|
||||
post_goal_options,
|
||||
index=2,
|
||||
help="Select the main goal of your post."
|
||||
)
|
||||
|
||||
if post_goal == "Customize":
|
||||
post_goal = st.text_input(
|
||||
"🎯 **Customize your goal:**",
|
||||
placeholder="e.g., Announce an event",
|
||||
help="Provide a specific goal if you selected 'Customize'."
|
||||
)
|
||||
|
||||
target_audience = st.text_input(
|
||||
"👥 **Describe your target audience:**",
|
||||
placeholder="e.g., Fitness enthusiasts aged 25-35",
|
||||
help="Describe the audience you are targeting with this post."
|
||||
)
|
||||
|
||||
post_tone_options = [
|
||||
"Informative",
|
||||
"Humorous",
|
||||
"Inspirational",
|
||||
"Upbeat",
|
||||
"Casual",
|
||||
"Professional",
|
||||
"Conversational",
|
||||
"Customize"
|
||||
]
|
||||
post_tone = st.selectbox(
|
||||
"🎨 **What tone do you want to use?**",
|
||||
post_tone_options,
|
||||
index=3,
|
||||
help="Choose the tone you want to use for the post."
|
||||
)
|
||||
|
||||
if post_tone == "Customize":
|
||||
post_tone = st.text_input(
|
||||
"🎨 **Customize your tone:**",
|
||||
placeholder="e.g., Professional",
|
||||
help="Provide a specific tone if you selected 'Customize'."
|
||||
)
|
||||
|
||||
with col2:
|
||||
business_type = st.text_input(
|
||||
"🏢 **What is your business type?**",
|
||||
placeholder="e.g., Fitness coach",
|
||||
help="Provide the type of your business. This will help tailor the post content."
|
||||
)
|
||||
|
||||
include = st.text_input(
|
||||
"📷 **What elements do you want to include?**",
|
||||
placeholder="e.g., Short video with a sneak peek of the challenge",
|
||||
help="Specify any elements you want to include in the post."
|
||||
)
|
||||
|
||||
avoid = st.text_input(
|
||||
"❌ **What elements do you want to avoid?**",
|
||||
placeholder="e.g., Long paragraphs",
|
||||
help="Specify any elements you want to avoid in the post."
|
||||
)
|
||||
|
||||
# Advanced options
|
||||
with st.expander("Advanced Options"):
|
||||
st.markdown("#### Post Structure")
|
||||
use_hook = st.checkbox("Use attention-grabbing hook", value=True)
|
||||
use_story = st.checkbox("Include storytelling elements", value=True)
|
||||
use_cta = st.checkbox("Add clear call-to-action", value=True)
|
||||
|
||||
st.markdown("#### Engagement Features")
|
||||
use_question = st.checkbox("Include engagement question", value=True)
|
||||
use_emoji = st.checkbox("Use relevant emojis", value=True)
|
||||
use_hashtags = st.checkbox("Add relevant hashtags", value=True)
|
||||
|
||||
with tab2:
|
||||
# Media and link options
|
||||
st.markdown("#### Media Options")
|
||||
media_type = st.radio(
|
||||
"Select media type:",
|
||||
["None", "Image", "Video", "Carousel", "Link Preview"],
|
||||
horizontal=True
|
||||
)
|
||||
|
||||
if media_type == "Image":
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
image_source = st.radio(
|
||||
"Image source:",
|
||||
["Upload", "Generate with AI", "Use URL"],
|
||||
horizontal=True
|
||||
)
|
||||
|
||||
if image_source == "Upload":
|
||||
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
|
||||
elif image_source == "Generate with AI":
|
||||
image_prompt = st.text_area("Describe the image you want to generate")
|
||||
if st.button("Generate Image"):
|
||||
with st.spinner("Generating image..."):
|
||||
# Call image generation function
|
||||
pass
|
||||
else:
|
||||
image_url = st.text_input("Enter image URL")
|
||||
|
||||
with col2:
|
||||
st.markdown("#### Image Settings")
|
||||
image_position = st.selectbox(
|
||||
"Image position:",
|
||||
["Above post", "Below post"]
|
||||
)
|
||||
add_image_caption = st.checkbox("Add image caption", value=True)
|
||||
|
||||
elif media_type == "Video":
|
||||
st.file_uploader("Upload a video", type=["mp4", "mov"])
|
||||
st.checkbox("Add video thumbnail", value=True)
|
||||
st.checkbox("Add video description", value=True)
|
||||
|
||||
elif media_type == "Carousel":
|
||||
st.file_uploader("Upload multiple images", type=["jpg", "jpeg", "png"], accept_multiple_files=True)
|
||||
st.checkbox("Add captions for each image", value=True)
|
||||
|
||||
elif media_type == "Link Preview":
|
||||
st.text_input("Enter URL to preview")
|
||||
st.checkbox("Customize link preview", value=False)
|
||||
|
||||
with tab3:
|
||||
# Preview and analytics section
|
||||
st.markdown("#### Post Preview")
|
||||
|
||||
# Generate post button
|
||||
if st.button("🚀 Generate Facebook Post", key="generate_post"):
|
||||
with st.spinner("Generating your post..."):
|
||||
if not business_type or not target_audience:
|
||||
st.error("🚫 Please provide the required inputs: Business Type and Target Audience.")
|
||||
else:
|
||||
# Generate the post content
|
||||
prompt = f"""
|
||||
Create a Facebook post for a {business_type} targeting {target_audience}.
|
||||
|
||||
Goal: {post_goal}
|
||||
Tone: {post_tone}
|
||||
|
||||
Include: {include}
|
||||
Avoid: {avoid}
|
||||
|
||||
Additional requirements:
|
||||
- Use attention-grabbing hook: {use_hook}
|
||||
- Include storytelling elements: {use_story}
|
||||
- Add clear call-to-action: {use_cta}
|
||||
- Include engagement question: {use_question}
|
||||
- Use relevant emojis: {use_emoji}
|
||||
- Add relevant hashtags: {use_hashtags}
|
||||
|
||||
Please write a well-structured Facebook post that:
|
||||
1. Grabs attention in the first line
|
||||
2. Maintains consistent tone throughout
|
||||
3. Includes engaging content that aligns with the goal
|
||||
4. Ends with a clear call-to-action
|
||||
5. Uses appropriate formatting and emojis
|
||||
6. Includes relevant hashtags if requested
|
||||
"""
|
||||
|
||||
generated_post = llm_text_gen(prompt)
|
||||
|
||||
if generated_post:
|
||||
# Display the generated post
|
||||
st.markdown("### Generated Post")
|
||||
st.markdown(generated_post)
|
||||
|
||||
# Display engagement predictions
|
||||
st.markdown("### 📊 Engagement Predictions")
|
||||
col1, col2, col3 = st.columns(3)
|
||||
with col1:
|
||||
st.metric("Expected Reach", "2.5K - 5K")
|
||||
with col2:
|
||||
st.metric("Expected Engagement", "5-8%")
|
||||
with col3:
|
||||
st.metric("Best Time to Post", "2 PM - 4 PM")
|
||||
|
||||
# Display optimization suggestions
|
||||
st.markdown("### 💡 Optimization Suggestions")
|
||||
st.info("""
|
||||
- Consider adding a question to increase comments
|
||||
- Use more emojis to increase visibility
|
||||
- Keep paragraphs shorter for better readability
|
||||
- Add a poll to increase engagement
|
||||
""")
|
||||
|
||||
# Copy button
|
||||
st.button("📋 Copy to Clipboard", key="copy_post")
|
||||
else:
|
||||
st.error("Error: Failed to generate Facebook Post.")
|
||||
@@ -1,246 +0,0 @@
|
||||
"""
|
||||
Facebook Story Generator Module
|
||||
|
||||
This module provides functionality to generate engaging Facebook Stories with various features
|
||||
and customization options.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
from ....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from ....gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
|
||||
|
||||
|
||||
def write_fb_story():
|
||||
"""Generate an engaging Facebook Story with various features and customization options."""
|
||||
|
||||
st.markdown("""
|
||||
### 📱 Facebook Story Generator
|
||||
Create engaging Facebook Stories that capture attention and drive engagement. Customize your story
|
||||
with various features and get AI-powered suggestions for optimal performance.
|
||||
""")
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3 = st.tabs(["Story Content", "Visual Elements", "Preview & Analytics"])
|
||||
|
||||
with tab1:
|
||||
# Basic story information
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
story_type_options = [
|
||||
"Product showcase",
|
||||
"Behind the scenes",
|
||||
"User testimonial",
|
||||
"Event promotion",
|
||||
"Tutorial/How-to",
|
||||
"Question/Poll",
|
||||
"Announcement",
|
||||
"Customize"
|
||||
]
|
||||
story_type = st.selectbox(
|
||||
"🎯 **What type of story do you want to create?**",
|
||||
story_type_options,
|
||||
index=0,
|
||||
help="Select the type of story you want to create."
|
||||
)
|
||||
|
||||
if story_type == "Customize":
|
||||
story_type = st.text_input(
|
||||
"🎯 **Customize your story type:**",
|
||||
placeholder="e.g., Product launch",
|
||||
help="Provide a specific story type if you selected 'Customize'."
|
||||
)
|
||||
|
||||
target_audience = st.text_input(
|
||||
"👥 **Describe your target audience:**",
|
||||
placeholder="e.g., Fashion enthusiasts aged 18-24",
|
||||
help="Describe the audience you are targeting with this story."
|
||||
)
|
||||
|
||||
story_tone_options = [
|
||||
"Casual",
|
||||
"Fun",
|
||||
"Professional",
|
||||
"Inspirational",
|
||||
"Educational",
|
||||
"Entertaining",
|
||||
"Customize"
|
||||
]
|
||||
story_tone = st.selectbox(
|
||||
"🎨 **What tone do you want to use?**",
|
||||
story_tone_options,
|
||||
index=0,
|
||||
help="Choose the tone you want to use for the story."
|
||||
)
|
||||
|
||||
if story_tone == "Customize":
|
||||
story_tone = st.text_input(
|
||||
"🎨 **Customize your tone:**",
|
||||
placeholder="e.g., Playful",
|
||||
help="Provide a specific tone if you selected 'Customize'."
|
||||
)
|
||||
|
||||
with col2:
|
||||
business_type = st.text_input(
|
||||
"🏢 **What is your business type?**",
|
||||
placeholder="e.g., Fashion brand",
|
||||
help="Provide the type of your business. This will help tailor the story content."
|
||||
)
|
||||
|
||||
include = st.text_input(
|
||||
"📷 **What elements do you want to include?**",
|
||||
placeholder="e.g., Product demonstration, customer testimonial",
|
||||
help="Specify any elements you want to include in the story."
|
||||
)
|
||||
|
||||
avoid = st.text_input(
|
||||
"❌ **What elements do you want to avoid?**",
|
||||
placeholder="e.g., Long text overlays",
|
||||
help="Specify any elements you want to avoid in the story."
|
||||
)
|
||||
|
||||
# Advanced options
|
||||
with st.expander("Advanced Options"):
|
||||
st.markdown("#### Story Structure")
|
||||
use_hook = st.checkbox("Use attention-grabbing opening", value=True)
|
||||
use_story = st.checkbox("Include storytelling elements", value=True)
|
||||
use_cta = st.checkbox("Add clear call-to-action", value=True)
|
||||
|
||||
st.markdown("#### Engagement Features")
|
||||
use_question = st.checkbox("Include engagement question", value=True)
|
||||
use_emoji = st.checkbox("Use relevant emojis", value=True)
|
||||
use_hashtags = st.checkbox("Add relevant hashtags", value=True)
|
||||
use_stickers = st.checkbox("Add interactive stickers", value=True)
|
||||
|
||||
with tab2:
|
||||
# Visual elements options
|
||||
st.markdown("#### Visual Elements")
|
||||
|
||||
# Background options
|
||||
st.markdown("##### Background")
|
||||
background_type = st.radio(
|
||||
"Select background type:",
|
||||
["Solid color", "Gradient", "Image", "Video"],
|
||||
horizontal=True
|
||||
)
|
||||
|
||||
if background_type == "Solid color":
|
||||
st.color_picker("Choose background color", "#FFFFFF")
|
||||
elif background_type == "Gradient":
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
st.color_picker("Start color", "#FFFFFF")
|
||||
with col2:
|
||||
st.color_picker("End color", "#000000")
|
||||
elif background_type == "Image":
|
||||
image_source = st.radio(
|
||||
"Image source:",
|
||||
["Upload", "Generate with AI", "Use URL"],
|
||||
horizontal=True
|
||||
)
|
||||
|
||||
if image_source == "Upload":
|
||||
st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
|
||||
elif image_source == "Generate with AI":
|
||||
image_prompt = st.text_area("Describe the image you want to generate")
|
||||
if st.button("Generate Image"):
|
||||
with st.spinner("Generating image..."):
|
||||
# Call image generation function
|
||||
pass
|
||||
else:
|
||||
st.text_input("Enter image URL")
|
||||
else:
|
||||
st.file_uploader("Upload a video", type=["mp4", "mov"])
|
||||
|
||||
# Text overlay options
|
||||
st.markdown("##### Text Overlay")
|
||||
text_style = st.selectbox(
|
||||
"Text style:",
|
||||
["Minimal", "Bold", "Playful", "Professional", "Custom"]
|
||||
)
|
||||
|
||||
if text_style == "Custom":
|
||||
st.text_input("Custom text style description")
|
||||
|
||||
text_color = st.color_picker("Text color", "#000000")
|
||||
text_position = st.selectbox(
|
||||
"Text position:",
|
||||
["Top", "Middle", "Bottom", "Custom"]
|
||||
)
|
||||
|
||||
# Interactive elements
|
||||
st.markdown("##### Interactive Elements")
|
||||
use_poll = st.checkbox("Add poll", value=False)
|
||||
use_quiz = st.checkbox("Add quiz", value=False)
|
||||
use_slider = st.checkbox("Add slider", value=False)
|
||||
use_countdown = st.checkbox("Add countdown", value=False)
|
||||
|
||||
with tab3:
|
||||
# Preview and analytics section
|
||||
st.markdown("#### Story Preview")
|
||||
|
||||
# Generate story button
|
||||
if st.button("🚀 Generate Facebook Story", key="generate_story"):
|
||||
with st.spinner("Generating your story..."):
|
||||
if not business_type or not target_audience:
|
||||
st.error("🚫 Please provide the required inputs: Business Type and Target Audience.")
|
||||
else:
|
||||
# Generate the story content
|
||||
prompt = f"""
|
||||
Create a Facebook Story for a {business_type} targeting {target_audience}.
|
||||
|
||||
Story Type: {story_type}
|
||||
Tone: {story_tone}
|
||||
|
||||
Include: {include}
|
||||
Avoid: {avoid}
|
||||
|
||||
Additional requirements:
|
||||
- Use attention-grabbing opening: {use_hook}
|
||||
- Include storytelling elements: {use_story}
|
||||
- Add clear call-to-action: {use_cta}
|
||||
- Include engagement question: {use_question}
|
||||
- Use relevant emojis: {use_emoji}
|
||||
- Add relevant hashtags: {use_hashtags}
|
||||
- Add interactive stickers: {use_stickers}
|
||||
|
||||
Please write a well-structured Facebook Story that:
|
||||
1. Grabs attention in the first frame
|
||||
2. Maintains consistent tone throughout
|
||||
3. Includes engaging content that aligns with the story type
|
||||
4. Ends with a clear call-to-action
|
||||
5. Uses appropriate formatting and emojis
|
||||
6. Includes relevant hashtags if requested
|
||||
7. Incorporates interactive elements if selected
|
||||
"""
|
||||
|
||||
generated_story = llm_text_gen(prompt)
|
||||
|
||||
if generated_story:
|
||||
# Display the generated story
|
||||
st.markdown("### Generated Story")
|
||||
st.markdown(generated_story)
|
||||
|
||||
# Display engagement predictions
|
||||
st.markdown("### 📊 Engagement Predictions")
|
||||
col1, col2, col3 = st.columns(3)
|
||||
with col1:
|
||||
st.metric("Expected Views", "1K - 2K")
|
||||
with col2:
|
||||
st.metric("Expected Engagement", "8-12%")
|
||||
with col3:
|
||||
st.metric("Best Time to Post", "6 PM - 8 PM")
|
||||
|
||||
# Display optimization suggestions
|
||||
st.markdown("### 💡 Optimization Suggestions")
|
||||
st.info("""
|
||||
- Add more interactive elements to increase engagement
|
||||
- Keep text overlays short and readable
|
||||
- Use vibrant colors to stand out
|
||||
- Add music to increase watch time
|
||||
""")
|
||||
|
||||
# Copy button
|
||||
st.button("📋 Copy to Clipboard", key="copy_story")
|
||||
else:
|
||||
st.error("Error: Failed to generate Facebook Story.")
|
||||
@@ -1,347 +0,0 @@
|
||||
# LinkedIn AI Writer
|
||||
|
||||
A comprehensive suite of AI-powered tools for generating professional LinkedIn content.
|
||||
|
||||
## Overview
|
||||
|
||||
LinkedIn AI Writer is a powerful tool designed to help professionals, businesses, and content creators generate high-quality LinkedIn content. It leverages advanced AI models to create engaging posts, articles, carousels, video scripts, and more, all optimized for LinkedIn's platform.
|
||||
|
||||
## Tools Status
|
||||
|
||||
| Tool | Status | Category |
|
||||
|------|--------|----------|
|
||||
| LinkedIn Post Generator | ✅ Active | Content Creation |
|
||||
| LinkedIn Article Generator | ✅ Active | Content Creation |
|
||||
| LinkedIn Carousel Post Generator | ✅ Active | Content Creation |
|
||||
| LinkedIn Video Script Generator | ✅ Active | Content Creation |
|
||||
| LinkedIn Poll Generator | ✅ Active | Content Creation |
|
||||
| LinkedIn Comment Response Generator | ✅ Active | Engagement |
|
||||
| LinkedIn Profile Optimizer | ✅ Active | Profile & Personal Branding |
|
||||
| LinkedIn Company Page Content Generator | ✅ Active | Business & Marketing |
|
||||
| LinkedIn Newsletter Generator | 🔄 Coming Soon | Business & Marketing |
|
||||
| LinkedIn Job Description Generator | 🔄 Coming Soon | Business & Marketing |
|
||||
| LinkedIn Sales Navigator Content Generator | 🔄 Coming Soon | Sales & Networking |
|
||||
| LinkedIn InMail Generator | 🔄 Coming Soon | Sales & Networking |
|
||||
| LinkedIn Learning Course Description Generator | 🔄 Coming Soon | Learning & Education |
|
||||
| LinkedIn Event Description Generator | 🔄 Coming Soon | Learning & Education |
|
||||
| LinkedIn Group Post Generator | 🔄 Coming Soon | Community & Engagement |
|
||||
|
||||
## Features
|
||||
|
||||
### Content Creation Tools
|
||||
|
||||
#### LinkedIn Post Generator
|
||||
- **Status**: Active
|
||||
- **Description**: Create engaging, professional posts that drive engagement and establish thought leadership.
|
||||
- **Features**:
|
||||
- Professional tone customization
|
||||
- Industry-specific terminology
|
||||
- Hashtag optimization
|
||||
- Formatting options
|
||||
- Character count optimization
|
||||
- Call-to-action suggestions
|
||||
- Engagement prediction
|
||||
- Visual content recommendations
|
||||
- Poll creation
|
||||
- Best posting time suggestions
|
||||
- Research-backed content
|
||||
- Reference tracking
|
||||
|
||||
#### LinkedIn Article Generator
|
||||
- **Status**: Active
|
||||
- **Description**: Generate long-form professional articles that showcase expertise and drive traffic.
|
||||
- **Features**:
|
||||
- Topic research and outline generation
|
||||
- SEO optimization for LinkedIn articles
|
||||
- Professional writing style adaptation
|
||||
- Section structuring
|
||||
- Citation and reference formatting
|
||||
- Image placement suggestions
|
||||
- Headline optimization
|
||||
- Meta description generation
|
||||
- Reading time estimation
|
||||
- Internal linking suggestions
|
||||
- Multiple research sources (Metaphor, Google, Tavily)
|
||||
- AI-generated section images
|
||||
|
||||
#### LinkedIn Carousel Post Generator
|
||||
- **Status**: Active
|
||||
- **Description**: Create engaging carousel posts that showcase information in a visually appealing way.
|
||||
- **Features**:
|
||||
- Slide content generation
|
||||
- Visual hierarchy optimization
|
||||
- Story arc development
|
||||
- Call-to-action placement
|
||||
- Brand consistency maintenance
|
||||
- Engagement element integration
|
||||
- Professional design suggestions
|
||||
- Content distribution strategy
|
||||
- Analytics integration
|
||||
- A/B testing variations
|
||||
|
||||
#### LinkedIn Video Script Generator
|
||||
- **Status**: Active
|
||||
- **Description**: Create scripts for LinkedIn videos that drive engagement.
|
||||
- **Features**:
|
||||
- Hook generation
|
||||
- Story structure development
|
||||
- Professional speaking points
|
||||
- Visual cue suggestions
|
||||
- Call-to-action optimization
|
||||
- Engagement prompt integration
|
||||
- Caption generation
|
||||
- Thumbnail text suggestions
|
||||
- Video description optimization
|
||||
- Hashtag strategy
|
||||
|
||||
#### LinkedIn Poll Generator
|
||||
- **Status**: Active
|
||||
- **Description**: Create engaging polls that drive interaction and gather insights.
|
||||
- **Features**:
|
||||
- Question formulation optimization
|
||||
- Option generation based on topic
|
||||
- Industry-specific poll templates
|
||||
- Engagement prediction
|
||||
- Result analysis suggestions
|
||||
- Follow-up content recommendations
|
||||
- Trending topic integration
|
||||
- Professional tone maintenance
|
||||
- Data visualization suggestions
|
||||
- Poll scheduling optimization
|
||||
|
||||
### Engagement Tools
|
||||
|
||||
#### LinkedIn Comment Response Generator
|
||||
- **Status**: Active
|
||||
- **Description**: Generate professional and engaging responses to LinkedIn comments with AI-powered analysis and optimization.
|
||||
- **Features**:
|
||||
- Comment analysis and categorization
|
||||
- Multiple response types (general, disagreement, value-add)
|
||||
- Brand voice customization
|
||||
- Engagement goal targeting
|
||||
- Resource suggestion generation
|
||||
- Follow-up question generation
|
||||
- Tone optimization
|
||||
- Response strategy recommendations
|
||||
- Context-aware responses
|
||||
- Professional formatting
|
||||
|
||||
### Profile & Personal Branding Tools
|
||||
|
||||
#### LinkedIn Profile Optimizer
|
||||
- **Status**: Active
|
||||
- **Description**: Enhance LinkedIn profiles to improve visibility and professional appeal.
|
||||
- **Features**:
|
||||
- Headline optimization
|
||||
- About section generation
|
||||
- Experience description enhancement
|
||||
- Skills recommendation
|
||||
- Project highlight creation
|
||||
- Endorsement request generation
|
||||
- Profile strength analysis
|
||||
- Keyword optimization
|
||||
- Professional summary generation
|
||||
- Custom URL suggestions
|
||||
|
||||
### Business & Marketing Tools
|
||||
|
||||
#### LinkedIn Company Page Content Generator
|
||||
- **Status**: Active
|
||||
- **Description**: Create content for company pages that builds brand awareness and engagement.
|
||||
- **Features**:
|
||||
- Company profile optimization
|
||||
- Company culture post generation
|
||||
- Product/service announcement templates
|
||||
- Employee spotlight content
|
||||
- Company milestone celebrations
|
||||
- Industry insights sharing
|
||||
- Event promotion content
|
||||
- Job posting templates
|
||||
- Company news updates
|
||||
- Brand voice consistency
|
||||
- Engagement metrics optimization
|
||||
|
||||
#### LinkedIn Newsletter Generator
|
||||
- **Status**: Coming Soon
|
||||
- **Description**: Create professional newsletters that establish thought leadership and drive engagement.
|
||||
- **Features**:
|
||||
- Newsletter structure templates
|
||||
- Topic clustering and organization
|
||||
- Professional introduction and conclusion
|
||||
- Industry trend analysis integration
|
||||
- Expert quote suggestions
|
||||
- Visual content recommendations
|
||||
- Call-to-action optimization
|
||||
- Subscriber engagement prompts
|
||||
- Consistency maintenance
|
||||
- Analytics integration suggestions
|
||||
|
||||
#### LinkedIn Job Description Generator
|
||||
- **Status**: Coming Soon
|
||||
- **Description**: Create compelling job descriptions that attract qualified candidates.
|
||||
- **Features**:
|
||||
- Role-specific templates
|
||||
- Skills and qualifications optimization
|
||||
- Company culture integration
|
||||
- Benefits and perks highlighting
|
||||
- Inclusive language checker
|
||||
- Keyword optimization
|
||||
- Application process clarity
|
||||
- Remote/hybrid work policy integration
|
||||
- Diversity and inclusion statements
|
||||
- A/B testing variations
|
||||
|
||||
### Sales & Networking Tools
|
||||
|
||||
#### LinkedIn Sales Navigator Content Generator
|
||||
- **Status**: Coming Soon
|
||||
- **Description**: Create personalized outreach content for sales professionals.
|
||||
- **Features**:
|
||||
- Prospect research integration
|
||||
- Industry-specific messaging
|
||||
- Personalization tokens
|
||||
- Connection request templates
|
||||
- Follow-up message sequences
|
||||
- Value proposition highlighting
|
||||
- Objection handling responses
|
||||
- Meeting request templates
|
||||
- Industry pain point addressing
|
||||
- ROI demonstration content
|
||||
|
||||
#### LinkedIn InMail Generator
|
||||
- **Status**: Coming Soon
|
||||
- **Description**: Create personalized and effective InMail messages.
|
||||
- **Features**:
|
||||
- Prospect research integration
|
||||
- Personalization token usage
|
||||
- Value proposition highlighting
|
||||
- Call-to-action optimization
|
||||
- Follow-up sequence generation
|
||||
- Objection handling preparation
|
||||
- Industry-specific messaging
|
||||
- A/B testing variations
|
||||
- Compliance checking
|
||||
- Engagement tracking suggestions
|
||||
|
||||
### Learning & Education Tools
|
||||
|
||||
#### LinkedIn Learning Course Description Generator
|
||||
- **Status**: Coming Soon
|
||||
- **Description**: Create compelling descriptions for LinkedIn Learning courses.
|
||||
- **Features**:
|
||||
- Course objective optimization
|
||||
- Learning outcome generation
|
||||
- Prerequisite suggestions
|
||||
- Target audience definition
|
||||
- Skill tag recommendations
|
||||
- Course structure outline
|
||||
- Engagement element suggestions
|
||||
- Completion certificate highlighting
|
||||
- Industry relevance emphasis
|
||||
- Career path integration
|
||||
|
||||
#### LinkedIn Event Description Generator
|
||||
- **Status**: Coming Soon
|
||||
- **Description**: Create compelling event descriptions that drive attendance and engagement.
|
||||
- **Features**:
|
||||
- Event objective highlighting
|
||||
- Speaker bio generation
|
||||
- Agenda formatting
|
||||
- Registration incentive suggestions
|
||||
- Networking opportunity emphasis
|
||||
- Industry relevance integration
|
||||
- Visual content recommendations
|
||||
- Engagement element suggestions
|
||||
- Post-event follow-up content
|
||||
- Attendance tracking integration
|
||||
|
||||
### Community & Engagement Tools
|
||||
|
||||
#### LinkedIn Group Post Generator
|
||||
- **Status**: Coming Soon
|
||||
- **Description**: Create content specifically optimized for LinkedIn Groups.
|
||||
- **Features**:
|
||||
- Group-specific content adaptation
|
||||
- Discussion prompt generation
|
||||
- Community guideline compliance
|
||||
- Engagement optimization
|
||||
- Moderation suggestion
|
||||
- Topic relevance checking
|
||||
- Member value highlighting
|
||||
- Cross-promotion opportunities
|
||||
- Group culture adaptation
|
||||
- Content scheduling
|
||||
|
||||
## Current Status
|
||||
|
||||
The LinkedIn AI Writer currently has the following tools fully implemented and active:
|
||||
|
||||
1. LinkedIn Post Generator
|
||||
2. LinkedIn Article Generator
|
||||
3. LinkedIn Carousel Post Generator
|
||||
4. LinkedIn Video Script Generator
|
||||
5. LinkedIn Comment Response Generator
|
||||
6. LinkedIn Profile Optimizer
|
||||
7. LinkedIn Poll Generator
|
||||
8. LinkedIn Company Page Content Generator
|
||||
|
||||
The remaining tools are marked as "Coming Soon" and will be implemented in future iterations.
|
||||
|
||||
## Future Development
|
||||
|
||||
### LinkedIn API Integration
|
||||
|
||||
To provide more personalized and effective content, future development will include integration with the LinkedIn API. This will allow:
|
||||
|
||||
- Access to user profile data for personalized content
|
||||
- Direct posting to LinkedIn
|
||||
- Analytics integration for content performance tracking
|
||||
- Engagement metrics for content optimization
|
||||
- Audience insights for targeted content creation
|
||||
|
||||
### Enhanced AI Models
|
||||
|
||||
We plan to enhance the AI models used for content generation to:
|
||||
|
||||
- Better understand LinkedIn's algorithm and best practices
|
||||
- Generate more engaging and platform-specific content
|
||||
- Provide more accurate engagement predictions
|
||||
- Create more personalized content based on user data
|
||||
|
||||
### Additional Features
|
||||
|
||||
Future iterations will include:
|
||||
|
||||
- Content calendar planning and scheduling
|
||||
- Multi-platform content adaptation
|
||||
- Advanced analytics and reporting
|
||||
- Team collaboration features
|
||||
- Content approval workflows
|
||||
- A/B testing capabilities
|
||||
- Custom templates and brand voice settings
|
||||
|
||||
## Getting Started
|
||||
|
||||
To use the LinkedIn AI Writer:
|
||||
|
||||
1. Navigate to the LinkedIn AI Writer dashboard
|
||||
2. Select the tool you want to use
|
||||
3. Fill in the required information
|
||||
4. Generate your content
|
||||
5. Review and edit as needed
|
||||
6. Copy the content to your LinkedIn account
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.8+
|
||||
- Streamlit
|
||||
- OpenAI API key (for GPT models)
|
||||
- Optional: LinkedIn API credentials (for future integration)
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions to the LinkedIn AI Writer project. Please feel free to submit issues, feature requests, or pull requests.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
@@ -1,20 +0,0 @@
|
||||
"""
|
||||
LinkedIn AI Writer Module
|
||||
|
||||
This module provides a comprehensive suite of tools for generating LinkedIn content.
|
||||
"""
|
||||
|
||||
from .linkedin_ai_writer import linkedin_main_menu, LinkedInAIWriter
|
||||
from .modules.post_generator.linkedin_post_generator import linkedin_post_generator_ui, LinkedInPostGenerator
|
||||
from .modules.article_generator.linkedin_article_generator import linkedin_article_generator_ui
|
||||
from .modules.carousel_generator.linkedin_carousel_generator import linkedin_carousel_generator_ui, LinkedInCarouselGenerator
|
||||
|
||||
__all__ = [
|
||||
'linkedin_main_menu',
|
||||
'LinkedInAIWriter',
|
||||
'linkedin_post_generator_ui',
|
||||
'LinkedInPostGenerator',
|
||||
'linkedin_article_generator_ui',
|
||||
'linkedin_carousel_generator_ui',
|
||||
'LinkedInCarouselGenerator'
|
||||
]
|
||||
@@ -1,580 +0,0 @@
|
||||
"""
|
||||
LinkedIn AI Writer
|
||||
|
||||
This module provides a comprehensive suite of tools for generating LinkedIn content.
|
||||
"""
|
||||
|
||||
import time
|
||||
import os
|
||||
import json
|
||||
import requests
|
||||
import streamlit as st
|
||||
import importlib
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Union
|
||||
from loguru import logger
|
||||
|
||||
# Import AI text generation
|
||||
from ...gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
|
||||
# Import web research tools
|
||||
from ...ai_web_researcher.gpt_online_researcher import do_google_serp_search
|
||||
from ...ai_web_researcher.metaphor_basic_neural_web_search import metaphor_search_articles, streamlit_display_metaphor_results
|
||||
from ...ai_web_researcher.tavily_ai_search import do_tavily_ai_search, streamlit_display_results
|
||||
|
||||
# Import LinkedIn content generators
|
||||
from .modules.post_generator.linkedin_post_generator import linkedin_post_generator_ui
|
||||
from .modules.article_generator.linkedin_article_generator import linkedin_article_generator_ui
|
||||
from .modules.carousel_generator.linkedin_carousel_generator import linkedin_carousel_generator_ui
|
||||
from .modules.video_script_generator.linkedin_video_script_generator import linkedin_video_script_generator_ui
|
||||
from .modules.comment_response_generator.linkedin_comment_response_generator_ui import linkedin_comment_response_generator_ui
|
||||
from .modules.profile_optimizer.linkedin_profile_optimizer_ui import linkedin_profile_optimizer_ui
|
||||
from .modules.poll_generator import linkedin_poll_generator_ui
|
||||
from .modules.company_page_generator import linkedin_company_page_generator_ui
|
||||
|
||||
# Import image generation
|
||||
from ...gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
|
||||
|
||||
# Create a wrapper for the async profile optimizer UI
|
||||
def linkedin_profile_optimizer_ui_wrapper():
|
||||
"""Wrapper function to call the async LinkedIn Profile Optimizer UI."""
|
||||
import asyncio
|
||||
asyncio.run(linkedin_profile_optimizer_ui())
|
||||
|
||||
# Create a wrapper for the async company page generator UI
|
||||
def linkedin_company_page_generator_ui_wrapper():
|
||||
"""Wrapper function to call the async LinkedIn Company Page Generator UI."""
|
||||
import asyncio
|
||||
asyncio.run(linkedin_company_page_generator_ui())
|
||||
|
||||
def linkedin_main_menu():
|
||||
"""Main function for the LinkedIn AI Writer."""
|
||||
|
||||
# Initialize session state for selected tool if it doesn't exist
|
||||
if "selected_tool" not in st.session_state:
|
||||
st.session_state.selected_tool = None
|
||||
|
||||
# Define the LinkedIn tools with their details
|
||||
linkedin_tools = [
|
||||
# Content Creation Tools
|
||||
{
|
||||
"name": "LinkedIn Post Generator",
|
||||
"icon": "📝",
|
||||
"description": "Create engaging, professional posts that drive engagement and establish thought leadership.",
|
||||
"color": "#0A66C2", # LinkedIn blue
|
||||
"category": "Content Creation",
|
||||
"function": linkedin_post_generator_ui,
|
||||
"status": "active",
|
||||
"features": [
|
||||
"Professional tone customization",
|
||||
"Industry-specific terminology",
|
||||
"Hashtag optimization",
|
||||
"Formatting options",
|
||||
"Character count optimization",
|
||||
"Call-to-action suggestions",
|
||||
"Engagement prediction",
|
||||
"Visual content recommendations",
|
||||
"Poll creation",
|
||||
"Best posting time suggestions",
|
||||
"Research-backed content",
|
||||
"Reference tracking"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn Article Generator",
|
||||
"icon": "📄",
|
||||
"description": "Generate long-form professional articles that showcase expertise and drive traffic.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Content Creation",
|
||||
"function": linkedin_article_generator_ui,
|
||||
"status": "active",
|
||||
"features": [
|
||||
"Topic research and outline generation",
|
||||
"SEO optimization for LinkedIn articles",
|
||||
"Professional writing style adaptation",
|
||||
"Section structuring",
|
||||
"Citation and reference formatting",
|
||||
"Image placement suggestions",
|
||||
"Headline optimization",
|
||||
"Meta description generation",
|
||||
"Reading time estimation",
|
||||
"Internal linking suggestions",
|
||||
"Multiple research sources (Metaphor, Google, Tavily)",
|
||||
"AI-generated section images"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn Carousel Post Generator",
|
||||
"icon": "🔄",
|
||||
"description": "Create engaging carousel posts that showcase information in a visually appealing way.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Content Creation",
|
||||
"function": linkedin_carousel_generator_ui,
|
||||
"status": "active",
|
||||
"features": [
|
||||
"Slide content generation",
|
||||
"Visual hierarchy optimization",
|
||||
"Story arc development",
|
||||
"Call-to-action placement",
|
||||
"Brand consistency maintenance",
|
||||
"Engagement element integration",
|
||||
"Professional design suggestions",
|
||||
"Content distribution strategy",
|
||||
"Analytics integration",
|
||||
"A/B testing variations"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn Video Script Generator",
|
||||
"icon": "🎥",
|
||||
"description": "Create scripts for LinkedIn videos that drive engagement.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Content Creation",
|
||||
"function": linkedin_video_script_generator_ui,
|
||||
"status": "active",
|
||||
"features": [
|
||||
"Hook generation",
|
||||
"Story structure development",
|
||||
"Professional speaking points",
|
||||
"Visual cue suggestions",
|
||||
"Call-to-action optimization",
|
||||
"Engagement prompt integration",
|
||||
"Caption generation",
|
||||
"Thumbnail text suggestions",
|
||||
"Video description optimization",
|
||||
"Hashtag strategy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn Comment Response Generator",
|
||||
"icon": "💬",
|
||||
"description": "Generate professional and engaging responses to LinkedIn comments with AI-powered analysis and optimization.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Engagement",
|
||||
"function": linkedin_comment_response_generator_ui,
|
||||
"status": "active",
|
||||
"features": [
|
||||
"Comment analysis and categorization",
|
||||
"Multiple response types (general, disagreement, value-add)",
|
||||
"Brand voice customization",
|
||||
"Engagement goal targeting",
|
||||
"Resource suggestion generation",
|
||||
"Follow-up question generation",
|
||||
"Tone optimization",
|
||||
"Response strategy recommendations",
|
||||
"Context-aware responses",
|
||||
"Professional formatting"
|
||||
]
|
||||
},
|
||||
|
||||
# Profile & Personal Branding Tools
|
||||
{
|
||||
"name": "LinkedIn Profile Optimizer",
|
||||
"icon": "👤",
|
||||
"description": "Enhance LinkedIn profiles to improve visibility and professional appeal.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Profile & Personal Branding",
|
||||
"function": linkedin_profile_optimizer_ui_wrapper,
|
||||
"status": "active",
|
||||
"features": [
|
||||
"Headline optimization",
|
||||
"About section generation",
|
||||
"Experience description enhancement",
|
||||
"Skills recommendation",
|
||||
"Project highlight creation",
|
||||
"Endorsement request generation",
|
||||
"Profile strength analysis",
|
||||
"Keyword optimization",
|
||||
"Professional summary generation",
|
||||
"Custom URL suggestions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn Poll Generator",
|
||||
"icon": "📊",
|
||||
"description": "Create engaging polls that drive interaction and gather insights.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Profile & Personal Branding",
|
||||
"function": linkedin_poll_generator_ui,
|
||||
"status": "active",
|
||||
"features": [
|
||||
"Question formulation optimization",
|
||||
"Option generation based on topic",
|
||||
"Industry-specific poll templates",
|
||||
"Engagement prediction",
|
||||
"Result analysis suggestions",
|
||||
"Follow-up content recommendations",
|
||||
"Trending topic integration",
|
||||
"Professional tone maintenance",
|
||||
"Data visualization suggestions",
|
||||
"Poll scheduling optimization"
|
||||
]
|
||||
},
|
||||
|
||||
# Business & Marketing Tools
|
||||
{
|
||||
"name": "LinkedIn Company Page Content Generator",
|
||||
"icon": "🏢",
|
||||
"description": "Create content for company pages that builds brand awareness and engagement.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Business & Marketing",
|
||||
"function": linkedin_company_page_generator_ui_wrapper,
|
||||
"status": "active",
|
||||
"features": [
|
||||
"Company culture post generation",
|
||||
"Product/service announcement templates",
|
||||
"Employee spotlight content",
|
||||
"Company milestone celebrations",
|
||||
"Industry insights sharing",
|
||||
"Event promotion content",
|
||||
"Job posting templates",
|
||||
"Company news updates",
|
||||
"Brand voice consistency",
|
||||
"Engagement metrics optimization"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn Newsletter Generator",
|
||||
"icon": "📰",
|
||||
"description": "Create professional newsletters that establish thought leadership and drive engagement.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Business & Marketing",
|
||||
"function": None,
|
||||
"status": "coming_soon",
|
||||
"features": [
|
||||
"Newsletter structure templates",
|
||||
"Topic clustering and organization",
|
||||
"Professional introduction and conclusion",
|
||||
"Industry trend analysis integration",
|
||||
"Expert quote suggestions",
|
||||
"Visual content recommendations",
|
||||
"Call-to-action optimization",
|
||||
"Subscriber engagement prompts",
|
||||
"Consistency maintenance",
|
||||
"Analytics integration suggestions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn Job Description Generator",
|
||||
"icon": "💼",
|
||||
"description": "Create compelling job descriptions that attract qualified candidates.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Business & Marketing",
|
||||
"function": None,
|
||||
"status": "coming_soon",
|
||||
"features": [
|
||||
"Role-specific templates",
|
||||
"Skills and qualifications optimization",
|
||||
"Company culture integration",
|
||||
"Benefits and perks highlighting",
|
||||
"Inclusive language checker",
|
||||
"Keyword optimization",
|
||||
"Application process clarity",
|
||||
"Remote/hybrid work policy integration",
|
||||
"Diversity and inclusion statements",
|
||||
"A/B testing variations"
|
||||
]
|
||||
},
|
||||
|
||||
# Sales & Networking Tools
|
||||
{
|
||||
"name": "LinkedIn Sales Navigator Content Generator",
|
||||
"icon": "💰",
|
||||
"description": "Create personalized outreach content for sales professionals.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Sales & Networking",
|
||||
"function": None,
|
||||
"status": "coming_soon",
|
||||
"features": [
|
||||
"Prospect research integration",
|
||||
"Industry-specific messaging",
|
||||
"Personalization tokens",
|
||||
"Connection request templates",
|
||||
"Follow-up message sequences",
|
||||
"Value proposition highlighting",
|
||||
"Objection handling responses",
|
||||
"Meeting request templates",
|
||||
"Industry pain point addressing",
|
||||
"ROI demonstration content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn InMail Generator",
|
||||
"icon": "✉️",
|
||||
"description": "Create personalized and effective InMail messages.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Sales & Networking",
|
||||
"function": None,
|
||||
"status": "coming_soon",
|
||||
"features": [
|
||||
"Prospect research integration",
|
||||
"Personalization token usage",
|
||||
"Value proposition highlighting",
|
||||
"Call-to-action optimization",
|
||||
"Follow-up sequence generation",
|
||||
"Objection handling preparation",
|
||||
"Industry-specific messaging",
|
||||
"A/B testing variations",
|
||||
"Compliance checking",
|
||||
"Engagement tracking suggestions"
|
||||
]
|
||||
},
|
||||
|
||||
# Learning & Education Tools
|
||||
{
|
||||
"name": "LinkedIn Learning Course Description Generator",
|
||||
"icon": "📚",
|
||||
"description": "Create compelling descriptions for LinkedIn Learning courses.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Learning & Education",
|
||||
"function": None,
|
||||
"status": "coming_soon",
|
||||
"features": [
|
||||
"Course objective optimization",
|
||||
"Learning outcome generation",
|
||||
"Prerequisite suggestions",
|
||||
"Target audience definition",
|
||||
"Skill tag recommendations",
|
||||
"Course structure outline",
|
||||
"Engagement element suggestions",
|
||||
"Completion certificate highlighting",
|
||||
"Industry relevance emphasis",
|
||||
"Career path integration"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn Event Description Generator",
|
||||
"icon": "📅",
|
||||
"description": "Create compelling event descriptions that drive attendance and engagement.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Learning & Education",
|
||||
"function": None,
|
||||
"status": "coming_soon",
|
||||
"features": [
|
||||
"Event objective highlighting",
|
||||
"Speaker bio generation",
|
||||
"Agenda formatting",
|
||||
"Registration incentive suggestions",
|
||||
"Networking opportunity emphasis",
|
||||
"Industry relevance integration",
|
||||
"Visual content recommendations",
|
||||
"Engagement element suggestions",
|
||||
"Post-event follow-up content",
|
||||
"Attendance tracking integration"
|
||||
]
|
||||
},
|
||||
|
||||
# Community & Engagement Tools
|
||||
{
|
||||
"name": "LinkedIn Group Post Generator",
|
||||
"icon": "👥",
|
||||
"description": "Create content specifically optimized for LinkedIn Groups.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Community & Engagement",
|
||||
"function": None,
|
||||
"status": "coming_soon",
|
||||
"features": [
|
||||
"Group-specific content adaptation",
|
||||
"Discussion prompt generation",
|
||||
"Community guideline compliance",
|
||||
"Engagement optimization",
|
||||
"Moderation suggestion",
|
||||
"Topic relevance checking",
|
||||
"Member value highlighting",
|
||||
"Cross-promotion opportunities",
|
||||
"Group culture adaptation",
|
||||
"Content scheduling"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LinkedIn Comment Response Generator",
|
||||
"icon": "💬",
|
||||
"description": "Create professional and engaging responses to comments on LinkedIn posts.",
|
||||
"color": "#0A66C2",
|
||||
"category": "Community & Engagement",
|
||||
"function": None,
|
||||
"status": "coming_soon",
|
||||
"features": [
|
||||
"Tone adaptation based on comment",
|
||||
"Professional disagreement handling",
|
||||
"Question answering optimization",
|
||||
"Engagement continuation prompts",
|
||||
"Value-add response generation",
|
||||
"Community building suggestions",
|
||||
"Moderation guidance",
|
||||
"Follow-up question generation",
|
||||
"Resource sharing suggestions",
|
||||
"Relationship building strategies"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
# Create a container for the dashboard
|
||||
dashboard_container = st.container()
|
||||
|
||||
# Create a container for the tool input section
|
||||
tool_container = st.container()
|
||||
|
||||
# If a tool is selected, show its input section
|
||||
if st.session_state.selected_tool is not None:
|
||||
with tool_container:
|
||||
# Add a back button at the top
|
||||
if st.button("← Back to Dashboard", key="back_to_dashboard"):
|
||||
st.session_state.selected_tool = None
|
||||
st.rerun()
|
||||
|
||||
# Display the tool header with card layout
|
||||
st.markdown(f"""
|
||||
<div style='
|
||||
background: linear-gradient(145deg, #ffffff 0%, #f0f7ff 50%, #e6f0ff 100%);
|
||||
padding: 2.5rem;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 10px 25px rgba(10, 102, 194, 0.08);
|
||||
margin: 1rem 0 2.5rem 0;
|
||||
border: 1px solid rgba(10, 102, 194, 0.1);
|
||||
'>
|
||||
<div style='
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1.2rem;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
padding: 1rem 1.5rem;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 15px rgba(10, 102, 194, 0.05);
|
||||
'>
|
||||
<div style='
|
||||
font-size: 2.5rem;
|
||||
margin-right: 1rem;
|
||||
color: #0A66C2;
|
||||
'>{st.session_state.selected_tool['icon']}</div>
|
||||
<div>
|
||||
<h1 style='
|
||||
margin: 0;
|
||||
color: #0A66C2;
|
||||
font-size: 2.2rem;
|
||||
font-weight: 600;
|
||||
'>{st.session_state.selected_tool['name']}</h1>
|
||||
<p style='
|
||||
color: #666;
|
||||
margin: 0.5rem 0 0 0;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.5;
|
||||
'>{st.session_state.selected_tool['description']}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Call the tool's function if it exists
|
||||
if st.session_state.selected_tool["function"] is not None:
|
||||
st.session_state.selected_tool["function"]()
|
||||
else:
|
||||
# Display coming soon information
|
||||
st.info(f"**{st.session_state.selected_tool['status'].replace('_', ' ').title()}!**")
|
||||
st.write(st.session_state.selected_tool["description"])
|
||||
|
||||
# Display features
|
||||
st.subheader("Features")
|
||||
for feature in st.session_state.selected_tool["features"]:
|
||||
st.markdown(f"- {feature}")
|
||||
|
||||
# Display placeholder image
|
||||
st.image(f"https://via.placeholder.com/600x300?text={st.session_state.selected_tool['name']}+Coming+Soon", use_container_width=True)
|
||||
else:
|
||||
with dashboard_container:
|
||||
# Display the dashboard
|
||||
# Header
|
||||
st.markdown("""
|
||||
<div style='background-color: #f0f2f6; padding: 10px; border-radius: 5px; margin-bottom: 10px;'>
|
||||
<h1 style='color: #0A66C2; text-align: center;'>💼 LinkedIn AI Writer</h1>
|
||||
<p style='text-align: center;'>Generate professional LinkedIn content with ALwrity's AI-powered tools</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Group tools by category
|
||||
categories = {}
|
||||
for tool in linkedin_tools:
|
||||
category = tool["category"]
|
||||
if category not in categories:
|
||||
categories[category] = []
|
||||
categories[category].append(tool)
|
||||
|
||||
# Display tools by category
|
||||
for category, tools in categories.items():
|
||||
st.markdown(f"## {category}")
|
||||
|
||||
# Create a 3-column layout for the tool cards
|
||||
cols = st.columns(3)
|
||||
|
||||
# Display the tool cards
|
||||
for i, tool in enumerate(tools):
|
||||
# Determine which column to use
|
||||
col = cols[i % 3]
|
||||
|
||||
with col:
|
||||
# Create a card for each tool
|
||||
status_badge = ""
|
||||
if tool["status"] == "coming_soon":
|
||||
status_badge = "<span style='background-color: #FFA500; color: white; padding: 2px 8px; border-radius: 10px; font-size: 0.8em;'>Coming Soon</span>"
|
||||
elif tool["status"] == "future":
|
||||
status_badge = "<span style='background-color: #808080; color: white; padding: 2px 8px; border-radius: 10px; font-size: 0.8em;'>Future</span>"
|
||||
elif tool["status"] == "active":
|
||||
status_badge = "<span style='background-color: #4CAF50; color: white; padding: 2px 8px; border-radius: 10px; font-size: 0.8em;'>Active</span>"
|
||||
|
||||
st.markdown(f"""
|
||||
<div style='background-color: {tool["color"]}; padding: 20px; border-radius: 10px; margin-bottom: 20px; color: white;'>
|
||||
<h2 style='color: white;'>{tool["icon"]} {tool["name"]} {status_badge}</h2>
|
||||
<p>{tool["description"]}</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Add a button to access the tool
|
||||
if st.button(f"Use {tool['name']}", key=f"btn_{tool['category']}_{tool['name']}"):
|
||||
# Store the selected tool in session state
|
||||
st.session_state.selected_tool = tool
|
||||
st.rerun()
|
||||
|
||||
|
||||
class LinkedInAIWriter:
|
||||
"""
|
||||
AI-powered content generator for LinkedIn marketing and communication.
|
||||
|
||||
This class provides various tools for generating LinkedIn content including:
|
||||
- Posts and articles
|
||||
- Profile optimization
|
||||
- Company page content
|
||||
- Sales and networking content
|
||||
- Learning and education content
|
||||
- Community and engagement content
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the LinkedIn AI Writer."""
|
||||
pass
|
||||
|
||||
# Methods will be implemented in future iterations
|
||||
# Each method will correspond to a specific LinkedIn content generation tool
|
||||
|
||||
|
||||
# List of available tools
|
||||
AVAILABLE_TOOLS = [
|
||||
'Post Generator',
|
||||
'Article Generator',
|
||||
'Carousel Post Generator',
|
||||
'Video Script Generator',
|
||||
'Profile Optimizer',
|
||||
'Poll Generator',
|
||||
'Company Page Content Generator',
|
||||
'Newsletter Generator',
|
||||
'Job Description Generator',
|
||||
'Sales Navigator Content Generator',
|
||||
'InMail Generator',
|
||||
'Learning Course Description Generator',
|
||||
'Event Description Generator',
|
||||
'Group Post Generator',
|
||||
'Comment Response Generator'
|
||||
]
|
||||
|
||||
if __name__ == "__main__":
|
||||
linkedin_main_menu()
|
||||
@@ -1,17 +0,0 @@
|
||||
"""
|
||||
LinkedIn AI Writer Modules
|
||||
|
||||
This package contains various modules for generating different types of LinkedIn content.
|
||||
"""
|
||||
|
||||
from .post_generator.linkedin_post_generator import linkedin_post_generator_ui, LinkedInPostGenerator
|
||||
from .article_generator.linkedin_article_generator import linkedin_article_generator_ui
|
||||
from .carousel_generator.linkedin_carousel_generator import linkedin_carousel_generator_ui, LinkedInCarouselGenerator
|
||||
|
||||
__all__ = [
|
||||
'linkedin_post_generator_ui',
|
||||
'LinkedInPostGenerator',
|
||||
'linkedin_article_generator_ui',
|
||||
'linkedin_carousel_generator_ui',
|
||||
'LinkedInCarouselGenerator'
|
||||
]
|
||||
@@ -1,253 +0,0 @@
|
||||
# LinkedIn Article Generator 📝
|
||||
|
||||
A powerful AI-powered tool designed specifically for LinkedIn content creators to generate professional, research-backed articles that engage and provide value to your professional network.
|
||||
|
||||
## 🌟 Key Features
|
||||
|
||||
### Content Generation
|
||||
- **AI-Powered Research**: Integrates with multiple search engines (Metaphor, Google, Tavily) for up-to-date, accurate content
|
||||
- **Professional Writing**: Generates industry-specific content with expert insights and statistics
|
||||
- **Topic-Focused Content**: Ensures all content stays relevant to your chosen topic without AI explanations or meta-commentary
|
||||
- **SEO Optimization**: Built-in SEO tools for maximum visibility
|
||||
- **Image Generation**: AI-powered visuals for article header and sections
|
||||
|
||||
### Research Integration
|
||||
- **Multi-Source Research**: Choose from Metaphor AI, Google Search, or Tavily AI
|
||||
- **Real-Time Data**: Access current industry trends and statistics
|
||||
- **Expert Insights**: Incorporate professional perspectives and quotes
|
||||
- **Fact-Checking**: Web-researched context to prevent AI hallucinations
|
||||
|
||||
### Visual Enhancement
|
||||
- **Topic Images**: Generate professional header images
|
||||
- **Section Visuals**: Create relevant images for each section
|
||||
- **Image Refinement**: Edit and regenerate images until perfect
|
||||
- **Custom Prompts**: Write your own image generation prompts
|
||||
|
||||
## 🚀 Getting Started
|
||||
|
||||
### 1. Article Generation Process
|
||||
|
||||
#### Step 1: Topic Input
|
||||
- Enter your article topic
|
||||
- Select your industry
|
||||
- Choose writing tone:
|
||||
- Professional
|
||||
- Analytical
|
||||
- Conversational
|
||||
- Technical
|
||||
- Thought Leadership
|
||||
|
||||
#### Step 2: Research Selection
|
||||
Choose your preferred research source:
|
||||
- 🔍 Metaphor AI: For comprehensive industry insights
|
||||
- 🌐 Google Search: For broad topic coverage
|
||||
- 🤖 Tavily AI: For focused, AI-curated research
|
||||
|
||||
#### Step 3: Content Generation
|
||||
The tool will:
|
||||
1. Research your topic thoroughly
|
||||
2. Create a detailed outline
|
||||
3. Generate comprehensive content
|
||||
4. Add relevant statistics and quotes
|
||||
5. Generate professional images
|
||||
6. Optimize for SEO
|
||||
|
||||
### 2. Article Preview and Editing
|
||||
|
||||
#### Content Tab
|
||||
- View the complete article
|
||||
- Edit content directly
|
||||
- Download in HTML format
|
||||
- Copy to clipboard
|
||||
|
||||
#### Images & Visuals Tab
|
||||
- Preview and regenerate topic image
|
||||
- Edit image prompts
|
||||
- Generate section-specific images
|
||||
- Choose from alternative image suggestions
|
||||
|
||||
#### SEO & Metadata Tab
|
||||
- Review focus keywords
|
||||
- Edit meta descriptions
|
||||
- Optimize article tags
|
||||
- Customize social sharing text
|
||||
|
||||
## 💡 Best Practices
|
||||
|
||||
### 1. Topic Selection
|
||||
- Choose specific, industry-relevant topics
|
||||
- Focus on your area of expertise
|
||||
- Consider current trends in your field
|
||||
- Target your professional audience's needs
|
||||
|
||||
### 2. Content Structure
|
||||
- Strong, attention-grabbing headlines
|
||||
- Professional introduction
|
||||
- Well-organized sections
|
||||
- Clear takeaways
|
||||
- Compelling call-to-action
|
||||
|
||||
### 3. Visual Strategy
|
||||
- Professional, topic-relevant images
|
||||
- Consistent visual style
|
||||
- High-quality graphics
|
||||
- Mobile-friendly visuals
|
||||
|
||||
## 🎯 Content Types
|
||||
|
||||
### Industry Insights
|
||||
- Market analysis
|
||||
- Trend reports
|
||||
- Expert perspectives
|
||||
- Case studies
|
||||
|
||||
### How-to Articles
|
||||
- Step-by-step guides
|
||||
- Best practices
|
||||
- Implementation strategies
|
||||
- Professional tips
|
||||
|
||||
### Thought Leadership
|
||||
- Industry predictions
|
||||
- Expert opinions
|
||||
- Strategy discussions
|
||||
- Innovation insights
|
||||
|
||||
## 📊 SEO Optimization
|
||||
|
||||
### Automatic Optimization
|
||||
- Focus keyword selection
|
||||
- Secondary keywords
|
||||
- Meta descriptions
|
||||
- Article tags
|
||||
- Social sharing text
|
||||
|
||||
### Content Enhancement
|
||||
- Keyword placement
|
||||
- Header optimization
|
||||
- Link suggestions
|
||||
- Readability improvements
|
||||
|
||||
## 🛠️ Advanced Features
|
||||
|
||||
### Research Integration
|
||||
- Multiple search engines
|
||||
- Real-time data gathering
|
||||
- Expert quote integration
|
||||
- Statistical data inclusion
|
||||
|
||||
### Image Generation
|
||||
- Custom prompt creation
|
||||
- Style customization
|
||||
- Alternative suggestions
|
||||
- Section-specific visuals
|
||||
|
||||
### Content Export
|
||||
- HTML format
|
||||
- Clipboard copy
|
||||
- Social media optimized
|
||||
- SEO-ready structure
|
||||
|
||||
## 📱 Mobile Optimization
|
||||
|
||||
- Responsive images
|
||||
- Readable text
|
||||
- Optimized layout
|
||||
- Cross-device compatibility
|
||||
|
||||
## 💪 Success Tips
|
||||
|
||||
### 1. Content Strategy
|
||||
- Regular posting schedule
|
||||
- Consistent topic focus
|
||||
- Industry relevance
|
||||
- Audience engagement
|
||||
|
||||
### 2. Visual Impact
|
||||
- Professional imagery
|
||||
- Brand consistency
|
||||
- Visual storytelling
|
||||
- Quality graphics
|
||||
|
||||
### 3. Engagement
|
||||
- Compelling headlines
|
||||
- Interactive elements
|
||||
- Clear call-to-action
|
||||
- Professional tone
|
||||
|
||||
## 🔍 Technical Details
|
||||
|
||||
### System Requirements
|
||||
- Modern web browser
|
||||
- Internet connection
|
||||
- API access (if using custom keys)
|
||||
|
||||
### Performance
|
||||
- Fast generation times
|
||||
- Real-time preview
|
||||
- Instant updates
|
||||
- Smooth editing
|
||||
|
||||
## 📈 Best Use Cases
|
||||
|
||||
1. **Industry Analysis**
|
||||
- Market trends
|
||||
- Technology updates
|
||||
- Business insights
|
||||
- Professional perspectives
|
||||
|
||||
2. **Professional Guides**
|
||||
- Best practices
|
||||
- Implementation strategies
|
||||
- Career development
|
||||
- Skill enhancement
|
||||
|
||||
3. **Thought Leadership**
|
||||
- Industry predictions
|
||||
- Expert opinions
|
||||
- Innovation insights
|
||||
- Strategic analysis
|
||||
|
||||
## 🎨 Design Guidelines
|
||||
|
||||
1. **Visual Consistency**
|
||||
- Brand colors
|
||||
- Professional fonts
|
||||
- Clean layouts
|
||||
- Quality images
|
||||
|
||||
2. **Content Format**
|
||||
- Clear headers
|
||||
- Organized sections
|
||||
- Professional tone
|
||||
- Engaging structure
|
||||
|
||||
3. **Mobile Design**
|
||||
- Responsive layout
|
||||
- Readable text
|
||||
- Optimized images
|
||||
- Cross-device testing
|
||||
|
||||
## 🔄 Workflow Integration
|
||||
|
||||
1. **Content Planning**
|
||||
- Topic research
|
||||
- Outline creation
|
||||
- Content generation
|
||||
- Visual design
|
||||
|
||||
2. **Quality Control**
|
||||
- Content review
|
||||
- Image refinement
|
||||
- SEO verification
|
||||
- Final checks
|
||||
|
||||
3. **Publishing**
|
||||
- Format selection
|
||||
- Preview verification
|
||||
- LinkedIn optimization
|
||||
- Engagement tracking
|
||||
|
||||
---
|
||||
|
||||
Start creating professional LinkedIn articles that engage your network and establish your expertise! 🚀
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,281 +0,0 @@
|
||||
# LinkedIn Carousel Generator 🎯
|
||||
|
||||
An AI-powered tool designed specifically for LinkedIn content creators to generate engaging, visually stunning carousel posts that drive engagement and showcase expertise.
|
||||
|
||||
## ✨ Key Features
|
||||
|
||||
### Content Creation
|
||||
- **AI-Powered Research**: Multi-source research integration (Metaphor, Google, Tavily)
|
||||
- **Dynamic Slide Generation**: Auto-generation of 3-10 cohesive slides
|
||||
- **Smart Content Structure**: Optimized flow from hook to call-to-action
|
||||
- **Visual Content**: AI-generated professional visuals for each slide
|
||||
- **Content Types**: How-to Guides, Lists, Stories, Case Studies, Tips & Tricks
|
||||
|
||||
### Visual Excellence
|
||||
- **Professional Imagery**: Custom AI-generated visuals per slide
|
||||
- **Brand Consistency**: Cohesive visual style across slides
|
||||
- **Visual Hierarchy**: Optimized layout for maximum impact
|
||||
- **Custom Styling**: Flexible design options for each slide
|
||||
|
||||
### Research Integration
|
||||
- **Triple-Engine Research**:
|
||||
- 🔍 Metaphor AI: Deep industry insights
|
||||
- 🌐 Google Search: Comprehensive coverage
|
||||
- 🤖 Tavily AI: Focused research
|
||||
- **Real-Time Data**: Current trends and statistics
|
||||
- **Expert Insights**: Professional quotes and perspectives
|
||||
|
||||
## 🚀 Getting Started
|
||||
|
||||
### 1. Carousel Creation Process
|
||||
|
||||
#### Initial Setup
|
||||
- Choose your topic
|
||||
- Select your industry
|
||||
- Pick your content style:
|
||||
- Professional
|
||||
- Educational
|
||||
- Conversational
|
||||
- Inspiring
|
||||
- Technical
|
||||
|
||||
#### Content Type Selection
|
||||
Choose from:
|
||||
- How-to Guide: Step-by-step instructions
|
||||
- List: Curated points or tips
|
||||
- Story: Narrative-driven content
|
||||
- Case Study: Real-world examples
|
||||
- Tips & Tricks: Quick, actionable advice
|
||||
|
||||
#### Slide Configuration
|
||||
- Select number of slides (3-10)
|
||||
- Choose research source
|
||||
- Enable/disable features:
|
||||
- Custom visuals
|
||||
- Content optimization
|
||||
- Research integration
|
||||
|
||||
### 2. Carousel Preview and Editing
|
||||
|
||||
#### Slide Navigation
|
||||
- Previous/Next navigation
|
||||
- Slide overview
|
||||
- Individual slide editing
|
||||
- Real-time preview
|
||||
|
||||
#### Content Editing
|
||||
- Edit headings
|
||||
- Modify subheadings
|
||||
- Update main content
|
||||
- Customize visuals
|
||||
- Optimize text
|
||||
|
||||
#### Visual Customization
|
||||
- Edit image prompts
|
||||
- Generate new visuals
|
||||
- Adjust style settings
|
||||
- Preview changes
|
||||
|
||||
## 💡 Best Practices
|
||||
|
||||
### 1. Content Strategy
|
||||
- **First Slide**
|
||||
- Strong hook
|
||||
- Clear value proposition
|
||||
- Attention-grabbing visual
|
||||
- Topic introduction
|
||||
|
||||
- **Middle Slides**
|
||||
- Logical progression
|
||||
- Supporting evidence
|
||||
- Engaging visuals
|
||||
- Clear explanations
|
||||
|
||||
- **Last Slide**
|
||||
- Strong call-to-action
|
||||
- Next steps
|
||||
- Contact information
|
||||
- Engagement prompt
|
||||
|
||||
### 2. Visual Strategy
|
||||
- **Consistency**
|
||||
- Cohesive style
|
||||
- Brand colors
|
||||
- Font hierarchy
|
||||
- Layout patterns
|
||||
|
||||
- **Image Quality**
|
||||
- Professional aesthetics
|
||||
- Clear messaging
|
||||
- Relevant visuals
|
||||
- Brand alignment
|
||||
|
||||
### 3. Content Flow
|
||||
- **Progression**
|
||||
- Logical sequence
|
||||
- Clear transitions
|
||||
- Building complexity
|
||||
- Cohesive narrative
|
||||
|
||||
## 📊 Content Types Guide
|
||||
|
||||
### How-to Guide
|
||||
- Clear steps
|
||||
- Visual instructions
|
||||
- Progress indicators
|
||||
- Action items
|
||||
|
||||
### List Format
|
||||
- Clear numbering
|
||||
- Consistent structure
|
||||
- Visual hierarchy
|
||||
- Easy scanning
|
||||
|
||||
### Story Format
|
||||
- Engaging narrative
|
||||
- Character elements
|
||||
- Visual journey
|
||||
- Emotional connection
|
||||
|
||||
### Case Study
|
||||
- Problem statement
|
||||
- Solution process
|
||||
- Results/outcomes
|
||||
- Key learnings
|
||||
|
||||
### Tips & Tricks
|
||||
- Quick insights
|
||||
- Actionable advice
|
||||
- Visual examples
|
||||
- Implementation guidance
|
||||
|
||||
## 🎨 Design Guidelines
|
||||
|
||||
### Visual Hierarchy
|
||||
- **Headlines**
|
||||
- Clear visibility
|
||||
- Consistent sizing
|
||||
- Impactful fonts
|
||||
- Color contrast
|
||||
|
||||
- **Content Layout**
|
||||
- Balanced design
|
||||
- White space
|
||||
- Reading flow
|
||||
- Visual anchors
|
||||
|
||||
### Brand Elements
|
||||
- **Style Guide**
|
||||
- Color palette
|
||||
- Typography
|
||||
- Logo placement
|
||||
- Visual elements
|
||||
|
||||
## 📱 Optimization
|
||||
|
||||
### Mobile View
|
||||
- Text readability
|
||||
- Image scaling
|
||||
- Touch-friendly
|
||||
- Quick loading
|
||||
|
||||
### Platform Specs
|
||||
- LinkedIn dimensions
|
||||
- File size limits
|
||||
- Format requirements
|
||||
- Quality standards
|
||||
|
||||
## 💪 Engagement Tips
|
||||
|
||||
### 1. Content Hooks
|
||||
- **First Slide**
|
||||
- Compelling question
|
||||
- Bold statement
|
||||
- Surprising fact
|
||||
- Clear benefit
|
||||
|
||||
### 2. Visual Impact
|
||||
- **Each Slide**
|
||||
- Professional quality
|
||||
- Clear message
|
||||
- Brand alignment
|
||||
- Emotional appeal
|
||||
|
||||
### 3. Call-to-Action
|
||||
- **Last Slide**
|
||||
- Clear direction
|
||||
- Value offer
|
||||
- Next steps
|
||||
- Engagement prompt
|
||||
|
||||
## 🛠️ Technical Features
|
||||
|
||||
### Performance
|
||||
- Fast generation
|
||||
- Real-time preview
|
||||
- Smooth editing
|
||||
- Quick exports
|
||||
|
||||
### Export Options
|
||||
- Individual slides
|
||||
- Complete carousel
|
||||
- Various formats
|
||||
- High resolution
|
||||
|
||||
## 📈 Success Tips
|
||||
|
||||
### Content Quality
|
||||
- Research-backed
|
||||
- Professional tone
|
||||
- Clear messaging
|
||||
- Valuable insights
|
||||
|
||||
### Visual Excellence
|
||||
- Professional design
|
||||
- Consistent branding
|
||||
- Quality visuals
|
||||
- Mobile optimization
|
||||
|
||||
### Engagement Focus
|
||||
- Interactive elements
|
||||
- Question prompts
|
||||
- Discussion starters
|
||||
- Clear CTAs
|
||||
|
||||
## 🔍 Quick Tips
|
||||
|
||||
1. **Optimal Length**
|
||||
- 3-5 slides for simple topics
|
||||
- 6-8 slides for detailed guides
|
||||
- 8-10 slides for comprehensive content
|
||||
|
||||
2. **Visual Best Practices**
|
||||
- One main point per slide
|
||||
- Clear, readable text
|
||||
- High-quality images
|
||||
- Consistent branding
|
||||
|
||||
3. **Content Flow**
|
||||
- Hook → Content → CTA
|
||||
- Logical progression
|
||||
- Clear transitions
|
||||
- Strong ending
|
||||
|
||||
4. **Engagement Boosters**
|
||||
- Ask questions
|
||||
- Include statistics
|
||||
- Share insights
|
||||
- Prompt discussion
|
||||
|
||||
---
|
||||
|
||||
Transform your LinkedIn presence with professional, engaging carousel posts! 🚀
|
||||
|
||||
Remember:
|
||||
- Keep each slide focused
|
||||
- Maintain visual consistency
|
||||
- Tell a compelling story
|
||||
- End with clear action steps
|
||||
- Test and optimize regularly
|
||||
|
||||
Start creating stunning LinkedIn carousels that showcase your expertise! 💫
|
||||
@@ -1,10 +0,0 @@
|
||||
"""
|
||||
LinkedIn Carousel Generator Package
|
||||
|
||||
This package provides functionality for generating LinkedIn carousel posts with
|
||||
AI-powered content and visuals.
|
||||
"""
|
||||
|
||||
from .linkedin_carousel_generator import linkedin_carousel_generator_ui, LinkedInCarouselGenerator, CarouselSlide
|
||||
|
||||
__all__ = ['linkedin_carousel_generator_ui', 'LinkedInCarouselGenerator', 'CarouselSlide']
|
||||
@@ -1,469 +0,0 @@
|
||||
"""
|
||||
LinkedIn Carousel Post Generator
|
||||
|
||||
This module provides functionality for generating LinkedIn carousel posts with
|
||||
AI-powered content and visuals.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
from typing import Dict, List, Optional
|
||||
from loguru import logger
|
||||
import json
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from .....gpt_providers.text_generation.gemini_pro_text import gemini_structured_json_response
|
||||
from .....gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
|
||||
from .....ai_web_researcher.gpt_online_researcher import do_google_serp_search
|
||||
from .....ai_web_researcher.metaphor_basic_neural_web_search import metaphor_search_articles
|
||||
from .....ai_web_researcher.tavily_ai_search import do_tavily_ai_search
|
||||
|
||||
|
||||
class CarouselSlide(BaseModel):
|
||||
"""Represents a single slide in the carousel."""
|
||||
index: int
|
||||
heading: str
|
||||
subheading: str
|
||||
content: str
|
||||
image_prompt: str
|
||||
image_path: Optional[str] = None
|
||||
|
||||
|
||||
class CarouselStructure(BaseModel):
|
||||
"""Represents the complete carousel structure."""
|
||||
slides: List[CarouselSlide]
|
||||
|
||||
|
||||
def generate_structured_content(prompt: str, model: str = 'gemini-pro') -> Optional[Dict]:
|
||||
"""Generate structured content using Gemini's structured output feature."""
|
||||
try:
|
||||
# Define the schema for the carousel structure
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"slides": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"index": {"type": "integer"},
|
||||
"heading": {"type": "string"},
|
||||
"subheading": {"type": "string"},
|
||||
"content": {"type": "string"},
|
||||
"image_prompt": {"type": "string"}
|
||||
},
|
||||
"required": ["index", "heading", "subheading", "content", "image_prompt"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["slides"]
|
||||
}
|
||||
|
||||
# Use the new function to generate structured content
|
||||
result = gemini_structured_json_response(prompt, schema)
|
||||
|
||||
# Check if there was an error
|
||||
if "error" in result:
|
||||
logger.error(f"Error generating structured content: {result['error']}")
|
||||
return None
|
||||
|
||||
logger.debug(f"Structured response: {json.dumps(result, indent=2)}")
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating structured content: {e}")
|
||||
logger.exception("Full traceback:")
|
||||
return None
|
||||
|
||||
|
||||
class LinkedInCarouselGenerator:
|
||||
"""
|
||||
Generator for LinkedIn carousel posts with AI-powered content and visuals.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the carousel generator."""
|
||||
self.slides: List[CarouselSlide] = []
|
||||
self.topic = ""
|
||||
self.industry = ""
|
||||
self.tone = ""
|
||||
self.content_type = ""
|
||||
self.num_slides = 0
|
||||
self.research_results = {}
|
||||
|
||||
def research_topic(self, topic: str, industry: str, search_engine: str = "metaphor") -> Dict:
|
||||
"""Research the topic to gather content for carousel slides."""
|
||||
try:
|
||||
# Construct research query
|
||||
search_query = f"""
|
||||
Find detailed professional content about '{topic}' in {industry} industry
|
||||
focusing on:
|
||||
- Key concepts and main points
|
||||
- Statistics and data
|
||||
- Examples and case studies
|
||||
- Best practices
|
||||
- Expert insights
|
||||
"""
|
||||
|
||||
# Perform research using selected engine
|
||||
if search_engine == "metaphor":
|
||||
results = metaphor_search_articles(search_query)
|
||||
elif search_engine == "google":
|
||||
results = do_google_serp_search(search_query)
|
||||
elif search_engine == "tavily":
|
||||
results = do_tavily_ai_search(search_query)
|
||||
|
||||
self.research_results = results
|
||||
return results
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error researching topic: {e}")
|
||||
return {}
|
||||
|
||||
def generate_slide_content(self, topic: str, num_slides: int = 5) -> bool:
|
||||
"""Generate content for carousel slides."""
|
||||
try:
|
||||
logger.info(f"Generating carousel outline for topic: {topic}")
|
||||
|
||||
# Step 1: Generate detailed outline
|
||||
outline_prompt = f"""
|
||||
Create a detailed outline for a LinkedIn carousel about {topic}.
|
||||
The outline should include:
|
||||
1. Main topic and key message
|
||||
2. {num_slides} main points to cover
|
||||
3. Supporting details for each point
|
||||
4. Key takeaways and call-to-action
|
||||
|
||||
Format the outline in a clear, structured way.
|
||||
"""
|
||||
|
||||
outline = llm_text_gen(outline_prompt)
|
||||
logger.debug(f"Generated outline: {outline}")
|
||||
|
||||
# Step 2: Generate structured carousel content
|
||||
carousel_prompt = f"""
|
||||
Based on this outline:
|
||||
{outline}
|
||||
|
||||
Create a LinkedIn carousel with {num_slides} slides.
|
||||
Each slide should have:
|
||||
- A compelling heading
|
||||
- A brief subheading
|
||||
- Concise, engaging content
|
||||
- A detailed image prompt for visual content
|
||||
|
||||
The content should be informative, engaging, and valuable for LinkedIn professionals.
|
||||
"""
|
||||
|
||||
logger.info("Generating structured carousel content")
|
||||
carousel_structure = generate_structured_content(carousel_prompt)
|
||||
|
||||
if not carousel_structure:
|
||||
logger.error("Failed to generate structured carousel content")
|
||||
return False
|
||||
|
||||
logger.debug(f"Generated carousel structure: {json.dumps(carousel_structure, indent=2)}")
|
||||
|
||||
# Validate and process the structure
|
||||
if "slides" not in carousel_structure:
|
||||
logger.error("Invalid carousel structure: missing 'slides' key")
|
||||
return False
|
||||
|
||||
self.slides = []
|
||||
for slide_data in carousel_structure["slides"]:
|
||||
try:
|
||||
slide = CarouselSlide(
|
||||
index=slide_data["index"],
|
||||
heading=slide_data["heading"],
|
||||
subheading=slide_data["subheading"],
|
||||
content=slide_data["content"],
|
||||
image_prompt=slide_data["image_prompt"]
|
||||
)
|
||||
self.slides.append(slide)
|
||||
logger.debug(f"Created slide {slide.index}: {slide.heading}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing slide data: {e}")
|
||||
logger.debug(f"Problematic slide data: {slide_data}")
|
||||
continue
|
||||
|
||||
if not self.slides:
|
||||
logger.error("No valid slides were created")
|
||||
return False
|
||||
|
||||
logger.info(f"Successfully generated {len(self.slides)} slides")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating slide content: {e}")
|
||||
logger.exception("Full traceback:")
|
||||
return False
|
||||
|
||||
def generate_slide_image(self, slide: CarouselSlide) -> Optional[str]:
|
||||
"""Generate an image for a carousel slide."""
|
||||
try:
|
||||
# Generate image using the slide's prompt
|
||||
image_path = generate_image(slide.image_prompt)
|
||||
slide.image_path = image_path
|
||||
return image_path
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating slide image: {e}")
|
||||
return None
|
||||
|
||||
def optimize_content(self, slide: CarouselSlide) -> CarouselSlide:
|
||||
"""Optimize slide content for engagement."""
|
||||
try:
|
||||
optimization_prompt = f"""
|
||||
Optimize this carousel slide content for maximum LinkedIn engagement:
|
||||
|
||||
Current Content:
|
||||
Heading: {slide.heading}
|
||||
Subheading: {slide.subheading}
|
||||
Content: {slide.content}
|
||||
|
||||
Requirements:
|
||||
1. Make heading more attention-grabbing
|
||||
2. Ensure content is concise and impactful
|
||||
3. Add relevant emojis where appropriate
|
||||
4. Optimize for readability
|
||||
5. Keep professional tone
|
||||
6. Maintain focus on {self.topic}
|
||||
|
||||
Return as JSON:
|
||||
{{
|
||||
"heading": "Optimized heading",
|
||||
"subheading": "Optimized subheading",
|
||||
"content": "Optimized content"
|
||||
}}
|
||||
"""
|
||||
|
||||
optimized = llm_text_gen(optimization_prompt)
|
||||
|
||||
try:
|
||||
optimized_data = json.loads(optimized)
|
||||
slide.heading = optimized_data["heading"]
|
||||
slide.subheading = optimized_data["subheading"]
|
||||
slide.content = optimized_data["content"]
|
||||
except json.JSONDecodeError:
|
||||
logger.error("Failed to parse optimized content")
|
||||
|
||||
return slide
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error optimizing slide content: {e}")
|
||||
return slide
|
||||
|
||||
|
||||
def linkedin_carousel_generator_ui():
|
||||
"""Streamlit UI for the LinkedIn Carousel Generator."""
|
||||
st.title("🔄 LinkedIn Carousel Post Generator")
|
||||
st.write("Create engaging carousel posts that showcase your content professionally")
|
||||
|
||||
# Initialize generator
|
||||
generator = LinkedInCarouselGenerator()
|
||||
|
||||
# Initialize session state
|
||||
if "carousel_data" not in st.session_state:
|
||||
st.session_state.carousel_data = {
|
||||
"slides": [],
|
||||
"research_results": None,
|
||||
"generated_images": {},
|
||||
"current_slide": 0
|
||||
}
|
||||
|
||||
# Input form
|
||||
with st.form("carousel_form"):
|
||||
topic = st.text_input("Topic", placeholder="Enter the main topic of your carousel")
|
||||
industry = st.text_input("Industry", placeholder="e.g., Technology, Healthcare, Finance")
|
||||
|
||||
col1, col2, col3 = st.columns(3)
|
||||
|
||||
with col1:
|
||||
tone = st.selectbox(
|
||||
"Tone",
|
||||
["Professional", "Educational", "Conversational", "Inspiring", "Technical"]
|
||||
)
|
||||
|
||||
with col2:
|
||||
content_type = st.selectbox(
|
||||
"Content Type",
|
||||
["How-to Guide", "List", "Story", "Case Study", "Tips & Tricks"]
|
||||
)
|
||||
|
||||
with col3:
|
||||
num_slides = st.slider("Number of Slides", min_value=3, max_value=10, value=5)
|
||||
|
||||
# Research source selection
|
||||
search_engine = st.radio(
|
||||
"Research Source",
|
||||
["metaphor", "google", "tavily"],
|
||||
format_func=lambda x: {
|
||||
"metaphor": "🔍 Metaphor AI",
|
||||
"google": "🌐 Google Search",
|
||||
"tavily": "🤖 Tavily AI"
|
||||
}[x]
|
||||
)
|
||||
|
||||
submit = st.form_submit_button("Generate Carousel")
|
||||
|
||||
if submit and topic and industry:
|
||||
# Create status container
|
||||
status_container = st.empty()
|
||||
|
||||
with st.spinner("Researching and generating your carousel..."):
|
||||
# Research phase
|
||||
status_container.text("🔍 Phase 1: Researching topic...")
|
||||
research_results = generator.research_topic(topic, industry, search_engine)
|
||||
st.session_state.carousel_data["research_results"] = research_results
|
||||
|
||||
if research_results:
|
||||
# Content generation phase
|
||||
status_container.text("✍️ Phase 2: Creating carousel content...")
|
||||
slides = generator.generate_slide_content(
|
||||
topic, num_slides
|
||||
)
|
||||
|
||||
if not slides:
|
||||
status_container.error("❌ Failed to generate carousel content. Please try again with different parameters.")
|
||||
st.error("""
|
||||
Tips to resolve this issue:
|
||||
1. Try a different topic or industry
|
||||
2. Adjust the number of slides
|
||||
3. Change the content type or tone
|
||||
4. Try a different research source
|
||||
""")
|
||||
return
|
||||
|
||||
st.session_state.carousel_data["slides"] = slides
|
||||
|
||||
# Image generation phase
|
||||
status_container.text("🎨 Phase 3: Generating slide visuals...")
|
||||
for slide in slides:
|
||||
image_path = generator.generate_slide_image(slide)
|
||||
if image_path:
|
||||
st.session_state.carousel_data["generated_images"][slide.index] = image_path
|
||||
|
||||
status_container.text("✅ Carousel generation complete!")
|
||||
else:
|
||||
status_container.error("❌ No research results found. Please try a different topic or research source.")
|
||||
st.error("""
|
||||
Tips to resolve this issue:
|
||||
1. Try a more specific topic
|
||||
2. Use a different research source
|
||||
3. Check if your topic is too niche or too broad
|
||||
4. Ensure your industry selection is accurate
|
||||
""")
|
||||
|
||||
# Display carousel if we have slides
|
||||
if st.session_state.carousel_data["slides"]:
|
||||
st.markdown("---")
|
||||
|
||||
# Create tabs for different views
|
||||
tab1, tab2 = st.tabs(["🎯 Carousel Preview", "📊 Research Results"])
|
||||
|
||||
with tab1:
|
||||
st.subheader("Carousel Preview")
|
||||
|
||||
# Slide navigation
|
||||
col1, col2, col3 = st.columns([1, 3, 1])
|
||||
|
||||
with col1:
|
||||
if st.button("⬅️ Previous") and st.session_state.carousel_data["current_slide"] > 0:
|
||||
st.session_state.carousel_data["current_slide"] -= 1
|
||||
|
||||
with col3:
|
||||
if st.button("Next ➡️") and st.session_state.carousel_data["current_slide"] < len(st.session_state.carousel_data["slides"]) - 1:
|
||||
st.session_state.carousel_data["current_slide"] += 1
|
||||
|
||||
# Display current slide
|
||||
current_slide = st.session_state.carousel_data["slides"][st.session_state.carousel_data["current_slide"]]
|
||||
|
||||
st.markdown(f"""
|
||||
<div style='
|
||||
background: white;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
margin: 1rem 0;
|
||||
'>
|
||||
<h1 style='
|
||||
color: #0A66C2;
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 0.5rem;
|
||||
'>{current_slide.heading}</h1>
|
||||
|
||||
<h2 style='
|
||||
color: #666;
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
'>{current_slide.subheading}</h2>
|
||||
|
||||
<p style='
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.6;
|
||||
color: #2f2f2f;
|
||||
'>{current_slide.content}</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Display slide image if available
|
||||
if current_slide.image_path:
|
||||
st.image(current_slide.image_path,
|
||||
caption=f"Slide {current_slide.index} Image",
|
||||
use_container_width=True)
|
||||
|
||||
# Slide controls
|
||||
st.markdown(f"**Slide {current_slide.index} of {len(st.session_state.carousel_data['slides'])}**")
|
||||
|
||||
# Edit options
|
||||
with st.expander("✏️ Edit Slide"):
|
||||
# Edit form for current slide
|
||||
edited_heading = st.text_input("Heading", value=current_slide.heading)
|
||||
edited_subheading = st.text_input("Subheading", value=current_slide.subheading)
|
||||
edited_content = st.text_area("Content", value=current_slide.content)
|
||||
|
||||
if st.button("Update Slide"):
|
||||
current_slide.heading = edited_heading
|
||||
current_slide.subheading = edited_subheading
|
||||
current_slide.content = edited_content
|
||||
st.success("✅ Slide updated!")
|
||||
|
||||
if st.button("Optimize Content"):
|
||||
optimized_slide = generator.optimize_content(current_slide)
|
||||
st.success("✅ Content optimized!")
|
||||
st.experimental_rerun()
|
||||
|
||||
# Export options
|
||||
with st.expander("💾 Export Options"):
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
if st.button("Export Current Slide"):
|
||||
st.success("Slide exported successfully!")
|
||||
with col2:
|
||||
if st.button("Export Full Carousel"):
|
||||
st.success("Carousel exported successfully!")
|
||||
|
||||
with tab2:
|
||||
st.subheader("Research Results")
|
||||
|
||||
research_results = st.session_state.carousel_data["research_results"]
|
||||
|
||||
if research_results:
|
||||
# Display key insights
|
||||
st.markdown("### Key Insights")
|
||||
for insight in research_results.get("key_insights", []):
|
||||
st.markdown(f"- {insight}")
|
||||
|
||||
# Display statistics
|
||||
st.markdown("### Statistics & Data")
|
||||
for stat in research_results.get("statistics", []):
|
||||
st.markdown(f"- {stat}")
|
||||
|
||||
# Display sources
|
||||
st.markdown("### Sources")
|
||||
for source in research_results.get("sources", []):
|
||||
st.markdown(f"- {source}")
|
||||
else:
|
||||
st.info("No research results available.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
linkedin_carousel_generator_ui()
|
||||
@@ -1,108 +0,0 @@
|
||||
import streamlit as st
|
||||
import json
|
||||
from typing import Optional, List
|
||||
from .linkedin_carousel_generator import LinkedInCarouselGenerator, CarouselSlide
|
||||
|
||||
def linkedin_carousel_generator_ui():
|
||||
"""Streamlit UI for LinkedIn Carousel Generator."""
|
||||
st.title("LinkedIn Carousel Generator")
|
||||
st.write("Create engaging carousel posts for LinkedIn with AI-powered content generation.")
|
||||
|
||||
# Initialize session state
|
||||
if 'generator' not in st.session_state:
|
||||
st.session_state.generator = LinkedInCarouselGenerator()
|
||||
if 'slides' not in st.session_state:
|
||||
st.session_state.slides = []
|
||||
if 'current_slide' not in st.session_state:
|
||||
st.session_state.current_slide = 0
|
||||
|
||||
# Sidebar for input parameters
|
||||
with st.sidebar:
|
||||
st.header("Carousel Parameters")
|
||||
topic = st.text_input("Topic", help="Enter the main topic for your carousel")
|
||||
num_slides = st.slider("Number of Slides", min_value=3, max_value=10, value=5,
|
||||
help="Choose how many slides you want in your carousel")
|
||||
|
||||
if st.button("Generate Carousel"):
|
||||
if not topic:
|
||||
st.error("Please enter a topic")
|
||||
return
|
||||
|
||||
with st.spinner("Generating carousel content..."):
|
||||
success = st.session_state.generator.generate_slide_content(topic, num_slides)
|
||||
if success:
|
||||
st.session_state.slides = st.session_state.generator.slides
|
||||
st.session_state.current_slide = 0
|
||||
st.success("Carousel content generated successfully!")
|
||||
else:
|
||||
st.error("Failed to generate carousel content. Please try again.")
|
||||
|
||||
# Main content area
|
||||
if st.session_state.slides:
|
||||
# Display current slide
|
||||
current_slide = st.session_state.slides[st.session_state.current_slide]
|
||||
|
||||
col1, col2 = st.columns([2, 1])
|
||||
|
||||
with col1:
|
||||
st.subheader(f"Slide {current_slide.index}")
|
||||
st.write("**Heading:**")
|
||||
st.write(current_slide.heading)
|
||||
st.write("**Subheading:**")
|
||||
st.write(current_slide.subheading)
|
||||
st.write("**Content:**")
|
||||
st.write(current_slide.content)
|
||||
st.write("**Image Prompt:**")
|
||||
st.write(current_slide.image_prompt)
|
||||
|
||||
# Navigation buttons
|
||||
col_prev, col_next = st.columns(2)
|
||||
with col_prev:
|
||||
if st.session_state.current_slide > 0:
|
||||
if st.button("← Previous"):
|
||||
st.session_state.current_slide -= 1
|
||||
st.experimental_rerun()
|
||||
with col_next:
|
||||
if st.session_state.current_slide < len(st.session_state.slides) - 1:
|
||||
if st.button("Next →"):
|
||||
st.session_state.current_slide += 1
|
||||
st.experimental_rerun()
|
||||
|
||||
with col2:
|
||||
# Display structured output
|
||||
st.subheader("Carousel Structure")
|
||||
carousel_data = {
|
||||
"slides": [
|
||||
{
|
||||
"index": slide.index,
|
||||
"heading": slide.heading,
|
||||
"subheading": slide.subheading,
|
||||
"content": slide.content,
|
||||
"image_prompt": slide.image_prompt
|
||||
}
|
||||
for slide in st.session_state.slides
|
||||
]
|
||||
}
|
||||
st.json(carousel_data)
|
||||
|
||||
# Export options
|
||||
st.download_button(
|
||||
"Download as JSON",
|
||||
data=json.dumps(carousel_data, indent=2),
|
||||
file_name="carousel_content.json",
|
||||
mime="application/json"
|
||||
)
|
||||
|
||||
if st.button("Generate Images"):
|
||||
with st.spinner("Generating images for slides..."):
|
||||
for slide in st.session_state.slides:
|
||||
if not slide.image_path:
|
||||
image_path = st.session_state.generator.generate_slide_image(slide)
|
||||
if image_path:
|
||||
slide.image_path = image_path
|
||||
st.success(f"Generated image for slide {slide.index}")
|
||||
else:
|
||||
st.error(f"Failed to generate image for slide {slide.index}")
|
||||
|
||||
else:
|
||||
st.info("Enter a topic and click 'Generate Carousel' to create your carousel content.")
|
||||
@@ -1,261 +0,0 @@
|
||||
# LinkedIn Comment Response Generator
|
||||
|
||||
A powerful AI-powered tool for generating professional, engaging, and contextually appropriate responses to LinkedIn comments. This module helps maintain active engagement on LinkedIn by providing intelligent, well-crafted responses that build relationships and drive meaningful discussions.
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Intelligent Comment Analysis
|
||||
- Sentiment analysis of comments
|
||||
- Identification of key discussion points
|
||||
- Recognition of user intent and tone
|
||||
- Context-aware interpretation
|
||||
- Engagement opportunity detection
|
||||
|
||||
### 2. Response Generation
|
||||
- Multiple response types:
|
||||
- General professional responses
|
||||
- Disagreement handling
|
||||
- Value-add responses
|
||||
- Resource suggestions
|
||||
- Follow-up questions
|
||||
- Brand voice customization
|
||||
- Engagement goal targeting
|
||||
- Context-aware responses
|
||||
- Professional tone maintenance
|
||||
|
||||
### 3. Disagreement Handling
|
||||
- Diplomatic response generation
|
||||
- Evidence-based arguments
|
||||
- Common ground identification
|
||||
- Constructive dialogue promotion
|
||||
- Relationship preservation
|
||||
- Professional conflict resolution
|
||||
|
||||
### 4. Value-Add Responses
|
||||
- Industry-specific insights
|
||||
- Actionable recommendations
|
||||
- Expert perspective sharing
|
||||
- Resource linking
|
||||
- Knowledge sharing
|
||||
- Engagement hooks
|
||||
|
||||
### 5. Resource Suggestions
|
||||
- Curated learning materials
|
||||
- Progressive learning paths
|
||||
- Practical application tips
|
||||
- Follow-up support
|
||||
- Expertise-level matching
|
||||
- Topic-specific resources
|
||||
|
||||
### 6. Follow-up Questions
|
||||
- Discussion deepening
|
||||
- Multiple perspective exploration
|
||||
- Experience sharing prompts
|
||||
- Reflection encouragement
|
||||
- Engagement maintenance
|
||||
- Value exploration
|
||||
|
||||
### 7. Tone Optimization
|
||||
- Multiple tone options:
|
||||
- Professional
|
||||
- Friendly
|
||||
- Expert
|
||||
- Supportive
|
||||
- Diplomatic
|
||||
- Appreciative
|
||||
- Audience-specific adjustments
|
||||
- Brand voice alignment
|
||||
- Engagement optimization
|
||||
- Relationship building focus
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Response Generation
|
||||
```python
|
||||
from lib.ai_writers.linkedin_writer.modules.comment_response_generator import LinkedInCommentResponseGenerator
|
||||
|
||||
# Initialize the generator
|
||||
generator = LinkedInCommentResponseGenerator()
|
||||
|
||||
# Generate a response
|
||||
response = await generator.generate_response(
|
||||
comment="Your comment here",
|
||||
post_context="Original post context",
|
||||
brand_voice="professional",
|
||||
engagement_goal="continue_discussion"
|
||||
)
|
||||
```
|
||||
|
||||
### Handling Disagreements
|
||||
```python
|
||||
# Generate a diplomatic response
|
||||
response = await generator.handle_disagreement(
|
||||
comment="Disagreeing comment",
|
||||
post_context="Post context",
|
||||
brand_voice="diplomatic"
|
||||
)
|
||||
```
|
||||
|
||||
### Value-Add Responses
|
||||
```python
|
||||
# Generate a value-adding response
|
||||
response = await generator.generate_value_add_response(
|
||||
comment="Comment to respond to",
|
||||
industry="Technology",
|
||||
expertise_areas=["AI", "Machine Learning", "Data Science"]
|
||||
)
|
||||
```
|
||||
|
||||
### Resource Suggestions
|
||||
```python
|
||||
# Suggest resources
|
||||
response = await generator.suggest_resources(
|
||||
comment="Comment requesting resources",
|
||||
topic="Artificial Intelligence",
|
||||
expertise_level="intermediate"
|
||||
)
|
||||
```
|
||||
|
||||
### Follow-up Questions
|
||||
```python
|
||||
# Generate follow-up questions
|
||||
response = await generator.generate_follow_up_questions(
|
||||
comment="Original comment",
|
||||
discussion_context="Discussion context"
|
||||
)
|
||||
```
|
||||
|
||||
### Tone Optimization
|
||||
```python
|
||||
# Optimize response tone
|
||||
optimized = await generator.optimize_response_tone(
|
||||
response="Your response",
|
||||
target_tone="professional",
|
||||
audience="Tech professionals"
|
||||
)
|
||||
```
|
||||
|
||||
## UI Interface
|
||||
|
||||
The module includes a Streamlit-based user interface with the following sections:
|
||||
|
||||
1. **General Response Tab**
|
||||
- Comment input
|
||||
- Post context
|
||||
- Brand voice selection
|
||||
- Engagement goal selection
|
||||
- Response generation
|
||||
- Strategy display
|
||||
|
||||
2. **Handle Disagreement Tab**
|
||||
- Disagreeing comment input
|
||||
- Context input
|
||||
- Brand voice selection
|
||||
- Diplomatic response generation
|
||||
- Strategy display
|
||||
|
||||
3. **Value-Add Response Tab**
|
||||
- Comment input
|
||||
- Industry specification
|
||||
- Expertise areas input
|
||||
- Value-adding response generation
|
||||
- Component display
|
||||
|
||||
4. **Resource Suggestions Tab**
|
||||
- Comment input
|
||||
- Topic specification
|
||||
- Expertise level selection
|
||||
- Resource suggestion generation
|
||||
- Resource details display
|
||||
|
||||
5. **Follow-up Questions Tab**
|
||||
- Comment input
|
||||
- Discussion context
|
||||
- Question generation
|
||||
- Strategy display
|
||||
|
||||
6. **Tone Optimization Section**
|
||||
- Response input
|
||||
- Target tone selection
|
||||
- Audience specification
|
||||
- Tone optimization
|
||||
- Optimization details display
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Core Components
|
||||
|
||||
1. **LinkedInCommentResponseGenerator Class**
|
||||
- Main generator class
|
||||
- Response tone definitions
|
||||
- Comment type definitions
|
||||
- Core response generation methods
|
||||
|
||||
2. **Response Generation Methods**
|
||||
- `analyze_comment`: Analyzes comment sentiment and intent
|
||||
- `generate_response`: Creates contextually appropriate responses
|
||||
- `handle_disagreement`: Generates diplomatic responses
|
||||
- `generate_value_add_response`: Creates value-adding responses
|
||||
- `suggest_resources`: Provides relevant resource suggestions
|
||||
- `generate_follow_up_questions`: Creates engaging follow-up questions
|
||||
- `optimize_response_tone`: Adjusts response tone for target audience
|
||||
|
||||
3. **UI Implementation**
|
||||
- Streamlit-based interface
|
||||
- Tab-based organization
|
||||
- Interactive input fields
|
||||
- Real-time response generation
|
||||
- Detailed strategy displays
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Streamlit
|
||||
- AI text generation capabilities
|
||||
- Web research tools
|
||||
- JSON processing
|
||||
- Async/await support
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Response Generation**
|
||||
- Always provide context
|
||||
- Select appropriate brand voice
|
||||
- Define clear engagement goals
|
||||
- Review generated responses
|
||||
- Optimize tone for audience
|
||||
|
||||
2. **Disagreement Handling**
|
||||
- Maintain professionalism
|
||||
- Focus on common ground
|
||||
- Provide evidence
|
||||
- Encourage dialogue
|
||||
- Preserve relationships
|
||||
|
||||
3. **Value-Add Responses**
|
||||
- Share relevant expertise
|
||||
- Provide actionable insights
|
||||
- Include supporting evidence
|
||||
- Suggest practical applications
|
||||
- Maintain engagement
|
||||
|
||||
4. **Resource Suggestions**
|
||||
- Match expertise level
|
||||
- Provide learning path
|
||||
- Include application tips
|
||||
- Offer follow-up support
|
||||
- Ensure resource accessibility
|
||||
|
||||
5. **Follow-up Questions**
|
||||
- Deepen discussion
|
||||
- Explore new angles
|
||||
- Encourage participation
|
||||
- Maintain professionalism
|
||||
- Drive engagement
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
@@ -1,11 +0,0 @@
|
||||
"""
|
||||
LinkedIn Comment Response Generator Module
|
||||
|
||||
This module provides AI-powered generation of professional and engaging responses
|
||||
to comments on LinkedIn posts.
|
||||
"""
|
||||
|
||||
from .linkedin_comment_response_generator import LinkedInCommentResponseGenerator
|
||||
from .linkedin_comment_response_generator_ui import linkedin_comment_response_generator_ui
|
||||
|
||||
__all__ = ['LinkedInCommentResponseGenerator', 'linkedin_comment_response_generator_ui']
|
||||
@@ -1,346 +0,0 @@
|
||||
"""
|
||||
LinkedIn Comment Response Generator
|
||||
|
||||
This module provides AI-powered generation of professional and engaging responses
|
||||
to comments on LinkedIn posts.
|
||||
"""
|
||||
|
||||
import json
|
||||
from typing import Dict, List, Optional
|
||||
from loguru import logger
|
||||
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from .....ai_web_researcher.gpt_online_researcher import do_google_serp_search
|
||||
from .....ai_web_researcher.metaphor_basic_neural_web_search import metaphor_search_articles
|
||||
from .....ai_web_researcher.tavily_ai_search import do_tavily_ai_search
|
||||
|
||||
class LinkedInCommentResponseGenerator:
|
||||
"""
|
||||
AI-powered generator for professional and engaging LinkedIn comment responses.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the LinkedIn Comment Response Generator."""
|
||||
self.response_tones = [
|
||||
"professional",
|
||||
"friendly",
|
||||
"expert",
|
||||
"supportive",
|
||||
"diplomatic",
|
||||
"appreciative"
|
||||
]
|
||||
|
||||
self.comment_types = [
|
||||
"question",
|
||||
"agreement",
|
||||
"disagreement",
|
||||
"appreciation",
|
||||
"criticism",
|
||||
"suggestion",
|
||||
"experience_sharing"
|
||||
]
|
||||
|
||||
async def analyze_comment(self, comment: str) -> Dict:
|
||||
"""
|
||||
Analyze the comment to determine its type, tone, and key points.
|
||||
|
||||
Args:
|
||||
comment: The comment text to analyze
|
||||
|
||||
Returns:
|
||||
Dict containing comment analysis
|
||||
"""
|
||||
prompt = f"""
|
||||
As a LinkedIn engagement expert, analyze this comment:
|
||||
|
||||
Comment: {comment}
|
||||
|
||||
Provide a detailed analysis including:
|
||||
- Comment type (question/agreement/disagreement/etc.)
|
||||
- Emotional tone
|
||||
- Key points or questions raised
|
||||
- Intent and context
|
||||
- Engagement potential
|
||||
|
||||
Return a JSON with:
|
||||
- comment_type: The type of comment
|
||||
- tone: Emotional tone
|
||||
- key_points: List of main points
|
||||
- questions: Any questions raised
|
||||
- intent: Perceived intent
|
||||
- engagement_potential: High/Medium/Low
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
|
||||
async def generate_response(self,
|
||||
comment: str,
|
||||
post_context: str,
|
||||
brand_voice: str,
|
||||
engagement_goal: str
|
||||
) -> Dict:
|
||||
"""
|
||||
Generate an appropriate response to the comment.
|
||||
|
||||
Args:
|
||||
comment: The comment to respond to
|
||||
post_context: The context of the original post
|
||||
brand_voice: Desired brand voice/tone
|
||||
engagement_goal: Goal for the response
|
||||
|
||||
Returns:
|
||||
Dict containing response and strategy
|
||||
"""
|
||||
# First analyze the comment
|
||||
analysis = await self.analyze_comment(comment)
|
||||
|
||||
prompt = f"""
|
||||
As a LinkedIn engagement expert, generate a response to this comment:
|
||||
|
||||
Comment: {comment}
|
||||
Post Context: {post_context}
|
||||
Brand Voice: {brand_voice}
|
||||
Engagement Goal: {engagement_goal}
|
||||
|
||||
Comment Analysis: {json.dumps(analysis)}
|
||||
|
||||
Generate a response that:
|
||||
- Maintains professional tone
|
||||
- Addresses key points/questions
|
||||
- Aligns with brand voice
|
||||
- Encourages further engagement
|
||||
- Builds community
|
||||
- Adds value
|
||||
|
||||
Return a JSON with:
|
||||
- response: The generated response
|
||||
- tone_used: Tone of the response
|
||||
- key_points_addressed: Points addressed
|
||||
- engagement_hooks: Elements to encourage interaction
|
||||
- value_adds: Additional value provided
|
||||
- follow_up_suggestions: Potential follow-up points
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
|
||||
async def handle_disagreement(self,
|
||||
comment: str,
|
||||
post_context: str,
|
||||
brand_voice: str
|
||||
) -> Dict:
|
||||
"""
|
||||
Generate a professional response to a disagreement.
|
||||
|
||||
Args:
|
||||
comment: The disagreeing comment
|
||||
post_context: Original post context
|
||||
brand_voice: Desired brand voice
|
||||
|
||||
Returns:
|
||||
Dict containing diplomatic response
|
||||
"""
|
||||
prompt = f"""
|
||||
As a LinkedIn communication expert, craft a diplomatic response to this disagreement:
|
||||
|
||||
Comment: {comment}
|
||||
Post Context: {post_context}
|
||||
Brand Voice: {brand_voice}
|
||||
|
||||
Generate a response that:
|
||||
- Maintains professionalism
|
||||
- Acknowledges the perspective
|
||||
- Provides supporting evidence
|
||||
- Finds common ground
|
||||
- Keeps discussion constructive
|
||||
- Invites further dialogue
|
||||
|
||||
Return a JSON with:
|
||||
- response: The diplomatic response
|
||||
- acknowledgment: How the perspective was acknowledged
|
||||
- evidence: Supporting points provided
|
||||
- common_ground: Areas of agreement
|
||||
- dialogue_hooks: Elements to continue discussion
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
|
||||
async def generate_value_add_response(self,
|
||||
comment: str,
|
||||
industry: str,
|
||||
expertise_areas: List[str]
|
||||
) -> Dict:
|
||||
"""
|
||||
Generate a response that adds significant value.
|
||||
|
||||
Args:
|
||||
comment: The comment to respond to
|
||||
industry: Relevant industry
|
||||
expertise_areas: Areas of expertise
|
||||
|
||||
Returns:
|
||||
Dict containing value-adding response
|
||||
"""
|
||||
# Research relevant insights
|
||||
research = await do_tavily_ai_search(
|
||||
f"latest insights trends {industry} {' '.join(expertise_areas)}"
|
||||
)
|
||||
|
||||
prompt = f"""
|
||||
As a LinkedIn thought leader, generate a value-adding response:
|
||||
|
||||
Comment: {comment}
|
||||
Industry: {industry}
|
||||
Expertise Areas: {expertise_areas}
|
||||
Research Insights: {json.dumps(research)}
|
||||
|
||||
Create a response that:
|
||||
- Shares relevant insights
|
||||
- Provides actionable advice
|
||||
- References credible sources
|
||||
- Demonstrates expertise
|
||||
- Encourages implementation
|
||||
- Invites questions
|
||||
|
||||
Return a JSON with:
|
||||
- response: The value-adding response
|
||||
- insights_shared: Key insights provided
|
||||
- action_items: Actionable takeaways
|
||||
- sources: Referenced sources
|
||||
- expertise_demonstrated: How expertise was shown
|
||||
- engagement_hooks: Questions or prompts
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
|
||||
async def suggest_resources(self,
|
||||
comment: str,
|
||||
topic: str,
|
||||
expertise_level: str
|
||||
) -> Dict:
|
||||
"""
|
||||
Suggest relevant resources in response to a comment.
|
||||
|
||||
Args:
|
||||
comment: The comment requesting/needing resources
|
||||
topic: The topic of discussion
|
||||
expertise_level: User's expertise level
|
||||
|
||||
Returns:
|
||||
Dict containing resource suggestions
|
||||
"""
|
||||
# Research relevant resources
|
||||
resources = await metaphor_search_articles(
|
||||
f"best resources tutorials guides {topic} {expertise_level}"
|
||||
)
|
||||
|
||||
prompt = f"""
|
||||
As a LinkedIn learning facilitator, suggest helpful resources:
|
||||
|
||||
Comment: {comment}
|
||||
Topic: {topic}
|
||||
Expertise Level: {expertise_level}
|
||||
Found Resources: {json.dumps(resources)}
|
||||
|
||||
Provide suggestions that:
|
||||
- Match expertise level
|
||||
- Cover key aspects
|
||||
- Include various formats
|
||||
- Are readily accessible
|
||||
- Support learning goals
|
||||
- Encourage application
|
||||
|
||||
Return a JSON with:
|
||||
- response: Resource suggestion response
|
||||
- recommended_resources: List of resources
|
||||
- learning_path: Suggested learning sequence
|
||||
- application_tips: How to apply resources
|
||||
- follow_up_support: Additional support offered
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
|
||||
async def generate_follow_up_questions(self,
|
||||
comment: str,
|
||||
discussion_context: str
|
||||
) -> Dict:
|
||||
"""
|
||||
Generate engaging follow-up questions to continue the discussion.
|
||||
|
||||
Args:
|
||||
comment: The comment to generate questions for
|
||||
discussion_context: Context of the discussion
|
||||
|
||||
Returns:
|
||||
Dict containing follow-up questions
|
||||
"""
|
||||
prompt = f"""
|
||||
As a LinkedIn engagement expert, generate follow-up questions:
|
||||
|
||||
Comment: {comment}
|
||||
Discussion Context: {discussion_context}
|
||||
|
||||
Generate questions that:
|
||||
- Deepen the discussion
|
||||
- Explore different angles
|
||||
- Draw out experiences
|
||||
- Encourage reflection
|
||||
- Maintain professionalism
|
||||
- Drive engagement
|
||||
|
||||
Return a JSON with:
|
||||
- primary_question: Main follow-up question
|
||||
- secondary_questions: Additional questions
|
||||
- discussion_angles: New perspectives to explore
|
||||
- engagement_prompts: Ways to encourage participation
|
||||
- value_exploration: Areas to uncover value
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
|
||||
async def optimize_response_tone(self,
|
||||
response: str,
|
||||
target_tone: str,
|
||||
audience: str
|
||||
) -> Dict:
|
||||
"""
|
||||
Optimize the tone of a response for the target audience.
|
||||
|
||||
Args:
|
||||
response: The response to optimize
|
||||
target_tone: Desired tone
|
||||
audience: Target audience
|
||||
|
||||
Returns:
|
||||
Dict containing tone-optimized response
|
||||
"""
|
||||
prompt = f"""
|
||||
As a LinkedIn communication expert, optimize this response's tone:
|
||||
|
||||
Response: {response}
|
||||
Target Tone: {target_tone}
|
||||
Audience: {audience}
|
||||
|
||||
Optimize the response to:
|
||||
- Match desired tone
|
||||
- Resonate with audience
|
||||
- Maintain professionalism
|
||||
- Enhance engagement
|
||||
- Build rapport
|
||||
- Reflect brand voice
|
||||
|
||||
Return a JSON with:
|
||||
- optimized_response: Tone-adjusted response
|
||||
- tone_adjustments: Changes made
|
||||
- audience_alignment: How it matches audience
|
||||
- engagement_potential: Expected engagement
|
||||
- relationship_building: How it builds connection
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
@@ -1,283 +0,0 @@
|
||||
"""
|
||||
LinkedIn Comment Response Generator UI
|
||||
|
||||
This module provides the Streamlit UI for the LinkedIn Comment Response Generator.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import json
|
||||
from typing import Dict, List
|
||||
from .linkedin_comment_response_generator import LinkedInCommentResponseGenerator
|
||||
|
||||
async def linkedin_comment_response_generator_ui():
|
||||
"""
|
||||
Streamlit UI for the LinkedIn Comment Response Generator.
|
||||
"""
|
||||
# Initialize the generator
|
||||
generator = LinkedInCommentResponseGenerator()
|
||||
|
||||
st.title("LinkedIn Comment Response Generator")
|
||||
|
||||
# Create tabs for different response scenarios
|
||||
tabs = st.tabs([
|
||||
"General Response",
|
||||
"Handle Disagreement",
|
||||
"Value-Add Response",
|
||||
"Resource Suggestions",
|
||||
"Follow-up Questions"
|
||||
])
|
||||
|
||||
# General Response Tab
|
||||
with tabs[0]:
|
||||
st.header("Generate Professional Response")
|
||||
st.info("Generate an engaging and professional response to a LinkedIn comment")
|
||||
|
||||
comment = st.text_area("Comment to Respond to", height=100)
|
||||
post_context = st.text_area("Original Post Context", height=100)
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
brand_voice = st.selectbox(
|
||||
"Brand Voice",
|
||||
["Professional", "Friendly", "Expert", "Supportive", "Diplomatic", "Appreciative"]
|
||||
)
|
||||
|
||||
with col2:
|
||||
engagement_goal = st.selectbox(
|
||||
"Engagement Goal",
|
||||
["Continue Discussion", "Share Knowledge", "Build Relationship", "Address Concern", "Encourage Action"]
|
||||
)
|
||||
|
||||
if st.button("Generate Response", key="general_response"):
|
||||
with st.spinner("Generating response..."):
|
||||
# First analyze the comment
|
||||
analysis = await generator.analyze_comment(comment)
|
||||
|
||||
# Display analysis
|
||||
with st.expander("Comment Analysis", expanded=True):
|
||||
st.json(analysis)
|
||||
|
||||
# Generate response
|
||||
response = await generator.generate_response(
|
||||
comment,
|
||||
post_context,
|
||||
brand_voice.lower(),
|
||||
engagement_goal
|
||||
)
|
||||
|
||||
# Display response
|
||||
st.subheader("Generated Response")
|
||||
st.success(response['response'])
|
||||
|
||||
# Display strategy
|
||||
with st.expander("Response Strategy"):
|
||||
st.write("**Tone Used:**", response['tone_used'])
|
||||
|
||||
st.write("**Key Points Addressed:**")
|
||||
for point in response['key_points_addressed']:
|
||||
st.write(f"- {point}")
|
||||
|
||||
st.write("**Engagement Hooks:**")
|
||||
for hook in response['engagement_hooks']:
|
||||
st.write(f"- {hook}")
|
||||
|
||||
st.write("**Value Adds:**")
|
||||
for value in response['value_adds']:
|
||||
st.write(f"- {value}")
|
||||
|
||||
st.write("**Follow-up Suggestions:**")
|
||||
for suggestion in response['follow_up_suggestions']:
|
||||
st.write(f"- {suggestion}")
|
||||
|
||||
# Handle Disagreement Tab
|
||||
with tabs[1]:
|
||||
st.header("Handle Disagreement")
|
||||
st.info("Generate a diplomatic response to a disagreeing comment")
|
||||
|
||||
disagreement_comment = st.text_area("Disagreeing Comment", height=100, key="disagreement_comment")
|
||||
disagreement_context = st.text_area("Post Context", height=100, key="disagreement_context")
|
||||
disagreement_voice = st.selectbox(
|
||||
"Brand Voice",
|
||||
["Diplomatic", "Professional", "Expert", "Supportive"],
|
||||
key="disagreement_voice"
|
||||
)
|
||||
|
||||
if st.button("Generate Diplomatic Response"):
|
||||
with st.spinner("Generating diplomatic response..."):
|
||||
response = await generator.handle_disagreement(
|
||||
disagreement_comment,
|
||||
disagreement_context,
|
||||
disagreement_voice.lower()
|
||||
)
|
||||
|
||||
st.subheader("Diplomatic Response")
|
||||
st.success(response['response'])
|
||||
|
||||
with st.expander("Response Strategy"):
|
||||
st.write("**Acknowledgment:**", response['acknowledgment'])
|
||||
|
||||
st.write("**Supporting Evidence:**")
|
||||
for point in response['evidence']:
|
||||
st.write(f"- {point}")
|
||||
|
||||
st.write("**Common Ground:**")
|
||||
for point in response['common_ground']:
|
||||
st.write(f"- {point}")
|
||||
|
||||
st.write("**Dialogue Continuation:**")
|
||||
for hook in response['dialogue_hooks']:
|
||||
st.write(f"- {hook}")
|
||||
|
||||
# Value-Add Response Tab
|
||||
with tabs[2]:
|
||||
st.header("Value-Add Response")
|
||||
st.info("Generate a response that provides significant value")
|
||||
|
||||
value_comment = st.text_area("Comment", height=100, key="value_comment")
|
||||
industry = st.text_input("Industry")
|
||||
expertise_areas = st.text_area(
|
||||
"Areas of Expertise (one per line)",
|
||||
height=100
|
||||
).split("\n")
|
||||
|
||||
if st.button("Generate Value-Add Response"):
|
||||
with st.spinner("Researching and generating response..."):
|
||||
response = await generator.generate_value_add_response(
|
||||
value_comment,
|
||||
industry,
|
||||
expertise_areas
|
||||
)
|
||||
|
||||
st.subheader("Value-Adding Response")
|
||||
st.success(response['response'])
|
||||
|
||||
with st.expander("Value Components"):
|
||||
st.write("**Key Insights:**")
|
||||
for insight in response['insights_shared']:
|
||||
st.write(f"- {insight}")
|
||||
|
||||
st.write("**Action Items:**")
|
||||
for item in response['action_items']:
|
||||
st.write(f"- {item}")
|
||||
|
||||
st.write("**Sources:**")
|
||||
for source in response['sources']:
|
||||
st.write(f"- {source}")
|
||||
|
||||
st.write("**Expertise Demonstrated:**")
|
||||
st.write(response['expertise_demonstrated'])
|
||||
|
||||
st.write("**Engagement Hooks:**")
|
||||
for hook in response['engagement_hooks']:
|
||||
st.write(f"- {hook}")
|
||||
|
||||
# Resource Suggestions Tab
|
||||
with tabs[3]:
|
||||
st.header("Resource Suggestions")
|
||||
st.info("Suggest helpful resources in response to a comment")
|
||||
|
||||
resource_comment = st.text_area("Comment", height=100, key="resource_comment")
|
||||
topic = st.text_input("Topic")
|
||||
expertise_level = st.select_slider(
|
||||
"Expertise Level",
|
||||
options=["Beginner", "Intermediate", "Advanced", "Expert"]
|
||||
)
|
||||
|
||||
if st.button("Generate Resource Suggestions"):
|
||||
with st.spinner("Researching and compiling resources..."):
|
||||
response = await generator.suggest_resources(
|
||||
resource_comment,
|
||||
topic,
|
||||
expertise_level.lower()
|
||||
)
|
||||
|
||||
st.subheader("Resource Suggestion Response")
|
||||
st.success(response['response'])
|
||||
|
||||
with st.expander("Resource Details"):
|
||||
st.write("**Recommended Resources:**")
|
||||
for resource in response['recommended_resources']:
|
||||
st.write(f"- {resource}")
|
||||
|
||||
st.write("**Learning Path:**")
|
||||
for step in response['learning_path']:
|
||||
st.write(f"- {step}")
|
||||
|
||||
st.write("**Application Tips:**")
|
||||
for tip in response['application_tips']:
|
||||
st.write(f"- {tip}")
|
||||
|
||||
st.write("**Follow-up Support:**")
|
||||
st.write(response['follow_up_support'])
|
||||
|
||||
# Follow-up Questions Tab
|
||||
with tabs[4]:
|
||||
st.header("Follow-up Questions")
|
||||
st.info("Generate engaging follow-up questions to continue the discussion")
|
||||
|
||||
question_comment = st.text_area("Comment", height=100, key="question_comment")
|
||||
discussion_context = st.text_area("Discussion Context", height=100, key="question_context")
|
||||
|
||||
if st.button("Generate Follow-up Questions"):
|
||||
with st.spinner("Generating questions..."):
|
||||
response = await generator.generate_follow_up_questions(
|
||||
question_comment,
|
||||
discussion_context
|
||||
)
|
||||
|
||||
st.subheader("Primary Follow-up Question")
|
||||
st.success(response['primary_question'])
|
||||
|
||||
st.subheader("Secondary Questions")
|
||||
for question in response['secondary_questions']:
|
||||
st.info(question)
|
||||
|
||||
with st.expander("Discussion Strategy"):
|
||||
st.write("**Discussion Angles:**")
|
||||
for angle in response['discussion_angles']:
|
||||
st.write(f"- {angle}")
|
||||
|
||||
st.write("**Engagement Prompts:**")
|
||||
for prompt in response['engagement_prompts']:
|
||||
st.write(f"- {prompt}")
|
||||
|
||||
st.write("**Value Exploration:**")
|
||||
for area in response['value_exploration']:
|
||||
st.write(f"- {area}")
|
||||
|
||||
# Add tone optimization section at the bottom
|
||||
st.divider()
|
||||
st.subheader("Response Tone Optimization")
|
||||
st.info("Optimize the tone of any generated response")
|
||||
|
||||
response_to_optimize = st.text_area("Response to Optimize", height=100)
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
target_tone = st.selectbox(
|
||||
"Target Tone",
|
||||
generator.response_tones
|
||||
)
|
||||
|
||||
with col2:
|
||||
audience = st.text_input("Target Audience")
|
||||
|
||||
if st.button("Optimize Tone"):
|
||||
with st.spinner("Optimizing response tone..."):
|
||||
optimized = await generator.optimize_response_tone(
|
||||
response_to_optimize,
|
||||
target_tone,
|
||||
audience
|
||||
)
|
||||
|
||||
st.subheader("Tone-Optimized Response")
|
||||
st.success(optimized['optimized_response'])
|
||||
|
||||
with st.expander("Optimization Details"):
|
||||
st.write("**Tone Adjustments:**")
|
||||
for adjustment in optimized['tone_adjustments']:
|
||||
st.write(f"- {adjustment}")
|
||||
|
||||
st.write("**Audience Alignment:**", optimized['audience_alignment'])
|
||||
st.write("**Engagement Potential:**", optimized['engagement_potential'])
|
||||
st.write("**Relationship Building:**", optimized['relationship_building'])
|
||||
@@ -1,14 +0,0 @@
|
||||
"""
|
||||
LinkedIn Company Page Content Generator Module
|
||||
|
||||
This module provides tools for generating and optimizing content for LinkedIn company pages.
|
||||
It includes features for company profile optimization, content generation, and engagement tracking.
|
||||
"""
|
||||
|
||||
from .linkedin_company_page_generator import LinkedInCompanyPageGenerator
|
||||
from .linkedin_company_page_generator_ui import linkedin_company_page_generator_ui
|
||||
|
||||
__all__ = [
|
||||
'LinkedInCompanyPageGenerator',
|
||||
'linkedin_company_page_generator_ui'
|
||||
]
|
||||
@@ -1,322 +0,0 @@
|
||||
"""
|
||||
LinkedIn Company Page Content Generator
|
||||
|
||||
This module provides the core functionality for generating and optimizing LinkedIn company page content.
|
||||
"""
|
||||
|
||||
import json
|
||||
from typing import Dict, List, Optional, Union
|
||||
from loguru import logger
|
||||
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from .....ai_web_researcher.gpt_online_researcher import do_google_serp_search
|
||||
from .....ai_web_researcher.metaphor_basic_neural_web_search import metaphor_search_articles
|
||||
from .....ai_web_researcher.tavily_ai_search import do_tavily_ai_search
|
||||
from .....gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
|
||||
|
||||
class LinkedInCompanyPageGenerator:
|
||||
"""Main class for generating LinkedIn company page content."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the LinkedIn Company Page Generator."""
|
||||
self.company_info = {}
|
||||
self.brand_voice = {}
|
||||
self.content_history = []
|
||||
|
||||
async def optimize_company_profile(
|
||||
self,
|
||||
company_name: str,
|
||||
industry: str,
|
||||
target_audience: List[str],
|
||||
brand_voice: str,
|
||||
key_products: List[str],
|
||||
company_size: str,
|
||||
company_description: str
|
||||
) -> Dict[str, str]:
|
||||
"""
|
||||
Optimize the company profile content for LinkedIn.
|
||||
|
||||
Args:
|
||||
company_name: Name of the company
|
||||
industry: Industry sector
|
||||
target_audience: List of target audience segments
|
||||
brand_voice: Desired brand voice/tone
|
||||
key_products: List of key products/services
|
||||
company_size: Size of the company
|
||||
company_description: Current company description
|
||||
|
||||
Returns:
|
||||
Dict containing optimized profile sections
|
||||
"""
|
||||
try:
|
||||
# Store company info for future content generation
|
||||
self.company_info = {
|
||||
"name": company_name,
|
||||
"industry": industry,
|
||||
"target_audience": target_audience,
|
||||
"brand_voice": brand_voice,
|
||||
"key_products": key_products,
|
||||
"size": company_size,
|
||||
"description": company_description
|
||||
}
|
||||
|
||||
# Create the prompt for profile optimization
|
||||
prompt = f"""
|
||||
Optimize the LinkedIn company profile for {company_name}, a {company_size} company in the {industry} industry.
|
||||
|
||||
Current Description:
|
||||
{company_description}
|
||||
|
||||
Key Products/Services:
|
||||
{', '.join(key_products)}
|
||||
|
||||
Target Audience:
|
||||
{', '.join(target_audience)}
|
||||
|
||||
Brand Voice:
|
||||
{brand_voice}
|
||||
|
||||
Generate a comprehensive LinkedIn company profile with the following sections:
|
||||
1. Company Overview
|
||||
2. Mission Statement
|
||||
3. Value Proposition
|
||||
4. Industry Expertise
|
||||
5. Company Culture
|
||||
6. Products/Services Overview
|
||||
|
||||
Ensure the content:
|
||||
- Maintains the specified brand voice
|
||||
- Targets the identified audience segments
|
||||
- Highlights key products/services
|
||||
- Optimizes for LinkedIn's algorithm
|
||||
- Includes relevant industry keywords
|
||||
- Maintains professional tone
|
||||
"""
|
||||
|
||||
# Define the JSON structure for the response
|
||||
json_struct = {
|
||||
"company_overview": "string",
|
||||
"mission_statement": "string",
|
||||
"value_proposition": "string",
|
||||
"industry_expertise": "string",
|
||||
"company_culture": "string",
|
||||
"products_services_overview": "string",
|
||||
"recommended_hashtags": ["string"],
|
||||
"seo_keywords": ["string"]
|
||||
}
|
||||
|
||||
# Generate the optimized profile content
|
||||
response = await llm_text_gen(
|
||||
prompt=prompt,
|
||||
json_struct=json_struct,
|
||||
temperature=0.7
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error optimizing company profile: {str(e)}")
|
||||
raise
|
||||
|
||||
async def generate_company_update(
|
||||
self,
|
||||
update_type: str,
|
||||
topic: str,
|
||||
target_audience: Optional[List[str]] = None,
|
||||
include_hashtags: bool = True,
|
||||
include_cta: bool = True
|
||||
) -> Dict[str, str]:
|
||||
"""
|
||||
Generate a company update post for LinkedIn.
|
||||
|
||||
Args:
|
||||
update_type: Type of update (product_launch, milestone, news, etc.)
|
||||
topic: Main topic or focus of the update
|
||||
target_audience: Optional list of target audience segments
|
||||
include_hashtags: Whether to include hashtags
|
||||
include_cta: Whether to include a call-to-action
|
||||
|
||||
Returns:
|
||||
Dict containing the generated update content
|
||||
"""
|
||||
try:
|
||||
# Use company info if target audience not specified
|
||||
if not target_audience:
|
||||
target_audience = self.company_info.get("target_audience", [])
|
||||
|
||||
# Create the prompt for update generation
|
||||
prompt = f"""
|
||||
Generate a LinkedIn company update post for {self.company_info['name']} about {topic}.
|
||||
|
||||
Update Type: {update_type}
|
||||
Target Audience: {', '.join(target_audience)}
|
||||
Brand Voice: {self.company_info['brand_voice']}
|
||||
|
||||
The post should:
|
||||
- Be engaging and professional
|
||||
- Include relevant industry context
|
||||
- Highlight the company's expertise
|
||||
- Drive meaningful engagement
|
||||
- Be optimized for LinkedIn's algorithm
|
||||
"""
|
||||
|
||||
if include_hashtags:
|
||||
prompt += "\n- Include 3-5 relevant hashtags"
|
||||
|
||||
if include_cta:
|
||||
prompt += "\n- Include a clear call-to-action"
|
||||
|
||||
# Define the JSON structure for the response
|
||||
json_struct = {
|
||||
"post_content": "string",
|
||||
"hashtags": ["string"],
|
||||
"call_to_action": "string",
|
||||
"suggested_image_prompt": "string",
|
||||
"engagement_tips": ["string"]
|
||||
}
|
||||
|
||||
# Generate the update content
|
||||
response = await llm_text_gen(
|
||||
prompt=prompt,
|
||||
json_struct=json_struct,
|
||||
temperature=0.7
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating company update: {str(e)}")
|
||||
raise
|
||||
|
||||
async def generate_employee_spotlight(
|
||||
self,
|
||||
employee_name: str,
|
||||
role: str,
|
||||
achievements: List[str],
|
||||
spotlight_type: str = "general"
|
||||
) -> Dict[str, str]:
|
||||
"""
|
||||
Generate an employee spotlight post for LinkedIn.
|
||||
|
||||
Args:
|
||||
employee_name: Name of the employee
|
||||
role: Employee's role
|
||||
achievements: List of key achievements
|
||||
spotlight_type: Type of spotlight (general, leadership, innovation, etc.)
|
||||
|
||||
Returns:
|
||||
Dict containing the generated spotlight content
|
||||
"""
|
||||
try:
|
||||
# Create the prompt for spotlight generation
|
||||
prompt = f"""
|
||||
Generate a LinkedIn employee spotlight post for {employee_name}, {role} at {self.company_info['name']}.
|
||||
|
||||
Spotlight Type: {spotlight_type}
|
||||
Key Achievements:
|
||||
{chr(10).join(f'- {achievement}' for achievement in achievements)}
|
||||
|
||||
Company Context:
|
||||
Industry: {self.company_info['industry']}
|
||||
Brand Voice: {self.company_info['brand_voice']}
|
||||
|
||||
The post should:
|
||||
- Highlight the employee's contributions
|
||||
- Showcase company culture
|
||||
- Be engaging and professional
|
||||
- Include relevant industry context
|
||||
- Drive meaningful engagement
|
||||
"""
|
||||
|
||||
# Define the JSON structure for the response
|
||||
json_struct = {
|
||||
"spotlight_content": "string",
|
||||
"hashtags": ["string"],
|
||||
"call_to_action": "string",
|
||||
"suggested_image_prompt": "string",
|
||||
"engagement_tips": ["string"]
|
||||
}
|
||||
|
||||
# Generate the spotlight content
|
||||
response = await llm_text_gen(
|
||||
prompt=prompt,
|
||||
json_struct=json_struct,
|
||||
temperature=0.7
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating employee spotlight: {str(e)}")
|
||||
raise
|
||||
|
||||
async def generate_industry_content(
|
||||
self,
|
||||
content_type: str,
|
||||
topic: str,
|
||||
target_audience: Optional[List[str]] = None
|
||||
) -> Dict[str, str]:
|
||||
"""
|
||||
Generate industry-focused content for LinkedIn.
|
||||
|
||||
Args:
|
||||
content_type: Type of content (insight, trend, analysis, etc.)
|
||||
topic: Main topic or focus
|
||||
target_audience: Optional list of target audience segments
|
||||
|
||||
Returns:
|
||||
Dict containing the generated content
|
||||
"""
|
||||
try:
|
||||
# Use company info if target audience not specified
|
||||
if not target_audience:
|
||||
target_audience = self.company_info.get("target_audience", [])
|
||||
|
||||
# Research industry trends and insights
|
||||
research_results = await do_tavily_ai_search(
|
||||
query=f"{topic} in {self.company_info['industry']} industry trends insights",
|
||||
search_depth="advanced"
|
||||
)
|
||||
|
||||
# Create the prompt for content generation
|
||||
prompt = f"""
|
||||
Generate LinkedIn industry content for {self.company_info['name']} about {topic}.
|
||||
|
||||
Content Type: {content_type}
|
||||
Target Audience: {', '.join(target_audience)}
|
||||
Industry: {self.company_info['industry']}
|
||||
Brand Voice: {self.company_info['brand_voice']}
|
||||
|
||||
Research Context:
|
||||
{research_results}
|
||||
|
||||
The content should:
|
||||
- Provide valuable industry insights
|
||||
- Position the company as a thought leader
|
||||
- Be data-driven and professional
|
||||
- Drive meaningful engagement
|
||||
- Include relevant examples and context
|
||||
"""
|
||||
|
||||
# Define the JSON structure for the response
|
||||
json_struct = {
|
||||
"content": "string",
|
||||
"hashtags": ["string"],
|
||||
"call_to_action": "string",
|
||||
"suggested_image_prompt": "string",
|
||||
"engagement_tips": ["string"],
|
||||
"key_insights": ["string"]
|
||||
}
|
||||
|
||||
# Generate the industry content
|
||||
response = await llm_text_gen(
|
||||
prompt=prompt,
|
||||
json_struct=json_struct,
|
||||
temperature=0.7
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating industry content: {str(e)}")
|
||||
raise
|
||||
@@ -1,321 +0,0 @@
|
||||
"""
|
||||
LinkedIn Company Page Generator UI
|
||||
|
||||
This module provides the Streamlit UI for the LinkedIn Company Page Generator.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import json
|
||||
from typing import Dict, List, Optional
|
||||
from loguru import logger
|
||||
|
||||
from .linkedin_company_page_generator import LinkedInCompanyPageGenerator
|
||||
|
||||
async def linkedin_company_page_generator_ui():
|
||||
"""Main UI function for the LinkedIn Company Page Generator."""
|
||||
|
||||
st.title("🏢 LinkedIn Company Page Content Generator")
|
||||
st.markdown("""
|
||||
Create engaging and professional content for your LinkedIn company page.
|
||||
This tool helps you generate optimized company profiles, updates, employee spotlights, and industry content.
|
||||
""")
|
||||
|
||||
# Initialize the generator
|
||||
generator = LinkedInCompanyPageGenerator()
|
||||
|
||||
# Create tabs for different content types
|
||||
tab1, tab2, tab3, tab4 = st.tabs([
|
||||
"Company Profile",
|
||||
"Company Updates",
|
||||
"Employee Spotlights",
|
||||
"Industry Content"
|
||||
])
|
||||
|
||||
# Company Profile Tab
|
||||
with tab1:
|
||||
st.header("Optimize Your Company Profile")
|
||||
st.markdown("Generate an optimized LinkedIn company profile that highlights your brand and drives engagement.")
|
||||
|
||||
# Company Information Form
|
||||
with st.form("company_profile_form"):
|
||||
company_name = st.text_input("Company Name", placeholder="Enter your company name")
|
||||
industry = st.text_input("Industry", placeholder="e.g., Technology, Healthcare, Finance")
|
||||
company_size = st.selectbox(
|
||||
"Company Size",
|
||||
["1-10", "11-50", "51-200", "201-500", "501-1000", "1000+"]
|
||||
)
|
||||
target_audience = st.multiselect(
|
||||
"Target Audience",
|
||||
["Job Seekers", "Customers", "Partners", "Investors", "Industry Professionals", "Media"],
|
||||
default=["Job Seekers", "Customers"]
|
||||
)
|
||||
brand_voice = st.selectbox(
|
||||
"Brand Voice",
|
||||
["Professional", "Innovative", "Friendly", "Authoritative", "Casual", "Technical"]
|
||||
)
|
||||
key_products = st.text_area(
|
||||
"Key Products/Services",
|
||||
placeholder="Enter your key products or services, one per line"
|
||||
).split("\n")
|
||||
company_description = st.text_area(
|
||||
"Current Company Description",
|
||||
placeholder="Enter your current company description"
|
||||
)
|
||||
|
||||
submit_profile = st.form_submit_button("Generate Optimized Profile")
|
||||
|
||||
if submit_profile:
|
||||
if not all([company_name, industry, target_audience, brand_voice, key_products, company_description]):
|
||||
st.error("Please fill in all required fields.")
|
||||
else:
|
||||
with st.spinner("Generating optimized company profile..."):
|
||||
try:
|
||||
profile_content = await generator.optimize_company_profile(
|
||||
company_name=company_name,
|
||||
industry=industry,
|
||||
target_audience=target_audience,
|
||||
brand_voice=brand_voice,
|
||||
key_products=key_products,
|
||||
company_size=company_size,
|
||||
company_description=company_description
|
||||
)
|
||||
|
||||
# Display the results
|
||||
st.success("Profile generated successfully!")
|
||||
|
||||
# Company Overview
|
||||
st.subheader("Company Overview")
|
||||
st.write(profile_content["company_overview"])
|
||||
|
||||
# Mission Statement
|
||||
st.subheader("Mission Statement")
|
||||
st.write(profile_content["mission_statement"])
|
||||
|
||||
# Value Proposition
|
||||
st.subheader("Value Proposition")
|
||||
st.write(profile_content["value_proposition"])
|
||||
|
||||
# Industry Expertise
|
||||
st.subheader("Industry Expertise")
|
||||
st.write(profile_content["industry_expertise"])
|
||||
|
||||
# Company Culture
|
||||
st.subheader("Company Culture")
|
||||
st.write(profile_content["company_culture"])
|
||||
|
||||
# Products/Services Overview
|
||||
st.subheader("Products/Services Overview")
|
||||
st.write(profile_content["products_services_overview"])
|
||||
|
||||
# SEO Keywords
|
||||
st.subheader("Recommended SEO Keywords")
|
||||
st.write(", ".join(profile_content["seo_keywords"]))
|
||||
|
||||
# Hashtags
|
||||
st.subheader("Recommended Hashtags")
|
||||
st.write(" ".join([f"#{tag}" for tag in profile_content["recommended_hashtags"]]))
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Error generating profile: {str(e)}")
|
||||
|
||||
# Company Updates Tab
|
||||
with tab2:
|
||||
st.header("Generate Company Updates")
|
||||
st.markdown("Create engaging company updates for your LinkedIn page.")
|
||||
|
||||
# Update Generation Form
|
||||
with st.form("company_update_form"):
|
||||
update_type = st.selectbox(
|
||||
"Update Type",
|
||||
["Product Launch", "Company Milestone", "Industry News", "Company News", "Event Announcement"]
|
||||
)
|
||||
topic = st.text_input("Topic", placeholder="Enter the main topic of your update")
|
||||
target_audience = st.multiselect(
|
||||
"Target Audience",
|
||||
["Job Seekers", "Customers", "Partners", "Investors", "Industry Professionals", "Media"],
|
||||
default=["Customers", "Industry Professionals"]
|
||||
)
|
||||
include_hashtags = st.checkbox("Include Hashtags", value=True)
|
||||
include_cta = st.checkbox("Include Call-to-Action", value=True)
|
||||
|
||||
submit_update = st.form_submit_button("Generate Update")
|
||||
|
||||
if submit_update:
|
||||
if not topic:
|
||||
st.error("Please enter a topic for your update.")
|
||||
else:
|
||||
with st.spinner("Generating company update..."):
|
||||
try:
|
||||
update_content = await generator.generate_company_update(
|
||||
update_type=update_type,
|
||||
topic=topic,
|
||||
target_audience=target_audience,
|
||||
include_hashtags=include_hashtags,
|
||||
include_cta=include_cta
|
||||
)
|
||||
|
||||
# Display the results
|
||||
st.success("Update generated successfully!")
|
||||
|
||||
# Post Content
|
||||
st.subheader("Generated Post")
|
||||
st.write(update_content["post_content"])
|
||||
|
||||
# Hashtags
|
||||
if include_hashtags:
|
||||
st.subheader("Recommended Hashtags")
|
||||
st.write(" ".join([f"#{tag}" for tag in update_content["hashtags"]]))
|
||||
|
||||
# Call-to-Action
|
||||
if include_cta:
|
||||
st.subheader("Call-to-Action")
|
||||
st.write(update_content["call_to_action"])
|
||||
|
||||
# Engagement Tips
|
||||
st.subheader("Engagement Tips")
|
||||
for tip in update_content["engagement_tips"]:
|
||||
st.write(f"• {tip}")
|
||||
|
||||
# Image Prompt
|
||||
st.subheader("Suggested Image Prompt")
|
||||
st.write(update_content["suggested_image_prompt"])
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Error generating update: {str(e)}")
|
||||
|
||||
# Employee Spotlights Tab
|
||||
with tab3:
|
||||
st.header("Generate Employee Spotlights")
|
||||
st.markdown("Create engaging employee spotlight posts to showcase your team.")
|
||||
|
||||
# Spotlight Generation Form
|
||||
with st.form("employee_spotlight_form"):
|
||||
employee_name = st.text_input("Employee Name", placeholder="Enter employee's name")
|
||||
role = st.text_input("Role", placeholder="Enter employee's role")
|
||||
achievements = st.text_area(
|
||||
"Key Achievements",
|
||||
placeholder="Enter key achievements, one per line"
|
||||
).split("\n")
|
||||
spotlight_type = st.selectbox(
|
||||
"Spotlight Type",
|
||||
["General", "Leadership", "Innovation", "Team Player", "Career Growth"]
|
||||
)
|
||||
|
||||
submit_spotlight = st.form_submit_button("Generate Spotlight")
|
||||
|
||||
if submit_spotlight:
|
||||
if not all([employee_name, role, achievements]):
|
||||
st.error("Please fill in all required fields.")
|
||||
else:
|
||||
with st.spinner("Generating employee spotlight..."):
|
||||
try:
|
||||
spotlight_content = await generator.generate_employee_spotlight(
|
||||
employee_name=employee_name,
|
||||
role=role,
|
||||
achievements=achievements,
|
||||
spotlight_type=spotlight_type
|
||||
)
|
||||
|
||||
# Display the results
|
||||
st.success("Spotlight generated successfully!")
|
||||
|
||||
# Spotlight Content
|
||||
st.subheader("Generated Spotlight")
|
||||
st.write(spotlight_content["spotlight_content"])
|
||||
|
||||
# Hashtags
|
||||
st.subheader("Recommended Hashtags")
|
||||
st.write(" ".join([f"#{tag}" for tag in spotlight_content["hashtags"]]))
|
||||
|
||||
# Call-to-Action
|
||||
st.subheader("Call-to-Action")
|
||||
st.write(spotlight_content["call_to_action"])
|
||||
|
||||
# Engagement Tips
|
||||
st.subheader("Engagement Tips")
|
||||
for tip in spotlight_content["engagement_tips"]:
|
||||
st.write(f"• {tip}")
|
||||
|
||||
# Image Prompt
|
||||
st.subheader("Suggested Image Prompt")
|
||||
st.write(spotlight_content["suggested_image_prompt"])
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Error generating spotlight: {str(e)}")
|
||||
|
||||
# Industry Content Tab
|
||||
with tab4:
|
||||
st.header("Generate Industry Content")
|
||||
st.markdown("Create thought leadership content to position your company as an industry expert.")
|
||||
|
||||
# Industry Content Generation Form
|
||||
with st.form("industry_content_form"):
|
||||
content_type = st.selectbox(
|
||||
"Content Type",
|
||||
["Industry Insight", "Trend Analysis", "Best Practices", "Case Study", "Market Update"]
|
||||
)
|
||||
topic = st.text_input("Topic", placeholder="Enter the main topic of your content")
|
||||
target_audience = st.multiselect(
|
||||
"Target Audience",
|
||||
["Job Seekers", "Customers", "Partners", "Investors", "Industry Professionals", "Media"],
|
||||
default=["Industry Professionals", "Customers"]
|
||||
)
|
||||
|
||||
submit_content = st.form_submit_button("Generate Content")
|
||||
|
||||
if submit_content:
|
||||
if not topic:
|
||||
st.error("Please enter a topic for your content.")
|
||||
else:
|
||||
with st.spinner("Generating industry content..."):
|
||||
try:
|
||||
content = await generator.generate_industry_content(
|
||||
content_type=content_type,
|
||||
topic=topic,
|
||||
target_audience=target_audience
|
||||
)
|
||||
|
||||
# Display the results
|
||||
st.success("Content generated successfully!")
|
||||
|
||||
# Content
|
||||
st.subheader("Generated Content")
|
||||
st.write(content["content"])
|
||||
|
||||
# Key Insights
|
||||
st.subheader("Key Insights")
|
||||
for insight in content["key_insights"]:
|
||||
st.write(f"• {insight}")
|
||||
|
||||
# Hashtags
|
||||
st.subheader("Recommended Hashtags")
|
||||
st.write(" ".join([f"#{tag}" for tag in content["hashtags"]]))
|
||||
|
||||
# Call-to-Action
|
||||
st.subheader("Call-to-Action")
|
||||
st.write(content["call_to_action"])
|
||||
|
||||
# Engagement Tips
|
||||
st.subheader("Engagement Tips")
|
||||
for tip in content["engagement_tips"]:
|
||||
st.write(f"• {tip}")
|
||||
|
||||
# Image Prompt
|
||||
st.subheader("Suggested Image Prompt")
|
||||
st.write(content["suggested_image_prompt"])
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Error generating content: {str(e)}")
|
||||
|
||||
# Add a footer with tips
|
||||
st.markdown("---")
|
||||
st.markdown("""
|
||||
### Tips for Effective LinkedIn Company Page Content:
|
||||
|
||||
- **Consistency**: Maintain a consistent posting schedule and brand voice
|
||||
- **Engagement**: Encourage comments and discussions on your posts
|
||||
- **Visuals**: Use high-quality images and videos to increase engagement
|
||||
- **Hashtags**: Use relevant industry hashtags to increase visibility
|
||||
- **Analytics**: Monitor your content performance and adjust your strategy
|
||||
- **Employee Advocacy**: Encourage employees to share and engage with company content
|
||||
""")
|
||||
@@ -1,216 +0,0 @@
|
||||
# LinkedIn Poll Generator
|
||||
|
||||
## Overview
|
||||
|
||||
The LinkedIn Poll Generator is an AI-powered tool designed to help professionals create engaging, data-driven polls for LinkedIn. This tool leverages advanced AI to generate poll questions, options, and engagement predictions, helping users gather valuable insights from their professional network.
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Poll Creation
|
||||
- **Multiple Poll Types**: Create various types of polls including:
|
||||
- Multiple Choice (2-4 options)
|
||||
- Yes/No
|
||||
- Rating Scale (1-5)
|
||||
- Ranking (order items by preference)
|
||||
- Open-ended (with suggested responses)
|
||||
- **Customizable Tone**: Generate polls with different tones (professional, casual, authoritative, conversational, thoughtful)
|
||||
- **Industry-Specific Content**: Tailor polls to specific industries and professional contexts
|
||||
|
||||
### 2. Research Integration
|
||||
- **Multi-Source Research**: Gather insights from multiple search engines:
|
||||
- Metaphor (neural search)
|
||||
- Google SERP
|
||||
- Tavily AI
|
||||
- **Insight Extraction**: Automatically extract key insights and trends from research
|
||||
- **Question Generation**: Generate potential poll questions based on research findings
|
||||
|
||||
### 3. Engagement Prediction
|
||||
- **Response Prediction**: Forecast expected engagement levels (low, medium, high, viral)
|
||||
- **Comment & Share Likelihood**: Predict the likelihood of comments and shares
|
||||
- **Response Distribution**: Estimate the expected distribution of responses across options
|
||||
- **Insight Generation**: Identify potential insights that could be gained from the poll
|
||||
|
||||
### 4. Optimization
|
||||
- **Question Improvements**: Get suggestions for improving poll question wording and clarity
|
||||
- **Option Improvements**: Receive recommendations for enhancing poll options
|
||||
- **Timing Suggestions**: Learn the optimal days and times to post your poll
|
||||
- **Audience Targeting**: Identify the most relevant audience segments for your poll
|
||||
- **Hashtag Recommendations**: Get industry-specific hashtag suggestions
|
||||
|
||||
### 5. Follow-up Content
|
||||
- **Post Templates**: Receive templates for sharing poll results
|
||||
- **Visual Suggestions**: Get recommendations for visualizing poll results
|
||||
- **Next Poll Ideas**: Discover ideas for follow-up polls that build on previous insights
|
||||
- **Data Visualization**: Receive suggestions for effective data visualization of poll results
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Workflow
|
||||
|
||||
1. **Select Topic and Industry**: Enter your poll topic and target industry
|
||||
2. **Choose Poll Type**: Select the type of poll you want to create
|
||||
3. **Set Tone**: Choose the tone for your poll (professional, casual, etc.)
|
||||
4. **Research Topic**: Gather insights about your topic (optional)
|
||||
5. **Generate Poll**: Create your poll with AI-generated questions and options
|
||||
6. **Review Predictions**: See engagement predictions and response distribution
|
||||
7. **Optimize**: Get suggestions for improving your poll
|
||||
8. **Plan Follow-up**: Receive templates and ideas for sharing results
|
||||
|
||||
### Advanced Features
|
||||
|
||||
#### Research Integration
|
||||
- Use the "Research Topic" button to gather insights before creating your poll
|
||||
- View key insights, emerging trends, and potential questions based on research
|
||||
- Use research findings to inform your poll creation
|
||||
|
||||
#### Engagement Prediction
|
||||
- View predicted engagement levels before posting
|
||||
- See expected response distribution across options
|
||||
- Identify potential insights that could be gained
|
||||
|
||||
#### Optimization
|
||||
- Get suggestions for improving your poll question and options
|
||||
- Learn the best times to post for maximum engagement
|
||||
- Identify the most relevant audience segments
|
||||
- Receive hashtag recommendations
|
||||
|
||||
#### Follow-up Content
|
||||
- Get templates for sharing poll results
|
||||
- Receive visual content suggestions
|
||||
- Discover ideas for follow-up polls
|
||||
- Get data visualization recommendations
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Creating Effective Polls
|
||||
|
||||
1. **Be Specific**: Ask clear, specific questions that your audience can answer confidently
|
||||
2. **Keep it Concise**: Use concise language for both questions and options
|
||||
3. **Avoid Bias**: Ensure your poll doesn't lead respondents toward a particular answer
|
||||
4. **Use Appropriate Options**: Make sure options are mutually exclusive and collectively exhaustive
|
||||
5. **Consider Timing**: Post polls at times when your audience is most active
|
||||
6. **Follow Up**: Share results and insights after the poll closes
|
||||
|
||||
### Maximizing Engagement
|
||||
|
||||
1. **Target Your Audience**: Ensure your poll is relevant to your specific audience
|
||||
2. **Use Visuals**: Include relevant images or graphics with your poll
|
||||
3. **Add Context**: Provide brief context or explanation for your poll
|
||||
4. **Engage with Comments**: Respond to comments to encourage discussion
|
||||
5. **Share Results**: Follow up with a post sharing the results and insights
|
||||
6. **Use Hashtags**: Include relevant hashtags to increase visibility
|
||||
|
||||
### Industry-Specific Tips
|
||||
|
||||
#### Technology
|
||||
- Focus on emerging trends and technologies
|
||||
- Ask about adoption rates and preferences
|
||||
- Include technical and non-technical options
|
||||
|
||||
#### Healthcare
|
||||
- Address current healthcare challenges
|
||||
- Ask about patient experiences and preferences
|
||||
- Include options that reflect different stakeholder perspectives
|
||||
|
||||
#### Finance
|
||||
- Focus on investment preferences and strategies
|
||||
- Ask about financial planning and management
|
||||
- Include options that reflect different risk tolerances
|
||||
|
||||
#### Marketing
|
||||
- Address current marketing trends and challenges
|
||||
- Ask about content preferences and consumption habits
|
||||
- Include options that reflect different marketing approaches
|
||||
|
||||
#### Education
|
||||
- Focus on learning preferences and methods
|
||||
- Ask about educational technology and tools
|
||||
- Include options that reflect different learning styles
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Dependencies
|
||||
- Streamlit: For the user interface
|
||||
- Plotly: For data visualization
|
||||
- Loguru: For logging
|
||||
- GPT Providers: For AI text generation
|
||||
- Web Research Tools: For gathering insights
|
||||
|
||||
### Architecture
|
||||
The LinkedIn Poll Generator consists of:
|
||||
- `LinkedInPollGenerator` class: Core functionality for poll generation
|
||||
- `linkedin_poll_generator_ui` function: Streamlit UI implementation
|
||||
|
||||
### Integration
|
||||
The Poll Generator is integrated into the LinkedIn AI Writer suite and can be accessed through the main LinkedIn AI Writer interface.
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Technology Industry Poll
|
||||
**Question**: "What emerging technology will have the biggest impact on business in 2023?"
|
||||
**Options**:
|
||||
1. Artificial Intelligence
|
||||
2. Blockchain
|
||||
3. Quantum Computing
|
||||
4. Extended Reality (XR)
|
||||
|
||||
### Example 2: Healthcare Industry Poll
|
||||
**Question**: "What is the most significant barrier to telehealth adoption?"
|
||||
**Options**:
|
||||
1. Technical issues
|
||||
2. Privacy concerns
|
||||
3. Lack of insurance coverage
|
||||
4. Patient preference for in-person care
|
||||
|
||||
### Example 3: Finance Industry Poll
|
||||
**Question**: "What investment strategy are you most likely to pursue in a volatile market?"
|
||||
**Options**:
|
||||
1. Increase cash reserves
|
||||
2. Focus on dividend stocks
|
||||
3. Invest in defensive sectors
|
||||
4. Look for opportunistic buys
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Research Not Returning Results**
|
||||
- Try a different search engine
|
||||
- Use more specific search terms
|
||||
- Check your internet connection
|
||||
|
||||
2. **Low Engagement Predictions**
|
||||
- Review question wording for clarity
|
||||
- Ensure options are relevant and distinct
|
||||
- Consider targeting a more specific audience
|
||||
|
||||
3. **JSON Parsing Errors**
|
||||
- This is typically handled automatically by the system
|
||||
- If persistent, try regenerating the poll
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- **A/B Testing**: Compare different poll versions
|
||||
- **Historical Data Analysis**: Learn from past poll performance
|
||||
- **Competitor Poll Analysis**: Analyze successful polls in your industry
|
||||
- **Advanced Visualization**: More sophisticated data visualization options
|
||||
- **Integration with LinkedIn API**: Direct posting to LinkedIn
|
||||
- **Poll Templates**: Pre-built templates for common use cases
|
||||
- **Multi-language Support**: Generate polls in multiple languages
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions to the LinkedIn Poll Generator are welcome! Please follow these steps:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
||||
## Contact
|
||||
|
||||
For questions or feedback about the LinkedIn Poll Generator, please contact the development team.
|
||||
@@ -1,10 +0,0 @@
|
||||
"""
|
||||
LinkedIn Poll Generator Module
|
||||
|
||||
This module provides functionality for generating LinkedIn polls with
|
||||
AI-powered content and engagement optimization.
|
||||
"""
|
||||
|
||||
from .linkedin_poll_generator import LinkedInPollGenerator, linkedin_poll_generator_ui
|
||||
|
||||
__all__ = ["LinkedInPollGenerator", "linkedin_poll_generator_ui"]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,291 +0,0 @@
|
||||
# LinkedIn Post Generator 🚀
|
||||
|
||||
An AI-powered tool designed for LinkedIn professionals to create engaging, research-backed posts that drive engagement and establish thought leadership.
|
||||
|
||||
## ✨ Key Features
|
||||
|
||||
### Content Creation
|
||||
- **AI-Powered Research**: Multi-source research integration (Metaphor, Google, Tavily)
|
||||
- **Smart Content Generation**: Industry-specific, engagement-optimized content
|
||||
- **Hashtag Optimization**: Data-driven hashtag suggestions
|
||||
- **Visual Content**: AI-generated images with professional aesthetics
|
||||
- **Engagement Predictions**: AI-powered performance analytics
|
||||
- **Poll Creation**: Interactive audience engagement tools
|
||||
- **Posting Time Optimization**: Industry-specific timing recommendations
|
||||
|
||||
### Research Excellence
|
||||
- **Triple-Engine Research**:
|
||||
- 🔍 Metaphor AI: Deep industry insights
|
||||
- 🌐 Google Search: Comprehensive coverage
|
||||
- 🤖 Tavily AI: Focused research
|
||||
- **Real-Time Data**: Current trends and statistics
|
||||
- **Expert Insights**: Professional quotes and perspectives
|
||||
- **Fact Verification**: Web-researched authenticity
|
||||
|
||||
### Visual Enhancement
|
||||
- **Professional Imagery**: AI-generated visuals
|
||||
- **Custom Prompts**: Tailored image generation
|
||||
- **Style Customization**: Brand-aligned visuals
|
||||
- **Multiple Formats**: Various visual content options
|
||||
|
||||
## 🎯 Getting Started
|
||||
|
||||
### 1. Post Creation Process
|
||||
|
||||
#### Initial Setup
|
||||
- Choose your topic
|
||||
- Select your industry
|
||||
- Pick your writing tone:
|
||||
- Professional
|
||||
- Casual
|
||||
- Informative
|
||||
- Inspirational
|
||||
|
||||
#### Research Configuration
|
||||
Select your preferred research source:
|
||||
- Metaphor AI: Comprehensive insights
|
||||
- Google Search: Wide coverage
|
||||
- Tavily AI: Focused research
|
||||
|
||||
#### Content Options
|
||||
Customize your post with:
|
||||
- ✅ Hashtags
|
||||
- 🖼️ Visual content
|
||||
- 📊 Polls
|
||||
- ⏰ Posting time recommendations
|
||||
|
||||
### 2. Post Generation and Preview
|
||||
|
||||
#### Content Tab
|
||||
- View generated post
|
||||
- Edit content directly
|
||||
- Copy to clipboard
|
||||
- Download as text
|
||||
|
||||
#### Analytics Tab
|
||||
- Engagement predictions
|
||||
- Optimal posting times
|
||||
- Performance metrics
|
||||
- Audience insights
|
||||
|
||||
#### Visual Content Tab
|
||||
- Preview generated images
|
||||
- Edit image prompts
|
||||
- Generate alternatives
|
||||
- Download visuals
|
||||
|
||||
## 💡 Best Practices
|
||||
|
||||
### 1. Content Strategy
|
||||
- **Topic Selection**
|
||||
- Industry relevance
|
||||
- Current trends
|
||||
- Audience interest
|
||||
- Professional expertise
|
||||
|
||||
- **Content Structure**
|
||||
- Strong hook
|
||||
- Value proposition
|
||||
- Supporting points
|
||||
- Clear CTA
|
||||
|
||||
### 2. Engagement Optimization
|
||||
- **Hashtag Strategy**
|
||||
- Industry-specific tags
|
||||
- Trending topics
|
||||
- Balanced visibility
|
||||
- Professional relevance
|
||||
|
||||
- **Visual Impact**
|
||||
- Professional imagery
|
||||
- Brand consistency
|
||||
- Clear messaging
|
||||
- Mobile optimization
|
||||
|
||||
### 3. Timing and Frequency
|
||||
- **Posting Schedule**
|
||||
- Industry peak times
|
||||
- Audience activity
|
||||
- Time zone consideration
|
||||
- Consistency
|
||||
|
||||
## 📊 Content Types
|
||||
|
||||
### 1. Thought Leadership
|
||||
- Industry insights
|
||||
- Expert opinions
|
||||
- Trend analysis
|
||||
- Future predictions
|
||||
|
||||
### 2. Professional Tips
|
||||
- Best practices
|
||||
- How-to guides
|
||||
- Career advice
|
||||
- Industry hacks
|
||||
|
||||
### 3. Success Stories
|
||||
- Case studies
|
||||
- Achievements
|
||||
- Lessons learned
|
||||
- Professional growth
|
||||
|
||||
### 4. Industry Updates
|
||||
- Market trends
|
||||
- News analysis
|
||||
- Technology updates
|
||||
- Professional developments
|
||||
|
||||
## 🎨 Visual Guidelines
|
||||
|
||||
### Image Generation
|
||||
- **Style Options**
|
||||
- Professional photography
|
||||
- Abstract concepts
|
||||
- Data visualization
|
||||
- Brand elements
|
||||
|
||||
- **Customization**
|
||||
- Color schemes
|
||||
- Text overlays
|
||||
- Visual hierarchy
|
||||
- Professional aesthetics
|
||||
|
||||
### Brand Alignment
|
||||
- **Visual Identity**
|
||||
- Consistent style
|
||||
- Professional tone
|
||||
- Brand colors
|
||||
- Quality standards
|
||||
|
||||
## 📱 Platform Optimization
|
||||
|
||||
### Mobile Experience
|
||||
- Text readability
|
||||
- Image scaling
|
||||
- Content preview
|
||||
- Performance check
|
||||
|
||||
### Cross-Platform
|
||||
- LinkedIn app compatibility
|
||||
- Web version optimization
|
||||
- Image resolution
|
||||
- Loading speed
|
||||
|
||||
## 💪 Engagement Strategies
|
||||
|
||||
### 1. Interactive Elements
|
||||
- **Polls**
|
||||
- Topic relevance
|
||||
- Response options
|
||||
- Duration setting
|
||||
- Follow-up strategy
|
||||
|
||||
- **Call-to-Action**
|
||||
- Clear direction
|
||||
- Value proposition
|
||||
- Professional tone
|
||||
- Measurable goals
|
||||
|
||||
### 2. Hashtag Optimization
|
||||
- **Selection Criteria**
|
||||
- Relevance
|
||||
- Reach
|
||||
- Professional context
|
||||
- Trending topics
|
||||
|
||||
### 3. Timing Strategy
|
||||
- **Post Scheduling**
|
||||
- Peak engagement times
|
||||
- Industry patterns
|
||||
- Audience availability
|
||||
- Global considerations
|
||||
|
||||
## 🛠️ Technical Features
|
||||
|
||||
### Performance
|
||||
- Fast generation
|
||||
- Real-time preview
|
||||
- Smooth editing
|
||||
- Quick updates
|
||||
|
||||
### Integration
|
||||
- Browser compatibility
|
||||
- API connections
|
||||
- Data security
|
||||
- Regular updates
|
||||
|
||||
## 📈 Analytics and Insights
|
||||
|
||||
### Engagement Metrics
|
||||
- Like predictions
|
||||
- Comment estimates
|
||||
- Share potential
|
||||
- Profile visit forecasts
|
||||
|
||||
### Performance Tracking
|
||||
- Engagement rates
|
||||
- Reach estimates
|
||||
- Audience response
|
||||
- Content effectiveness
|
||||
|
||||
## 🔄 Workflow Integration
|
||||
|
||||
### 1. Content Planning
|
||||
- Topic research
|
||||
- Content creation
|
||||
- Visual design
|
||||
- Optimization
|
||||
|
||||
### 2. Quality Assurance
|
||||
- Content review
|
||||
- Image verification
|
||||
- Hashtag check
|
||||
- Timing optimization
|
||||
|
||||
### 3. Publication
|
||||
- Final preview
|
||||
- Platform check
|
||||
- Scheduling
|
||||
- Performance monitoring
|
||||
|
||||
## 🎯 Success Metrics
|
||||
|
||||
### Engagement Goals
|
||||
- Professional visibility
|
||||
- Audience growth
|
||||
- Industry authority
|
||||
- Network expansion
|
||||
|
||||
### Content Quality
|
||||
- Professional standards
|
||||
- Industry relevance
|
||||
- Value delivery
|
||||
- Brand alignment
|
||||
|
||||
## 🔍 Support and Resources
|
||||
|
||||
### Help Center
|
||||
- User guides
|
||||
- Best practices
|
||||
- FAQs
|
||||
- Technical support
|
||||
|
||||
### Updates
|
||||
- Feature releases
|
||||
- Performance improvements
|
||||
- Platform updates
|
||||
- Content tips
|
||||
|
||||
---
|
||||
|
||||
Transform your LinkedIn presence with professional, engaging posts that drive results! 🚀
|
||||
|
||||
### Quick Tips
|
||||
- Keep posts between 800-1200 characters
|
||||
- Include 3-5 relevant hashtags
|
||||
- Add professional visuals
|
||||
- Engage with comments
|
||||
- Monitor performance
|
||||
- Stay consistent
|
||||
|
||||
Start creating impactful LinkedIn posts that establish your professional authority! 💫
|
||||
@@ -1,10 +0,0 @@
|
||||
"""
|
||||
LinkedIn Post Generator Package
|
||||
|
||||
This package provides functionality for generating LinkedIn posts with research-backed content,
|
||||
optimized hashtags, and engagement predictions.
|
||||
"""
|
||||
|
||||
from .linkedin_post_generator import linkedin_post_generator_ui, LinkedInPostGenerator
|
||||
|
||||
__all__ = ['linkedin_post_generator_ui', 'LinkedInPostGenerator']
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,184 +0,0 @@
|
||||
# LinkedIn Profile Optimizer
|
||||
|
||||
## Overview
|
||||
The LinkedIn Profile Optimizer is an AI-powered tool designed to help content creators maximize their LinkedIn presence and professional appeal. This tool analyzes and enhances every aspect of your LinkedIn profile to increase visibility, engagement, and professional opportunities.
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. Profile Strength Analysis 📊
|
||||
- Comprehensive profile audit with section-by-section scoring
|
||||
- SEO optimization recommendations
|
||||
- Missing elements identification
|
||||
- Prioritized improvement suggestions
|
||||
- Engagement potential assessment
|
||||
- Overall profile strength score
|
||||
|
||||
### 2. Headline Optimizer 🎯
|
||||
- Industry-specific keyword optimization
|
||||
- Value proposition enhancement
|
||||
- Achievement integration
|
||||
- Character count optimization
|
||||
- Professional title recommendations
|
||||
- SEO-friendly formatting
|
||||
|
||||
### 3. About Section Generator 📝
|
||||
- Compelling narrative creation
|
||||
- Professional journey storytelling
|
||||
- Achievement showcase
|
||||
- Industry expertise highlighting
|
||||
- Call-to-action optimization
|
||||
- Target audience alignment
|
||||
- Proper formatting and structure
|
||||
|
||||
### 4. Experience Description Enhancer 💼
|
||||
- Action verb optimization
|
||||
- Quantifiable achievement integration
|
||||
- Key responsibility highlighting
|
||||
- Industry-relevant keyword incorporation
|
||||
- Professional formatting
|
||||
- Impact measurement metrics
|
||||
- Role-specific enhancements
|
||||
|
||||
### 5. Skills Recommender 🎓
|
||||
- Industry-trending skills analysis
|
||||
- Role-specific recommendations
|
||||
- Technical and soft skills balance
|
||||
- Skill categorization
|
||||
- Obsolete skill identification
|
||||
- Endorsement strategy suggestions
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
- Python 3.8 or higher
|
||||
- Streamlit
|
||||
- Access to ALwrity's AI services
|
||||
|
||||
### Usage
|
||||
|
||||
1. **Profile Analysis**
|
||||
```python
|
||||
# Initialize the optimizer
|
||||
optimizer = LinkedInProfileOptimizer()
|
||||
|
||||
# Analyze profile
|
||||
analysis = await optimizer.analyze_profile_strength(profile_data)
|
||||
```
|
||||
|
||||
2. **Headline Optimization**
|
||||
```python
|
||||
# Optimize your headline
|
||||
headline_result = await optimizer.optimize_headline(
|
||||
current_headline="Your current headline",
|
||||
industry="Your industry",
|
||||
role="Your role"
|
||||
)
|
||||
```
|
||||
|
||||
3. **About Section Generation**
|
||||
```python
|
||||
# Generate optimized About section
|
||||
about_section = await optimizer.generate_about_section(
|
||||
current_about="Your current about",
|
||||
experience=experience_list,
|
||||
achievements=achievements_list,
|
||||
target_audience="Your target audience"
|
||||
)
|
||||
```
|
||||
|
||||
## Best Practices for Content Creators
|
||||
|
||||
### 1. Profile Optimization Strategy
|
||||
- Start with the Profile Analysis to identify key improvement areas
|
||||
- Focus on your headline first - it's your first impression
|
||||
- Craft your About section to showcase your content creation expertise
|
||||
- Highlight your content creation achievements with metrics
|
||||
- Include multimedia samples of your work
|
||||
|
||||
### 2. Content Creator Specific Tips
|
||||
- Emphasize your content creation specialties in your headline
|
||||
- Showcase engagement metrics in your experience descriptions
|
||||
- Include platform-specific expertise (LinkedIn, YouTube, etc.)
|
||||
- Highlight collaboration experiences with brands
|
||||
- Demonstrate thought leadership in your niche
|
||||
|
||||
### 3. SEO Optimization
|
||||
- Use industry-standard content creation terms
|
||||
- Include platform-specific keywords
|
||||
- Incorporate trending industry hashtags
|
||||
- Balance creative and professional terminology
|
||||
- Optimize for both human readers and search algorithms
|
||||
|
||||
### 4. Skills Strategy
|
||||
- Balance technical content creation skills with soft skills
|
||||
- Include platform-specific skills (LinkedIn content creation, etc.)
|
||||
- Add emerging content formats (Shorts, Lives, etc.)
|
||||
- Include analytics and measurement skills
|
||||
- Showcase collaboration and community management abilities
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Custom URL Optimization
|
||||
- Professional URL structure recommendations
|
||||
- Brand alignment suggestions
|
||||
- SEO-friendly formatting
|
||||
- Consistency with other social profiles
|
||||
|
||||
### Project Highlights
|
||||
- Content campaign showcases
|
||||
- Viral content examples
|
||||
- Brand collaboration features
|
||||
- Impact metrics display
|
||||
- Portfolio integration
|
||||
|
||||
### Endorsement Strategy
|
||||
- Skill endorsement prioritization
|
||||
- Network engagement tactics
|
||||
- Reciprocal endorsement approaches
|
||||
- Expertise validation methods
|
||||
|
||||
## Performance Metrics
|
||||
|
||||
The Profile Optimizer evaluates profiles based on:
|
||||
- Profile Completeness Score
|
||||
- Keyword Optimization Level
|
||||
- Content Quality Metrics
|
||||
- Engagement Potential
|
||||
- Network Growth Indicators
|
||||
- Professional Appeal Score
|
||||
|
||||
## Tips for Maximum Impact
|
||||
|
||||
1. **Regular Updates**
|
||||
- Review and update your profile monthly
|
||||
- Add new content creation achievements regularly
|
||||
- Keep skills current with industry trends
|
||||
- Update metrics and performance statistics
|
||||
|
||||
2. **Content Strategy Integration**
|
||||
- Align profile messaging with your content
|
||||
- Cross-reference your content platforms
|
||||
- Showcase your content creation process
|
||||
- Highlight your unique value proposition
|
||||
|
||||
3. **Network Growth**
|
||||
- Optimize for your target audience
|
||||
- Use industry-specific terminology
|
||||
- Showcase collaboration opportunities
|
||||
- Highlight your community engagement
|
||||
|
||||
## Support and Resources
|
||||
|
||||
For additional support:
|
||||
- Check the [ALwrity Documentation](https://docs.alwrity.com)
|
||||
- Join our [Content Creator Community](https://community.alwrity.com)
|
||||
- Follow our [LinkedIn Page](https://linkedin.com/company/alwrity)
|
||||
- Contact support at support@alwrity.com
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions from the content creator community! Please read our [Contributing Guidelines](CONTRIBUTING.md) for details on submitting pull requests.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
@@ -1,11 +0,0 @@
|
||||
"""
|
||||
LinkedIn Profile Optimizer Module
|
||||
|
||||
This module provides AI-powered optimization for LinkedIn profiles to improve visibility
|
||||
and professional appeal.
|
||||
"""
|
||||
|
||||
from .linkedin_profile_optimizer import LinkedInProfileOptimizer
|
||||
from .linkedin_profile_optimizer_ui import linkedin_profile_optimizer_ui
|
||||
|
||||
__all__ = ['LinkedInProfileOptimizer', 'linkedin_profile_optimizer_ui']
|
||||
@@ -1,240 +0,0 @@
|
||||
"""
|
||||
LinkedIn Profile Optimizer
|
||||
|
||||
This module provides AI-powered optimization for LinkedIn profiles to improve visibility
|
||||
and professional appeal.
|
||||
"""
|
||||
|
||||
import json
|
||||
from typing import Dict, List, Optional
|
||||
from loguru import logger
|
||||
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from .....ai_web_researcher.gpt_online_researcher import do_google_serp_search
|
||||
from .....ai_web_researcher.metaphor_basic_neural_web_search import metaphor_search_articles
|
||||
from .....ai_web_researcher.tavily_ai_search import do_tavily_ai_search
|
||||
|
||||
class LinkedInProfileOptimizer:
|
||||
"""
|
||||
AI-powered LinkedIn Profile Optimizer that enhances profiles for better visibility
|
||||
and professional appeal.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the LinkedIn Profile Optimizer."""
|
||||
self.industry_keywords = {}
|
||||
self.seo_patterns = {}
|
||||
self.profile_sections = [
|
||||
"headline",
|
||||
"about",
|
||||
"experience",
|
||||
"skills",
|
||||
"projects",
|
||||
"endorsements",
|
||||
"summary",
|
||||
"custom_url"
|
||||
]
|
||||
|
||||
async def optimize_headline(self, current_headline: str, industry: str, role: str) -> Dict:
|
||||
"""
|
||||
Optimize the LinkedIn headline for better visibility and impact.
|
||||
|
||||
Args:
|
||||
current_headline: Current LinkedIn headline
|
||||
industry: User's industry
|
||||
role: User's current or target role
|
||||
|
||||
Returns:
|
||||
Dict containing optimized headline and explanation
|
||||
"""
|
||||
prompt = f"""
|
||||
As an expert LinkedIn profile optimizer, enhance this headline for maximum impact and visibility:
|
||||
Current Headline: {current_headline}
|
||||
Industry: {industry}
|
||||
Role: {role}
|
||||
|
||||
Consider:
|
||||
- Including relevant keywords for {industry}
|
||||
- Highlighting unique value proposition
|
||||
- Using industry-standard titles
|
||||
- Incorporating achievements or specialties
|
||||
- Keeping it under LinkedIn's character limit
|
||||
|
||||
Return a JSON with:
|
||||
- optimized_headline: The enhanced headline
|
||||
- explanation: Why changes were made
|
||||
- keywords_used: Key terms included
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
|
||||
async def generate_about_section(self,
|
||||
current_about: str,
|
||||
experience: List[Dict],
|
||||
achievements: List[str],
|
||||
target_audience: str
|
||||
) -> Dict:
|
||||
"""
|
||||
Generate an optimized About section.
|
||||
|
||||
Args:
|
||||
current_about: Current About section content
|
||||
experience: List of work experiences
|
||||
achievements: List of key achievements
|
||||
target_audience: Intended profile visitors
|
||||
|
||||
Returns:
|
||||
Dict containing new About section and explanation
|
||||
"""
|
||||
prompt = f"""
|
||||
As an expert LinkedIn profile writer, create an engaging About section that showcases professional value:
|
||||
|
||||
Current About: {current_about}
|
||||
Key Experiences: {json.dumps(experience)}
|
||||
Achievements: {json.dumps(achievements)}
|
||||
Target Audience: {target_audience}
|
||||
|
||||
Consider:
|
||||
- Strong opening hook
|
||||
- Professional journey narrative
|
||||
- Key achievements and impact
|
||||
- Industry expertise
|
||||
- Call to action
|
||||
- Proper formatting and structure
|
||||
|
||||
Return a JSON with:
|
||||
- about_section: The optimized content
|
||||
- structure_explanation: Section breakdown
|
||||
- impact_factors: Key elements that drive engagement
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
|
||||
async def enhance_experience_descriptions(self,
|
||||
experiences: List[Dict]
|
||||
) -> List[Dict]:
|
||||
"""
|
||||
Enhance work experience descriptions for better impact.
|
||||
|
||||
Args:
|
||||
experiences: List of work experiences with roles and descriptions
|
||||
|
||||
Returns:
|
||||
List of enhanced experience descriptions
|
||||
"""
|
||||
enhanced_experiences = []
|
||||
|
||||
for exp in experiences:
|
||||
prompt = f"""
|
||||
As an expert LinkedIn profile writer, enhance this work experience description:
|
||||
|
||||
Role: {exp.get('role')}
|
||||
Company: {exp.get('company')}
|
||||
Current Description: {exp.get('description')}
|
||||
|
||||
Enhance the description to:
|
||||
- Lead with strong action verbs
|
||||
- Include quantifiable achievements
|
||||
- Highlight key responsibilities
|
||||
- Incorporate relevant keywords
|
||||
- Use proper formatting
|
||||
|
||||
Return a JSON with:
|
||||
- enhanced_description: The improved description
|
||||
- achievements_highlighted: Key accomplishments
|
||||
- keywords_used: Industry terms included
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
enhanced_exp = json.loads(response)
|
||||
enhanced_experiences.append({
|
||||
**exp,
|
||||
'enhanced_description': enhanced_exp['enhanced_description'],
|
||||
'achievements': enhanced_exp['achievements_highlighted'],
|
||||
'keywords': enhanced_exp['keywords_used']
|
||||
})
|
||||
|
||||
return enhanced_experiences
|
||||
|
||||
async def recommend_skills(self,
|
||||
current_skills: List[str],
|
||||
industry: str,
|
||||
role: str
|
||||
) -> Dict:
|
||||
"""
|
||||
Recommend relevant skills based on industry and role.
|
||||
|
||||
Args:
|
||||
current_skills: List of current skills
|
||||
industry: User's industry
|
||||
role: User's role
|
||||
|
||||
Returns:
|
||||
Dict containing skill recommendations
|
||||
"""
|
||||
# Research trending skills in the industry
|
||||
industry_research = await do_tavily_ai_search(
|
||||
f"most in-demand skills for {role} in {industry} LinkedIn 2024"
|
||||
)
|
||||
|
||||
prompt = f"""
|
||||
As a LinkedIn profile optimization expert, recommend skills based on:
|
||||
|
||||
Current Skills: {json.dumps(current_skills)}
|
||||
Industry: {industry}
|
||||
Role: {role}
|
||||
Industry Research: {json.dumps(industry_research)}
|
||||
|
||||
Provide:
|
||||
- Must-have technical skills
|
||||
- Important soft skills
|
||||
- Trending skills in the industry
|
||||
- Skills to remove (if any)
|
||||
|
||||
Return a JSON with:
|
||||
- recommended_skills: New skills to add
|
||||
- skills_to_remove: Skills to consider removing
|
||||
- skill_categories: Grouping of skills by category
|
||||
- trending_skills: Currently popular skills
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
|
||||
async def analyze_profile_strength(self,
|
||||
profile_data: Dict
|
||||
) -> Dict:
|
||||
"""
|
||||
Analyze overall profile strength and provide improvement recommendations.
|
||||
|
||||
Args:
|
||||
profile_data: Complete profile information
|
||||
|
||||
Returns:
|
||||
Dict containing analysis and recommendations
|
||||
"""
|
||||
prompt = f"""
|
||||
As a LinkedIn profile optimization expert, analyze this profile:
|
||||
|
||||
Profile Data: {json.dumps(profile_data)}
|
||||
|
||||
Provide a comprehensive analysis including:
|
||||
- Overall profile strength score
|
||||
- Section-by-section analysis
|
||||
- Missing elements
|
||||
- Improvement opportunities
|
||||
- SEO optimization suggestions
|
||||
- Engagement potential
|
||||
|
||||
Return a JSON with:
|
||||
- strength_score: 0-100 rating
|
||||
- section_scores: Individual section ratings
|
||||
- missing_elements: Key missing components
|
||||
- priority_improvements: Ordered list of suggestions
|
||||
- seo_recommendations: Keyword and optimization tips
|
||||
"""
|
||||
|
||||
response = await llm_text_gen(prompt)
|
||||
return json.loads(response)
|
||||
@@ -1,215 +0,0 @@
|
||||
"""
|
||||
LinkedIn Profile Optimizer UI
|
||||
|
||||
This module provides the Streamlit UI for the LinkedIn Profile Optimizer.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import json
|
||||
from typing import Dict, List
|
||||
from .linkedin_profile_optimizer import LinkedInProfileOptimizer
|
||||
|
||||
async def linkedin_profile_optimizer_ui():
|
||||
"""
|
||||
Streamlit UI for the LinkedIn Profile Optimizer.
|
||||
"""
|
||||
# Initialize the profile optimizer
|
||||
optimizer = LinkedInProfileOptimizer()
|
||||
|
||||
# Create tabs for different optimization sections
|
||||
tabs = st.tabs([
|
||||
"Profile Analysis",
|
||||
"Headline Optimizer",
|
||||
"About Section",
|
||||
"Experience Enhancer",
|
||||
"Skills Recommender"
|
||||
])
|
||||
|
||||
# Profile Analysis Tab
|
||||
with tabs[0]:
|
||||
st.header("Profile Strength Analysis")
|
||||
st.info("Upload your profile information for a comprehensive analysis")
|
||||
|
||||
# Profile Data Input
|
||||
st.subheader("Enter Profile Information")
|
||||
profile_data = {
|
||||
"headline": st.text_input("Current Headline", key="profile_headline"),
|
||||
"about": st.text_area("About Section", key="profile_about"),
|
||||
"industry": st.text_input("Industry", key="profile_industry"),
|
||||
"current_role": st.text_input("Current Role", key="profile_role"),
|
||||
"experience": [],
|
||||
"skills": st.text_area("Current Skills (one per line)", key="profile_skills").split("\n"),
|
||||
"education": st.text_area("Education (one per line)", key="profile_education").split("\n")
|
||||
}
|
||||
|
||||
# Experience Input
|
||||
st.subheader("Work Experience")
|
||||
num_experiences = st.number_input("Number of experiences to add", min_value=0, max_value=10, value=1, key="profile_num_exp")
|
||||
|
||||
for i in range(num_experiences):
|
||||
st.markdown(f"**Experience {i+1}**")
|
||||
exp = {
|
||||
"role": st.text_input(f"Role {i+1}", key=f"profile_role_{i}"),
|
||||
"company": st.text_input(f"Company {i+1}", key=f"profile_company_{i}"),
|
||||
"description": st.text_area(f"Description {i+1}", key=f"profile_desc_{i}")
|
||||
}
|
||||
profile_data["experience"].append(exp)
|
||||
st.divider()
|
||||
|
||||
if st.button("Analyze Profile", key="profile_analyze_btn"):
|
||||
with st.spinner("Analyzing your profile..."):
|
||||
analysis = await optimizer.analyze_profile_strength(profile_data)
|
||||
|
||||
# Display Analysis Results
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
st.metric("Profile Strength Score", f"{analysis['strength_score']}/100")
|
||||
|
||||
st.subheader("Section Scores")
|
||||
for section, score in analysis['section_scores'].items():
|
||||
st.progress(score/100, text=f"{section}: {score}%")
|
||||
|
||||
with col2:
|
||||
st.subheader("Priority Improvements")
|
||||
for improvement in analysis['priority_improvements']:
|
||||
st.warning(improvement)
|
||||
|
||||
st.subheader("SEO Recommendations")
|
||||
for rec in analysis['seo_recommendations']:
|
||||
st.info(rec)
|
||||
|
||||
# Headline Optimizer Tab
|
||||
with tabs[1]:
|
||||
st.header("Headline Optimizer")
|
||||
st.info("Optimize your headline for better visibility and impact")
|
||||
|
||||
current_headline = st.text_input("Current Headline", key="headline_current")
|
||||
industry = st.text_input("Industry", key="headline_industry")
|
||||
role = st.text_input("Current/Target Role", key="headline_role")
|
||||
|
||||
if st.button("Optimize Headline", key="headline_optimize_btn"):
|
||||
with st.spinner("Generating optimized headline..."):
|
||||
headline_optimization = await optimizer.optimize_headline(
|
||||
current_headline,
|
||||
industry,
|
||||
role
|
||||
)
|
||||
|
||||
st.subheader("Optimized Headline")
|
||||
st.success(headline_optimization['optimized_headline'])
|
||||
|
||||
st.subheader("Optimization Explanation")
|
||||
st.write(headline_optimization['explanation'])
|
||||
|
||||
st.subheader("Keywords Used")
|
||||
for keyword in headline_optimization['keywords_used']:
|
||||
st.info(keyword)
|
||||
|
||||
# About Section Tab
|
||||
with tabs[2]:
|
||||
st.header("About Section Generator")
|
||||
st.info("Create an engaging and professional About section")
|
||||
|
||||
current_about = st.text_area("Current About Section", key="about_current")
|
||||
achievements = st.text_area("Key Achievements (one per line)", key="about_achievements").split("\n")
|
||||
target_audience = st.text_input("Target Audience", key="about_audience")
|
||||
|
||||
if st.button("Generate About Section", key="about_generate_btn"):
|
||||
with st.spinner("Generating optimized About section..."):
|
||||
about_optimization = await optimizer.generate_about_section(
|
||||
current_about,
|
||||
profile_data.get("experience", []),
|
||||
achievements,
|
||||
target_audience
|
||||
)
|
||||
|
||||
st.subheader("Optimized About Section")
|
||||
st.markdown(about_optimization['about_section'])
|
||||
|
||||
st.subheader("Section Structure")
|
||||
for section, explanation in about_optimization['structure_explanation'].items():
|
||||
st.markdown(f"**{section}**")
|
||||
st.write(explanation)
|
||||
st.divider()
|
||||
|
||||
st.subheader("Impact Factors")
|
||||
for factor in about_optimization['impact_factors']:
|
||||
st.success(factor)
|
||||
|
||||
# Experience Enhancer Tab
|
||||
with tabs[3]:
|
||||
st.header("Experience Description Enhancer")
|
||||
st.info("Enhance your work experience descriptions for maximum impact")
|
||||
|
||||
experiences = []
|
||||
num_exp = st.number_input("Number of experiences to enhance", min_value=1, max_value=10, value=1, key="exp_num")
|
||||
|
||||
for i in range(num_exp):
|
||||
st.markdown(f"**Experience {i+1}**")
|
||||
exp = {
|
||||
"role": st.text_input(f"Role {i+1}", key=f"exp_role_{i}"),
|
||||
"company": st.text_input(f"Company {i+1}", key=f"exp_company_{i}"),
|
||||
"description": st.text_area(f"Current Description {i+1}", key=f"exp_desc_{i}")
|
||||
}
|
||||
experiences.append(exp)
|
||||
st.divider()
|
||||
|
||||
if st.button("Enhance Experiences", key="exp_enhance_btn"):
|
||||
with st.spinner("Enhancing experience descriptions..."):
|
||||
enhanced_experiences = await optimizer.enhance_experience_descriptions(experiences)
|
||||
|
||||
for i, exp in enumerate(enhanced_experiences):
|
||||
st.markdown(f"**Enhanced Experience {i+1}**")
|
||||
st.subheader(f"{exp['role']} at {exp['company']}")
|
||||
st.markdown(exp['enhanced_description'])
|
||||
|
||||
st.subheader("Key Achievements")
|
||||
for achievement in exp['achievements']:
|
||||
st.success(achievement)
|
||||
|
||||
st.subheader("Keywords Used")
|
||||
for keyword in exp['keywords']:
|
||||
st.info(keyword)
|
||||
|
||||
st.divider()
|
||||
|
||||
# Skills Recommender Tab
|
||||
with tabs[4]:
|
||||
st.header("Skills Recommender")
|
||||
st.info("Get personalized skill recommendations for your profile")
|
||||
|
||||
current_skills = st.text_area("Current Skills (one per line)", key="skills_current").split("\n")
|
||||
industry = st.text_input("Industry (for skills)", key="skills_industry")
|
||||
role = st.text_input("Role (for skills)", key="skills_role")
|
||||
|
||||
if st.button("Get Skill Recommendations", key="skills_recommend_btn"):
|
||||
with st.spinner("Analyzing and recommending skills..."):
|
||||
skill_recommendations = await optimizer.recommend_skills(
|
||||
current_skills,
|
||||
industry,
|
||||
role
|
||||
)
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
st.subheader("Recommended Skills to Add")
|
||||
for skill in skill_recommendations['recommended_skills']:
|
||||
st.success(skill)
|
||||
|
||||
st.subheader("Consider Removing")
|
||||
for skill in skill_recommendations['skills_to_remove']:
|
||||
st.warning(skill)
|
||||
|
||||
with col2:
|
||||
st.subheader("Trending Skills")
|
||||
for skill in skill_recommendations['trending_skills']:
|
||||
st.info(skill)
|
||||
|
||||
st.subheader("Skill Categories")
|
||||
for category, skills in skill_recommendations['skill_categories'].items():
|
||||
st.markdown(f"**{category}**")
|
||||
for skill in skills:
|
||||
st.write(f"- {skill}")
|
||||
st.divider()
|
||||
@@ -1,207 +0,0 @@
|
||||
# LinkedIn Video Script Generator
|
||||
|
||||
## Overview
|
||||
|
||||
The LinkedIn Video Script Generator is an AI-powered tool designed to help professionals create engaging and effective video scripts for LinkedIn content. This tool combines research-driven insights with professional scriptwriting techniques to generate compelling video content that resonates with your target audience.
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Script Generation
|
||||
- **Hook Creation**: Generate attention-grabbing openings that capture viewer interest
|
||||
- **Story Structure**: Create well-organized scripts with clear sections and transitions
|
||||
- **Professional Speaking Points**: Generate key talking points and emphasis areas
|
||||
- **Multiple Video Types**:
|
||||
- Thought Leadership
|
||||
- Tutorial/How-to
|
||||
- Product Demo
|
||||
- Company Culture
|
||||
- Industry Insights
|
||||
- Event Highlights
|
||||
- Customer Story
|
||||
- Behind the Scenes
|
||||
|
||||
### 2. Research Integration
|
||||
- **Multi-Source Research**: Gather insights from:
|
||||
- Metaphor (neural search)
|
||||
- Google SERP
|
||||
- Tavily AI
|
||||
- **Insight Extraction**: Automatically extract key insights and trends
|
||||
- **Topic Analysis**: Research current trends and best practices
|
||||
|
||||
### 3. Visual Elements
|
||||
- **Visual Cue Suggestions**: Get recommendations for:
|
||||
- B-roll footage
|
||||
- Graphics and animations
|
||||
- Text overlays
|
||||
- Visual transitions
|
||||
- **Timing Guidance**: Precise timing suggestions for each visual element
|
||||
- **Visual Hierarchy**: Optimize visual flow and emphasis
|
||||
|
||||
### 4. Engagement Optimization
|
||||
- **Call-to-Action Generation**: Create compelling CTAs
|
||||
- **Engagement Prompts**: Generate discussion questions and interaction points
|
||||
- **Audience Targeting**: Tailor content to specific professional audiences
|
||||
- **Tone Customization**: Multiple tone options:
|
||||
- Professional & Authoritative
|
||||
- Conversational & Friendly
|
||||
- Educational & Informative
|
||||
- Inspirational & Motivational
|
||||
- Storytelling & Narrative
|
||||
|
||||
### 5. Length Options
|
||||
- Short (< 1 minute)
|
||||
- Medium (1-3 minutes)
|
||||
- Long (3-5 minutes)
|
||||
- Extended (5+ minutes)
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Workflow
|
||||
|
||||
1. **Enter Basic Details**
|
||||
- Choose your topic
|
||||
- Select your industry
|
||||
- Pick a video type
|
||||
- Set desired length
|
||||
|
||||
2. **Configure Advanced Options**
|
||||
- Select target audience
|
||||
- Choose tone
|
||||
- Set additional preferences
|
||||
|
||||
3. **Research Your Topic**
|
||||
- Choose research source
|
||||
- Review insights and trends
|
||||
- Incorporate key findings
|
||||
|
||||
4. **Generate Script**
|
||||
- Get complete script with sections
|
||||
- Review visual suggestions
|
||||
- Check engagement elements
|
||||
|
||||
### Best Practices
|
||||
|
||||
#### Script Structure
|
||||
1. **Strong Hook (0-15 seconds)**
|
||||
- Capture attention immediately
|
||||
- Present clear value proposition
|
||||
- Use professional tone
|
||||
|
||||
2. **Content Flow (Main Body)**
|
||||
- Clear section transitions
|
||||
- Logical progression
|
||||
- Engaging visuals
|
||||
|
||||
3. **Effective Closing**
|
||||
- Strong call-to-action
|
||||
- Engagement prompts
|
||||
- Next steps
|
||||
|
||||
#### Visual Elements
|
||||
1. **Professional Quality**
|
||||
- High-quality visuals
|
||||
- Consistent branding
|
||||
- Clear text overlays
|
||||
|
||||
2. **Engagement Focus**
|
||||
- Strategic visual pacing
|
||||
- Attention-holding elements
|
||||
- Professional transitions
|
||||
|
||||
3. **Brand Consistency**
|
||||
- Aligned with brand guidelines
|
||||
- Professional appearance
|
||||
- Consistent style
|
||||
|
||||
#### Content Tips by Video Type
|
||||
|
||||
##### Thought Leadership
|
||||
- Focus on unique insights
|
||||
- Share expert perspective
|
||||
- Include industry trends
|
||||
|
||||
##### Tutorial/How-to
|
||||
- Clear step-by-step structure
|
||||
- Visual demonstrations
|
||||
- Practical examples
|
||||
|
||||
##### Product Demo
|
||||
- Feature highlights
|
||||
- Use cases
|
||||
- Value proposition
|
||||
|
||||
##### Company Culture
|
||||
- Authentic representation
|
||||
- Team involvement
|
||||
- Behind-the-scenes elements
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Dependencies
|
||||
- Streamlit: For the user interface
|
||||
- GPT Providers: For AI text generation
|
||||
- Web Research Tools: For gathering insights
|
||||
|
||||
### Integration
|
||||
The Video Script Generator is fully integrated into the LinkedIn AI Writer suite and can be accessed through the main interface.
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Tech Industry Thought Leadership
|
||||
**Topic**: "The Future of AI in Business"
|
||||
**Length**: 2-3 minutes
|
||||
**Target**: Decision Makers
|
||||
|
||||
### Example 2: Healthcare Tutorial
|
||||
**Topic**: "Implementing Telehealth Solutions"
|
||||
**Length**: 3-5 minutes
|
||||
**Target**: Healthcare Professionals
|
||||
|
||||
### Example 3: Product Demo
|
||||
**Topic**: "New CRM Features Overview"
|
||||
**Length**: 1-2 minutes
|
||||
**Target**: Business Users
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Research Not Returning Results**
|
||||
- Try different search terms
|
||||
- Switch research sources
|
||||
- Check connection
|
||||
|
||||
2. **Script Generation Issues**
|
||||
- Verify all fields are filled
|
||||
- Try different topic phrasing
|
||||
- Check length settings
|
||||
|
||||
3. **Visual Suggestions**
|
||||
- Ensure script sections are clear
|
||||
- Check timing specifications
|
||||
- Review section content
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- **AI Voice Generation**: Add AI voiceover capabilities
|
||||
- **Template Library**: Pre-built script templates
|
||||
- **Analytics Integration**: Performance tracking
|
||||
- **Multi-language Support**: Generate scripts in multiple languages
|
||||
- **Direct Publishing**: Integration with LinkedIn video upload
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions to the LinkedIn Video Script Generator are welcome! Please follow these steps:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
||||
## Contact
|
||||
|
||||
For questions or feedback about the LinkedIn Video Script Generator, please contact the development team.
|
||||
@@ -1,10 +0,0 @@
|
||||
"""
|
||||
LinkedIn Video Script Generator Module
|
||||
|
||||
This module provides functionality for generating professional video scripts
|
||||
for LinkedIn content with AI-powered optimization and engagement features.
|
||||
"""
|
||||
|
||||
from .linkedin_video_script_generator import LinkedInVideoScriptGenerator, linkedin_video_script_generator_ui
|
||||
|
||||
__all__ = ["LinkedInVideoScriptGenerator", "linkedin_video_script_generator_ui"]
|
||||
@@ -1,571 +0,0 @@
|
||||
"""
|
||||
LinkedIn Video Script Generator
|
||||
|
||||
This module provides functionality for generating professional video scripts
|
||||
for LinkedIn content with AI-powered optimization and engagement features.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import json
|
||||
from typing import Dict, List, Optional, Union
|
||||
from loguru import logger
|
||||
|
||||
from .....gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||
from .....gpt_providers.text_generation.gemini_pro_text import gemini_structured_json_response
|
||||
from .....ai_web_researcher.gpt_online_researcher import do_google_serp_search
|
||||
from .....ai_web_researcher.metaphor_basic_neural_web_search import metaphor_search_articles
|
||||
from .....ai_web_researcher.tavily_ai_search import do_tavily_ai_search
|
||||
|
||||
|
||||
class LinkedInVideoScriptGenerator:
|
||||
"""
|
||||
AI-powered LinkedIn video script generator that creates engaging scripts with
|
||||
hooks, story structure, and visual suggestions.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the LinkedIn Video Script Generator."""
|
||||
self.video_types = {
|
||||
"thought_leadership": "Thought Leadership",
|
||||
"tutorial": "Tutorial/How-to",
|
||||
"product_demo": "Product Demo",
|
||||
"company_culture": "Company Culture",
|
||||
"industry_insights": "Industry Insights",
|
||||
"event_highlights": "Event Highlights",
|
||||
"customer_story": "Customer Story",
|
||||
"behind_scenes": "Behind the Scenes"
|
||||
}
|
||||
|
||||
self.video_lengths = {
|
||||
"short": "Short (< 1 minute)",
|
||||
"medium": "Medium (1-3 minutes)",
|
||||
"long": "Long (3-5 minutes)",
|
||||
"extended": "Extended (5+ minutes)"
|
||||
}
|
||||
|
||||
self.tone_options = {
|
||||
"professional": "Professional & Authoritative",
|
||||
"conversational": "Conversational & Friendly",
|
||||
"educational": "Educational & Informative",
|
||||
"inspirational": "Inspirational & Motivational",
|
||||
"storytelling": "Storytelling & Narrative"
|
||||
}
|
||||
|
||||
self.target_audiences = {
|
||||
"professionals": "Industry Professionals",
|
||||
"decision_makers": "Decision Makers",
|
||||
"job_seekers": "Job Seekers",
|
||||
"students": "Students & Early Career",
|
||||
"entrepreneurs": "Entrepreneurs & Business Owners",
|
||||
"general": "General Professional Network"
|
||||
}
|
||||
|
||||
def research_topic(self, topic: str, industry: str, search_engine: str = "metaphor") -> Dict:
|
||||
"""
|
||||
Research a topic to gather insights for video content.
|
||||
|
||||
Args:
|
||||
topic: The main topic for the video
|
||||
industry: The target industry
|
||||
search_engine: The search engine to use (metaphor, google, tavily)
|
||||
|
||||
Returns:
|
||||
Dict containing research results and insights
|
||||
"""
|
||||
try:
|
||||
search_query = f"{topic} {industry} trends insights best practices"
|
||||
|
||||
if search_engine == "metaphor":
|
||||
articles = metaphor_search_articles(search_query)
|
||||
elif search_engine == "google":
|
||||
articles = do_google_serp_search(search_query)
|
||||
elif search_engine == "tavily":
|
||||
articles = do_tavily_ai_search(search_query)
|
||||
else:
|
||||
raise ValueError(f"Unsupported search engine: {search_engine}")
|
||||
|
||||
insights, trends = self._extract_insights_and_trends(articles)
|
||||
|
||||
return {
|
||||
"articles": articles,
|
||||
"insights": insights,
|
||||
"trends": trends
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error researching topic: {str(e)}")
|
||||
return {
|
||||
"articles": [],
|
||||
"insights": [],
|
||||
"trends": []
|
||||
}
|
||||
|
||||
def _extract_insights_and_trends(self, articles: List[Dict]) -> tuple[List[str], List[str]]:
|
||||
"""Extract key insights and trends from research articles."""
|
||||
try:
|
||||
prompt = f"""
|
||||
Analyze these articles and extract key insights and trends:
|
||||
|
||||
Articles:
|
||||
{json.dumps(articles, indent=2)}
|
||||
|
||||
Identify the most valuable insights and emerging trends from these articles.
|
||||
"""
|
||||
|
||||
# Define the schema for insights and trends
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"insights": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"}
|
||||
},
|
||||
"trends": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"required": ["insights", "trends"]
|
||||
}
|
||||
|
||||
# Use the structured JSON response function
|
||||
result = gemini_structured_json_response(prompt, schema)
|
||||
|
||||
# Check if there was an error
|
||||
if "error" in result:
|
||||
logger.error(f"Error extracting insights and trends: {result['error']}")
|
||||
return [], []
|
||||
|
||||
return result.get("insights", []), result.get("trends", [])
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error extracting insights and trends: {str(e)}")
|
||||
return [], []
|
||||
|
||||
def generate_hook(self, topic: str, video_type: str, target_audience: str, tone: str) -> str:
|
||||
"""
|
||||
Generate an attention-grabbing hook for the video.
|
||||
|
||||
Args:
|
||||
topic: The main topic of the video
|
||||
video_type: Type of video content
|
||||
target_audience: Target audience for the video
|
||||
tone: Desired tone of the hook
|
||||
|
||||
Returns:
|
||||
str: The generated hook
|
||||
"""
|
||||
try:
|
||||
prompt = f"""
|
||||
Create an attention-grabbing hook for a LinkedIn video with:
|
||||
- Topic: {topic}
|
||||
- Video Type: {self.video_types[video_type]}
|
||||
- Target Audience: {self.target_audiences[target_audience]}
|
||||
- Tone: {self.tone_options[tone]}
|
||||
|
||||
The hook should be:
|
||||
1. Under 15 seconds when spoken
|
||||
2. Immediately capture attention
|
||||
3. Clear value proposition
|
||||
4. Professional and engaging
|
||||
|
||||
Return only the hook text.
|
||||
"""
|
||||
|
||||
return llm_text_gen(prompt)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating hook: {str(e)}")
|
||||
return ""
|
||||
|
||||
def generate_story_structure(self, topic: str, video_type: str, length: str, insights: List[str]) -> Dict:
|
||||
"""Generate a structured story for the video."""
|
||||
try:
|
||||
prompt = f"""
|
||||
Create a story structure for a LinkedIn video:
|
||||
- Topic: {topic}
|
||||
- Video Type: {self.video_types[video_type]}
|
||||
- Length: {self.video_lengths[length]}
|
||||
- Key Insights: {json.dumps(insights)}
|
||||
|
||||
Create a well-structured story with clear sections, transitions, and key points.
|
||||
Include guidance on pacing and delivery.
|
||||
"""
|
||||
|
||||
# Define the schema for the story structure
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"sections": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {"type": "string"},
|
||||
"content": {"type": "string"},
|
||||
"duration": {"type": "string"}
|
||||
},
|
||||
"required": ["title", "content", "duration"]
|
||||
}
|
||||
},
|
||||
"transitions": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"}
|
||||
},
|
||||
"key_points": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"}
|
||||
},
|
||||
"pacing_notes": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"required": ["sections", "transitions", "key_points", "pacing_notes"]
|
||||
}
|
||||
|
||||
# Use the structured JSON response function
|
||||
result = gemini_structured_json_response(prompt, schema)
|
||||
|
||||
# Check if there was an error
|
||||
if "error" in result:
|
||||
logger.error(f"Error generating story structure: {result['error']}")
|
||||
return {
|
||||
"sections": [],
|
||||
"transitions": [],
|
||||
"key_points": [],
|
||||
"pacing_notes": []
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating story structure: {str(e)}")
|
||||
return {
|
||||
"sections": [],
|
||||
"transitions": [],
|
||||
"key_points": [],
|
||||
"pacing_notes": []
|
||||
}
|
||||
|
||||
def generate_visual_cues(self, script_sections: List[Dict]) -> List[Dict]:
|
||||
"""Generate visual cues for the video script."""
|
||||
try:
|
||||
prompt = f"""
|
||||
Create visual cues for this video script:
|
||||
|
||||
Script Sections:
|
||||
{json.dumps(script_sections, indent=2)}
|
||||
|
||||
For each section, suggest:
|
||||
1. Visual type (b-roll, graphics, text overlay, etc.)
|
||||
2. Description of visual content
|
||||
3. Timing and duration
|
||||
4. Visual transitions
|
||||
"""
|
||||
|
||||
# Define the schema for visual cues
|
||||
schema = {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"section_title": {"type": "string"},
|
||||
"visual_type": {"type": "string"},
|
||||
"description": {"type": "string"},
|
||||
"timing": {"type": "string"},
|
||||
"transitions": {"type": "string"}
|
||||
},
|
||||
"required": ["section_title", "visual_type", "description", "timing", "transitions"]
|
||||
}
|
||||
}
|
||||
|
||||
# Use the structured JSON response function
|
||||
result = gemini_structured_json_response(prompt, schema)
|
||||
|
||||
# Check if there was an error
|
||||
if "error" in result:
|
||||
logger.error(f"Error generating visual cues: {result['error']}")
|
||||
return []
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating visual cues: {str(e)}")
|
||||
return []
|
||||
|
||||
def generate_full_script(self, topic: str, video_type: str, length: str,
|
||||
target_audience: str, tone: str, insights: List[str]) -> Dict:
|
||||
"""
|
||||
Generate a complete video script with all components.
|
||||
|
||||
Args:
|
||||
topic: Main topic of the video
|
||||
video_type: Type of video content
|
||||
length: Target video length
|
||||
target_audience: Target audience
|
||||
tone: Desired tone
|
||||
insights: Research insights
|
||||
|
||||
Returns:
|
||||
Dict containing the complete script
|
||||
"""
|
||||
try:
|
||||
# Generate hook
|
||||
hook = self.generate_hook(topic, video_type, target_audience, tone)
|
||||
|
||||
# Generate story structure
|
||||
structure = self.generate_story_structure(topic, video_type, length, insights)
|
||||
|
||||
# Generate visual cues
|
||||
visuals = self.generate_visual_cues(structure["sections"])
|
||||
|
||||
# Generate call-to-action
|
||||
cta = self.generate_cta(topic, video_type, target_audience)
|
||||
|
||||
# Combine all components
|
||||
script = {
|
||||
"metadata": {
|
||||
"topic": topic,
|
||||
"video_type": video_type,
|
||||
"length": length,
|
||||
"target_audience": target_audience,
|
||||
"tone": tone
|
||||
},
|
||||
"hook": hook,
|
||||
"structure": structure,
|
||||
"visuals": visuals,
|
||||
"cta": cta
|
||||
}
|
||||
|
||||
return script
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating full script: {str(e)}")
|
||||
return {}
|
||||
|
||||
def generate_cta(self, topic: str, video_type: str, target_audience: str) -> Dict:
|
||||
"""Generate a compelling call-to-action for the video."""
|
||||
try:
|
||||
prompt = f"""
|
||||
Create a compelling call-to-action for a LinkedIn video:
|
||||
- Topic: {topic}
|
||||
- Video Type: {self.video_types[video_type]}
|
||||
- Target Audience: {target_audience}
|
||||
|
||||
Generate a clear, engaging call-to-action that encourages viewer engagement.
|
||||
"""
|
||||
|
||||
# Define the schema for the CTA
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"primary_cta": {
|
||||
"type": "string",
|
||||
"description": "Main call-to-action text"
|
||||
},
|
||||
"secondary_cta": {
|
||||
"type": "string",
|
||||
"description": "Optional secondary call-to-action"
|
||||
},
|
||||
"engagement_hooks": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "Additional engagement prompts"
|
||||
},
|
||||
"hashtag_suggestions": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "Relevant hashtags for the CTA"
|
||||
}
|
||||
},
|
||||
"required": ["primary_cta", "secondary_cta", "engagement_hooks", "hashtag_suggestions"]
|
||||
}
|
||||
|
||||
# Use the structured JSON response function
|
||||
result = gemini_structured_json_response(prompt, schema)
|
||||
|
||||
# Check if there was an error
|
||||
if "error" in result:
|
||||
logger.error(f"Error generating CTA: {result['error']}")
|
||||
return {
|
||||
"primary_cta": "Thanks for watching!",
|
||||
"secondary_cta": "Let me know your thoughts in the comments.",
|
||||
"engagement_hooks": ["What did you think about this topic?"],
|
||||
"hashtag_suggestions": ["#LinkedInVideo"]
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating CTA: {str(e)}")
|
||||
return {
|
||||
"primary_cta": "Thanks for watching!",
|
||||
"secondary_cta": "Let me know your thoughts in the comments.",
|
||||
"engagement_hooks": ["What did you think about this topic?"],
|
||||
"hashtag_suggestions": ["#LinkedInVideo"]
|
||||
}
|
||||
|
||||
def linkedin_video_script_generator_ui():
|
||||
"""Streamlit UI for the LinkedIn Video Script Generator."""
|
||||
|
||||
st.title("LinkedIn Video Script Generator")
|
||||
st.markdown("""
|
||||
Create professional video scripts for LinkedIn that drive engagement and showcase your expertise.
|
||||
""")
|
||||
|
||||
# Initialize the video script generator
|
||||
generator = LinkedInVideoScriptGenerator()
|
||||
|
||||
# Create tabs for different sections
|
||||
tab1, tab2, tab3 = st.tabs(["Script Details", "Research & Insights", "Generated Script"])
|
||||
|
||||
with tab1:
|
||||
st.header("Video Script Details")
|
||||
|
||||
# Basic information
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
topic = st.text_input("Topic", placeholder="e.g., AI in Healthcare, Remote Work Best Practices")
|
||||
industry = st.text_input("Industry", placeholder="e.g., Technology, Healthcare, Finance")
|
||||
|
||||
with col2:
|
||||
video_type = st.selectbox(
|
||||
"Video Type",
|
||||
options=list(generator.video_types.keys()),
|
||||
format_func=lambda x: generator.video_types[x]
|
||||
)
|
||||
length = st.selectbox(
|
||||
"Video Length",
|
||||
options=list(generator.video_lengths.keys()),
|
||||
format_func=lambda x: generator.video_lengths[x]
|
||||
)
|
||||
|
||||
# Advanced options
|
||||
with st.expander("Advanced Options"):
|
||||
col3, col4 = st.columns(2)
|
||||
with col3:
|
||||
target_audience = st.selectbox(
|
||||
"Target Audience",
|
||||
options=list(generator.target_audiences.keys()),
|
||||
format_func=lambda x: generator.target_audiences[x]
|
||||
)
|
||||
|
||||
with col4:
|
||||
tone = st.selectbox(
|
||||
"Tone",
|
||||
options=list(generator.tone_options.keys()),
|
||||
format_func=lambda x: generator.tone_options[x]
|
||||
)
|
||||
|
||||
with tab2:
|
||||
st.header("Research & Insights")
|
||||
|
||||
if topic and industry:
|
||||
# Research options
|
||||
search_engine = st.selectbox(
|
||||
"Research Source",
|
||||
options=["metaphor", "google", "tavily"],
|
||||
format_func=lambda x: x.title()
|
||||
)
|
||||
|
||||
if st.button("Research Topic"):
|
||||
with st.spinner("Researching topic..."):
|
||||
research_results = generator.research_topic(topic, industry, search_engine)
|
||||
|
||||
if research_results["insights"] or research_results["trends"]:
|
||||
# Store results in session state
|
||||
st.session_state.research_results = research_results
|
||||
|
||||
# Display insights
|
||||
st.subheader("Key Insights")
|
||||
for insight in research_results["insights"]:
|
||||
st.markdown(f"- {insight}")
|
||||
|
||||
# Display trends
|
||||
st.subheader("Current Trends")
|
||||
for trend in research_results["trends"]:
|
||||
st.markdown(f"- {trend}")
|
||||
else:
|
||||
st.warning("No insights found. Try adjusting your topic or using a different research source.")
|
||||
else:
|
||||
st.info("Please enter a topic and industry in the Script Details tab to research insights.")
|
||||
|
||||
with tab3:
|
||||
st.header("Generated Script")
|
||||
|
||||
if all([topic, industry, video_type, length, target_audience, tone]):
|
||||
if st.button("Generate Script"):
|
||||
with st.spinner("Generating video script..."):
|
||||
# Get insights from research if available
|
||||
insights = []
|
||||
if hasattr(st.session_state, 'research_results'):
|
||||
insights = st.session_state.research_results.get("insights", [])
|
||||
|
||||
# Generate full script
|
||||
script = generator.generate_full_script(
|
||||
topic=topic,
|
||||
video_type=video_type,
|
||||
length=length,
|
||||
target_audience=target_audience,
|
||||
tone=tone,
|
||||
insights=insights
|
||||
)
|
||||
|
||||
if script:
|
||||
# Display hook
|
||||
st.subheader("Hook")
|
||||
st.write(script["hook"])
|
||||
|
||||
# Display structure
|
||||
st.subheader("Script Structure")
|
||||
for i, section in enumerate(script["structure"]["sections"], 1):
|
||||
with st.expander(f"Section {i}"):
|
||||
st.write(f"**Timing:** {section.get('timing', 'N/A')}")
|
||||
st.write(f"**Content:** {section.get('content', 'N/A')}")
|
||||
|
||||
# Display visual cues for this section
|
||||
if script["visuals"]:
|
||||
visual = next((v for v in script["visuals"] if v.get("section") == i), None)
|
||||
if visual:
|
||||
st.write("**Visual Elements:**")
|
||||
st.write(f"- Type: {visual.get('type', 'N/A')}")
|
||||
st.write(f"- Description: {visual.get('description', 'N/A')}")
|
||||
st.write(f"- Duration: {visual.get('duration', 'N/A')}")
|
||||
|
||||
# Display transitions
|
||||
st.subheader("Transitions")
|
||||
for transition in script["structure"]["transitions"]:
|
||||
st.markdown(f"- {transition}")
|
||||
|
||||
# Display key points
|
||||
st.subheader("Key Points to Emphasize")
|
||||
for point in script["structure"]["key_points"]:
|
||||
st.markdown(f"- {point}")
|
||||
|
||||
# Display CTA
|
||||
st.subheader("Call-to-Action")
|
||||
st.write(f"**Primary CTA:** {script['cta'].get('primary_cta', 'N/A')}")
|
||||
if script['cta'].get('secondary_cta'):
|
||||
st.write(f"**Secondary CTA:** {script['cta']['secondary_cta']}")
|
||||
|
||||
# Display engagement prompts
|
||||
if script['cta'].get('engagement_hooks'):
|
||||
st.subheader("Engagement Prompts")
|
||||
for prompt in script['cta']['engagement_hooks']:
|
||||
st.markdown(f"- {prompt}")
|
||||
|
||||
# Display hashtag suggestions
|
||||
if script['cta'].get('hashtag_suggestions'):
|
||||
st.subheader("Hashtag Suggestions")
|
||||
for hashtag in script['cta']['hashtag_suggestions']:
|
||||
st.markdown(f"- {hashtag}")
|
||||
|
||||
# Display pacing notes
|
||||
st.subheader("Pacing & Delivery Notes")
|
||||
for note in script["structure"]["pacing_notes"]:
|
||||
st.markdown(f"- {note}")
|
||||
else:
|
||||
st.error("Failed to generate script. Please try again.")
|
||||
else:
|
||||
st.info("Please fill in all required fields in the Script Details tab to generate a script.")
|
||||
Reference in New Issue
Block a user