1547 lines
70 KiB
Python
1547 lines
70 KiB
Python
"""
|
|
Calendar Generator Service
|
|
AI-powered service for generating comprehensive content calendars based on enterprise best practices.
|
|
"""
|
|
|
|
import json
|
|
import time
|
|
from datetime import datetime, timedelta
|
|
from typing import Dict, Any, List, Optional
|
|
from loguru import logger
|
|
|
|
from services.content_gap_analyzer.ai_engine_service import AIEngineService
|
|
from services.onboarding_data_service import OnboardingDataService
|
|
from services.content_gap_analyzer.keyword_researcher import KeywordResearcher
|
|
from services.content_gap_analyzer.competitor_analyzer import CompetitorAnalyzer
|
|
from services.ai_analysis_db_service import AIAnalysisDBService
|
|
from services.content_planning_db import ContentPlanningDBService
|
|
from services.ai_service_manager import AIServiceManager
|
|
|
|
class CalendarGeneratorService:
|
|
"""AI-powered content calendar generator for SMEs."""
|
|
|
|
def __init__(self):
|
|
self.ai_engine = AIEngineService()
|
|
self.onboarding_service = OnboardingDataService()
|
|
self.keyword_researcher = KeywordResearcher()
|
|
self.competitor_analyzer = CompetitorAnalyzer()
|
|
self.ai_analysis_db_service = AIAnalysisDBService()
|
|
# Initialize content planning db service as None - will be set when needed
|
|
self.content_planning_db_service = None
|
|
|
|
# Enterprise content calendar templates
|
|
self.content_pillars = {
|
|
"technology": ["Educational Content", "Thought Leadership", "Product Updates", "Industry Insights", "Team Culture"],
|
|
"healthcare": ["Patient Education", "Medical Insights", "Health Tips", "Industry News", "Expert Opinions"],
|
|
"finance": ["Financial Education", "Market Analysis", "Investment Tips", "Regulatory Updates", "Success Stories"],
|
|
"education": ["Learning Resources", "Teaching Tips", "Student Success", "Industry Trends", "Innovation"],
|
|
"retail": ["Product Showcases", "Shopping Tips", "Customer Stories", "Trend Analysis", "Behind the Scenes"],
|
|
"manufacturing": ["Industry Insights", "Process Improvements", "Technology Updates", "Case Studies", "Team Spotlights"]
|
|
}
|
|
|
|
self.platform_strategies = {
|
|
"website": {
|
|
"content_types": ["blog_posts", "case_studies", "whitepapers", "product_pages"],
|
|
"frequency": "2-3 per week",
|
|
"optimal_length": "1500+ words",
|
|
"tone": "professional, educational"
|
|
},
|
|
"linkedin": {
|
|
"content_types": ["industry_insights", "professional_tips", "company_updates", "employee_spotlights"],
|
|
"frequency": "daily",
|
|
"optimal_length": "100-300 words",
|
|
"tone": "professional, thought leadership"
|
|
},
|
|
"instagram": {
|
|
"content_types": ["behind_scenes", "product_demos", "team_culture", "infographics"],
|
|
"frequency": "daily",
|
|
"optimal_length": "visual focus",
|
|
"tone": "casual, engaging"
|
|
},
|
|
"youtube": {
|
|
"content_types": ["tutorial_videos", "product_demos", "customer_testimonials", "industry_interviews"],
|
|
"frequency": "weekly",
|
|
"optimal_length": "5-15 minutes",
|
|
"tone": "educational, conversational"
|
|
},
|
|
"twitter": {
|
|
"content_types": ["industry_news", "quick_tips", "event_announcements", "community_engagement"],
|
|
"frequency": "3-5 per day",
|
|
"optimal_length": "280 characters",
|
|
"tone": "informative, conversational"
|
|
}
|
|
}
|
|
|
|
self.content_mix = {
|
|
"educational": 0.40,
|
|
"thought_leadership": 0.30,
|
|
"engagement": 0.20,
|
|
"promotional": 0.10
|
|
}
|
|
|
|
async def generate_comprehensive_calendar(
|
|
self,
|
|
user_id: int,
|
|
strategy_id: Optional[int] = None,
|
|
calendar_type: str = "monthly",
|
|
industry: Optional[str] = None,
|
|
business_size: str = "sme"
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Generate a comprehensive content calendar using AI with database-driven insights.
|
|
|
|
Args:
|
|
user_id: User ID
|
|
strategy_id: Content strategy ID
|
|
calendar_type: Type of calendar (monthly, weekly, custom)
|
|
industry: Business industry
|
|
business_size: Business size (startup, sme, enterprise)
|
|
|
|
Returns:
|
|
Comprehensive calendar with AI insights and recommendations
|
|
"""
|
|
try:
|
|
logger.info(f"🚀 Starting comprehensive calendar generation for user {user_id}")
|
|
start_time = time.time()
|
|
|
|
# Get comprehensive user data from database
|
|
user_data = await self._get_comprehensive_user_data(user_id, strategy_id)
|
|
industry = industry or user_data.get("industry", "technology")
|
|
|
|
# Generate calendar components using database insights
|
|
calendar_data = {
|
|
"user_id": user_id,
|
|
"strategy_id": strategy_id,
|
|
"calendar_type": calendar_type,
|
|
"industry": industry,
|
|
"business_size": business_size,
|
|
"generated_at": datetime.utcnow().isoformat(),
|
|
"content_pillars": self._get_content_pillars(industry),
|
|
"platform_strategies": self.platform_strategies,
|
|
"content_mix": self.content_mix,
|
|
"daily_schedule": await self._generate_daily_schedule_with_db_data(calendar_type, industry, user_data),
|
|
"weekly_themes": await self._generate_weekly_themes_with_db_data(calendar_type, industry, user_data),
|
|
"content_recommendations": await self._generate_content_recommendations_with_db_data(user_data, industry),
|
|
"optimal_timing": await self._generate_optimal_timing_with_db_data(industry, user_data),
|
|
"performance_predictions": await self._generate_performance_predictions_with_db_data(industry, user_data),
|
|
"trending_topics": await self._get_trending_topics_from_db(industry, user_data),
|
|
"repurposing_opportunities": await self._generate_repurposing_opportunities_with_db_data(user_data),
|
|
"ai_insights": await self._generate_ai_insights_with_db_data(user_data, industry),
|
|
"competitor_analysis": await self._analyze_competitors_with_db_data(user_data, industry),
|
|
"gap_analysis_insights": user_data.get("gap_analysis", {}),
|
|
"strategy_insights": user_data.get("strategy_data", {}),
|
|
"onboarding_insights": user_data.get("onboarding_data", {})
|
|
}
|
|
|
|
processing_time = time.time() - start_time
|
|
calendar_data["processing_time"] = processing_time
|
|
calendar_data["ai_confidence"] = 0.90 # Higher confidence with database-driven insights
|
|
|
|
logger.info(f"✅ Calendar generation completed in {processing_time:.2f}s")
|
|
return calendar_data
|
|
|
|
except Exception as e:
|
|
logger.error(f"❌ Error generating calendar: {str(e)}")
|
|
raise
|
|
|
|
async def generate_ai_powered_calendar(
|
|
self,
|
|
user_id: int,
|
|
strategy_id: Optional[int] = None,
|
|
calendar_type: str = "monthly",
|
|
industry: Optional[str] = None,
|
|
business_size: str = "sme"
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Generate an AI-powered content calendar using comprehensive database insights.
|
|
This is the enhanced version with full data transparency and advanced features.
|
|
"""
|
|
try:
|
|
logger.info(f"Generating AI-powered calendar for user {user_id}")
|
|
start_time = time.time()
|
|
|
|
# Get comprehensive user data
|
|
user_data = await self._get_comprehensive_user_data(user_id, strategy_id)
|
|
|
|
# Generate calendar using AI insights
|
|
calendar_data = await self._generate_calendar_with_advanced_ai(
|
|
user_data, calendar_type, industry, business_size
|
|
)
|
|
|
|
# Add performance predictions
|
|
performance_predictions = await self._predict_calendar_performance(
|
|
calendar_data, user_data
|
|
)
|
|
|
|
# Add trending topics integration
|
|
trending_topics = await self._get_trending_topics_for_calendar(
|
|
user_data, industry
|
|
)
|
|
|
|
# Add content repurposing opportunities
|
|
repurposing_opportunities = await self._identify_repurposing_opportunities(
|
|
calendar_data, user_data
|
|
)
|
|
|
|
processing_time = time.time() - start_time
|
|
|
|
return {
|
|
"user_id": user_id,
|
|
"strategy_id": strategy_id,
|
|
"calendar_type": calendar_type,
|
|
"industry": industry or user_data.get("industry", "technology"),
|
|
"business_size": business_size,
|
|
"generated_at": datetime.now().isoformat(),
|
|
"content_pillars": calendar_data.get("content_pillars", []),
|
|
"platform_strategies": calendar_data.get("platform_strategies", {}),
|
|
"content_mix": calendar_data.get("content_mix", {}),
|
|
"daily_schedule": calendar_data.get("daily_schedule", []),
|
|
"weekly_themes": calendar_data.get("weekly_themes", []),
|
|
"content_recommendations": calendar_data.get("content_recommendations", []),
|
|
"optimal_timing": calendar_data.get("optimal_timing", {}),
|
|
"performance_predictions": performance_predictions,
|
|
"trending_topics": trending_topics,
|
|
"repurposing_opportunities": repurposing_opportunities,
|
|
"ai_insights": calendar_data.get("ai_insights", []),
|
|
"competitor_analysis": user_data.get("competitor_analysis", {}),
|
|
"gap_analysis_insights": user_data.get("gap_analysis", {}),
|
|
"strategy_insights": user_data.get("strategy_data", {}),
|
|
"onboarding_insights": user_data.get("onboarding_data", {}),
|
|
"processing_time": processing_time,
|
|
"ai_confidence": 0.95
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating AI-powered calendar: {str(e)}")
|
|
raise
|
|
|
|
async def _get_comprehensive_user_data(self, user_id: int, strategy_id: Optional[int]) -> Dict[str, Any]:
|
|
"""Get comprehensive user data from all database sources."""
|
|
try:
|
|
logger.info(f"Getting comprehensive user data for user {user_id}")
|
|
|
|
# Get onboarding data (not async)
|
|
onboarding_data = self.onboarding_service.get_personalized_ai_inputs(user_id)
|
|
|
|
# Get AI analysis results from the working endpoint
|
|
try:
|
|
from services.ai_analytics_service import AIAnalyticsService
|
|
ai_analytics = AIAnalyticsService()
|
|
ai_analysis_results = await ai_analytics.generate_strategic_intelligence(strategy_id or 1)
|
|
except Exception as e:
|
|
logger.warning(f"Could not get AI analysis results: {str(e)}")
|
|
ai_analysis_results = {"insights": [], "recommendations": []}
|
|
|
|
# Get gap analysis data from the working endpoint
|
|
try:
|
|
from services.content_gap_analyzer.ai_engine_service import AIEngineService
|
|
ai_engine = AIEngineService()
|
|
gap_analysis_data = await ai_engine.generate_content_recommendations(onboarding_data)
|
|
except Exception as e:
|
|
logger.warning(f"Could not get gap analysis data: {str(e)}")
|
|
gap_analysis_data = []
|
|
|
|
# Get content strategy data
|
|
strategy_data = {}
|
|
if strategy_id:
|
|
strategy_data = await self._get_strategy_data(strategy_id)
|
|
|
|
# Get content recommendations
|
|
recommendations_data = await self._get_recommendations_data(user_id, strategy_id)
|
|
|
|
# Get performance metrics
|
|
performance_data = await self._get_performance_data(user_id, strategy_id)
|
|
|
|
# Build comprehensive response
|
|
comprehensive_data = {
|
|
"user_id": user_id,
|
|
"onboarding_data": onboarding_data,
|
|
"ai_analysis_results": ai_analysis_results,
|
|
"gap_analysis": {
|
|
"content_gaps": gap_analysis_data if isinstance(gap_analysis_data, list) else [],
|
|
"keyword_opportunities": onboarding_data.get("keyword_analysis", {}).get("high_value_keywords", []),
|
|
"competitor_insights": onboarding_data.get("competitor_analysis", {}).get("top_performers", []),
|
|
"recommendations": gap_analysis_data if isinstance(gap_analysis_data, list) else [],
|
|
"opportunities": onboarding_data.get("gap_analysis", {}).get("content_opportunities", [])
|
|
},
|
|
"strategy_data": strategy_data,
|
|
"recommendations_data": recommendations_data,
|
|
"performance_data": performance_data,
|
|
"industry": onboarding_data.get("website_analysis", {}).get("industry_focus", "technology"),
|
|
"target_audience": onboarding_data.get("website_analysis", {}).get("target_audience", []),
|
|
"business_goals": ["Increase brand awareness", "Generate leads", "Establish thought leadership"],
|
|
"website_analysis": onboarding_data.get("website_analysis", {}),
|
|
"competitor_analysis": onboarding_data.get("competitor_analysis", {}),
|
|
"keyword_analysis": onboarding_data.get("keyword_analysis", {})
|
|
}
|
|
|
|
logger.info(f"✅ Successfully retrieved comprehensive user data for user {user_id}")
|
|
return comprehensive_data
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting comprehensive user data: {str(e)}")
|
|
return {"user_id": user_id, "industry": "technology"}
|
|
|
|
async def _get_gap_analysis_data(self, user_id: int) -> Dict[str, Any]:
|
|
"""Get gap analysis data from database."""
|
|
try:
|
|
# Check if database service is available
|
|
if self.content_planning_db_service is None:
|
|
logger.warning("ContentPlanningDBService not available, returning empty gap analysis data")
|
|
return {}
|
|
|
|
# Get latest gap analysis results using the correct method name
|
|
gap_analyses = await self.content_planning_db_service.get_user_content_gap_analyses(user_id)
|
|
|
|
if gap_analyses:
|
|
latest_analysis = gap_analyses[0] # Get most recent
|
|
return {
|
|
"content_gaps": latest_analysis.get("analysis_results", {}).get("content_gaps", []),
|
|
"keyword_opportunities": latest_analysis.get("analysis_results", {}).get("keyword_opportunities", []),
|
|
"competitor_insights": latest_analysis.get("analysis_results", {}).get("competitor_insights", []),
|
|
"recommendations": latest_analysis.get("recommendations", []),
|
|
"opportunities": latest_analysis.get("opportunities", [])
|
|
}
|
|
return {}
|
|
except Exception as e:
|
|
logger.error(f"Error getting gap analysis data: {str(e)}")
|
|
return {}
|
|
|
|
async def _get_strategy_data(self, strategy_id: int) -> Dict[str, Any]:
|
|
"""Get content strategy data from database."""
|
|
try:
|
|
# Check if database service is available
|
|
if self.content_planning_db_service is None:
|
|
logger.warning("ContentPlanningDBService not available, returning empty strategy data")
|
|
return {}
|
|
|
|
strategy = await self.content_planning_db_service.get_content_strategy(strategy_id)
|
|
if strategy:
|
|
return {
|
|
"content_pillars": strategy.get("content_pillars", []),
|
|
"target_audience": strategy.get("target_audience", {}),
|
|
"ai_recommendations": strategy.get("ai_recommendations", {}),
|
|
"industry": strategy.get("industry", ""),
|
|
"business_goals": strategy.get("business_goals", [])
|
|
}
|
|
return {}
|
|
except Exception as e:
|
|
logger.error(f"Error getting strategy data: {str(e)}")
|
|
return {}
|
|
|
|
async def _get_recommendations_data(self, user_id: int, strategy_id: Optional[int]) -> List[Dict[str, Any]]:
|
|
"""Get content recommendations from database."""
|
|
try:
|
|
# Check if database service is available
|
|
if self.content_planning_db_service is None:
|
|
logger.warning("ContentPlanningDBService not available, returning empty recommendations data")
|
|
return []
|
|
|
|
recommendations = await self.content_planning_db_service.get_user_content_recommendations(user_id)
|
|
return recommendations or []
|
|
except Exception as e:
|
|
logger.error(f"Error getting recommendations data: {str(e)}")
|
|
return []
|
|
|
|
async def _get_performance_data(self, user_id: int, strategy_id: Optional[int]) -> Dict[str, Any]:
|
|
"""Get performance data from database."""
|
|
try:
|
|
# Check if database service is available
|
|
if self.content_planning_db_service is None:
|
|
logger.warning("ContentPlanningDBService not available, returning empty performance data")
|
|
return {}
|
|
|
|
# For now, return empty performance data since the method might not exist
|
|
# This can be enhanced later when performance tracking is implemented
|
|
return {}
|
|
except Exception as e:
|
|
logger.error(f"Error getting performance data: {str(e)}")
|
|
return {}
|
|
|
|
def _get_content_pillars(self, industry: str) -> List[str]:
|
|
"""Get content pillars for the industry."""
|
|
return self.content_pillars.get(industry, self.content_pillars["technology"])
|
|
|
|
async def _generate_daily_schedule_with_db_data(self, calendar_type: str, industry: str, user_data: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
"""Generate daily content schedule using database insights."""
|
|
try:
|
|
# Extract relevant data from user_data
|
|
gap_analysis = user_data.get("gap_analysis", {})
|
|
strategy_data = user_data.get("strategy_data", {})
|
|
onboarding_data = user_data.get("onboarding_data", {})
|
|
recommendations = user_data.get("recommendations_data", [])
|
|
|
|
prompt = f"""
|
|
Create a comprehensive daily content schedule for a {industry} business using the following specific data:
|
|
|
|
GAP ANALYSIS INSIGHTS:
|
|
- Content Gaps: {gap_analysis.get('content_gaps', [])}
|
|
- Keyword Opportunities: {gap_analysis.get('keyword_opportunities', [])}
|
|
- Competitor Insights: {gap_analysis.get('competitor_insights', [])}
|
|
- Recommendations: {gap_analysis.get('recommendations', [])}
|
|
|
|
STRATEGY DATA:
|
|
- Content Pillars: {strategy_data.get('content_pillars', [])}
|
|
- Target Audience: {strategy_data.get('target_audience', {})}
|
|
- AI Recommendations: {strategy_data.get('ai_recommendations', {})}
|
|
|
|
ONBOARDING DATA:
|
|
- Website Analysis: {onboarding_data.get('website_analysis', {})}
|
|
- Competitor Analysis: {onboarding_data.get('competitor_analysis', {})}
|
|
- Keyword Analysis: {onboarding_data.get('keyword_analysis', {})}
|
|
|
|
EXISTING RECOMMENDATIONS:
|
|
- Content Recommendations: {recommendations}
|
|
|
|
Requirements:
|
|
- Generate {calendar_type} schedule
|
|
- Address specific content gaps identified
|
|
- Incorporate keyword opportunities
|
|
- Use competitor insights for differentiation
|
|
- Align with existing content pillars
|
|
- Consider target audience preferences
|
|
- Balance educational, thought leadership, engagement, and promotional content
|
|
|
|
Return a structured schedule that specifically addresses the identified gaps and opportunities.
|
|
"""
|
|
|
|
response = await self.ai_engine.generate_structured_response(
|
|
prompt=prompt,
|
|
schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"daily_schedule": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"day": {"type": "string"},
|
|
"theme": {"type": "string"},
|
|
"content_types": {"type": "array", "items": {"type": "string"}},
|
|
"platforms": {"type": "array", "items": {"type": "string"}},
|
|
"optimal_times": {"type": "array", "items": {"type": "string"}},
|
|
"content_mix": {"type": "object"},
|
|
"gap_addresses": {"type": "array", "items": {"type": "string"}},
|
|
"keyword_focus": {"type": "array", "items": {"type": "string"}},
|
|
"competitor_differentiation": {"type": "string"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
return response.get("daily_schedule", [])
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating daily schedule with DB data: {str(e)}")
|
|
return self._get_default_daily_schedule(calendar_type)
|
|
|
|
async def _generate_weekly_themes_with_db_data(self, calendar_type: str, industry: str, user_data: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
"""Generate weekly content themes using database insights."""
|
|
try:
|
|
gap_analysis = user_data.get("gap_analysis", {})
|
|
strategy_data = user_data.get("strategy_data", {})
|
|
onboarding_data = user_data.get("onboarding_data", {})
|
|
|
|
prompt = f"""
|
|
Create weekly content themes for a {industry} business using specific database insights:
|
|
|
|
CONTENT GAPS TO ADDRESS:
|
|
- Identified Gaps: {gap_analysis.get('content_gaps', [])}
|
|
- Opportunities: {gap_analysis.get('opportunities', [])}
|
|
|
|
STRATEGY FOUNDATION:
|
|
- Content Pillars: {strategy_data.get('content_pillars', [])}
|
|
- Target Audience: {strategy_data.get('target_audience', {})}
|
|
|
|
COMPETITOR INSIGHTS:
|
|
- Competitor Analysis: {onboarding_data.get('competitor_analysis', {})}
|
|
- Industry Position: {onboarding_data.get('website_analysis', {}).get('industry_focus', '')}
|
|
|
|
Requirements:
|
|
- Generate {calendar_type} themes that address specific gaps
|
|
- Align with existing content pillars
|
|
- Incorporate competitor insights for differentiation
|
|
- Focus on identified opportunities
|
|
- Consider seasonal and trending topics
|
|
- Balance different content types based on audience preferences
|
|
|
|
Return structured weekly themes that specifically address the identified gaps and opportunities.
|
|
"""
|
|
|
|
response = await self.ai_engine.generate_structured_response(
|
|
prompt=prompt,
|
|
schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"weekly_themes": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"week": {"type": "string"},
|
|
"theme": {"type": "string"},
|
|
"focus_areas": {"type": "array", "items": {"type": "string"}},
|
|
"trending_topics": {"type": "array", "items": {"type": "string"}},
|
|
"content_types": {"type": "array", "items": {"type": "string"}},
|
|
"gap_addresses": {"type": "array", "items": {"type": "string"}},
|
|
"competitor_differentiation": {"type": "string"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
return response.get("weekly_themes", [])
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating weekly themes with DB data: {str(e)}")
|
|
return self._get_default_weekly_themes(calendar_type)
|
|
|
|
async def _generate_content_recommendations_with_db_data(self, user_data: Dict[str, Any], industry: str) -> List[Dict[str, Any]]:
|
|
"""Generate specific content recommendations using database insights."""
|
|
try:
|
|
gap_analysis = user_data.get("gap_analysis", {})
|
|
strategy_data = user_data.get("strategy_data", {})
|
|
onboarding_data = user_data.get("onboarding_data", {})
|
|
existing_recommendations = user_data.get("recommendations_data", [])
|
|
|
|
prompt = f"""
|
|
Generate specific content recommendations for a {industry} business using comprehensive database insights:
|
|
|
|
CONTENT GAPS TO FILL:
|
|
- Identified Gaps: {gap_analysis.get('content_gaps', [])}
|
|
- Keyword Opportunities: {gap_analysis.get('keyword_opportunities', [])}
|
|
- Competitor Insights: {gap_analysis.get('competitor_insights', [])}
|
|
|
|
STRATEGY CONTEXT:
|
|
- Content Pillars: {strategy_data.get('content_pillars', [])}
|
|
- Target Audience: {strategy_data.get('target_audience', {})}
|
|
- AI Recommendations: {strategy_data.get('ai_recommendations', {})}
|
|
|
|
AUDIENCE INSIGHTS:
|
|
- Website Analysis: {onboarding_data.get('website_analysis', {})}
|
|
- Target Demographics: {onboarding_data.get('target_audience', {})}
|
|
- Content Preferences: {onboarding_data.get('keyword_analysis', {}).get('content_topics', [])}
|
|
|
|
EXISTING RECOMMENDATIONS:
|
|
- Current Recommendations: {existing_recommendations}
|
|
|
|
Requirements:
|
|
- Create specific content ideas that address identified gaps
|
|
- Incorporate keyword opportunities
|
|
- Use competitor insights for differentiation
|
|
- Align with content pillars and audience preferences
|
|
- Predict performance based on existing data
|
|
- Provide implementation suggestions
|
|
|
|
Return structured recommendations that specifically address the database insights.
|
|
"""
|
|
|
|
response = await self.ai_engine.generate_structured_response(
|
|
prompt=prompt,
|
|
schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"content_recommendations": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"title": {"type": "string"},
|
|
"description": {"type": "string"},
|
|
"content_type": {"type": "string"},
|
|
"platforms": {"type": "array", "items": {"type": "string"}},
|
|
"target_audience": {"type": "string"},
|
|
"estimated_performance": {"type": "object"},
|
|
"implementation_tips": {"type": "array", "items": {"type": "string"}},
|
|
"gap_addresses": {"type": "array", "items": {"type": "string"}},
|
|
"keyword_focus": {"type": "array", "items": {"type": "string"}},
|
|
"competitor_differentiation": {"type": "string"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
return response.get("content_recommendations", [])
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating content recommendations with DB data: {str(e)}")
|
|
return self._get_default_content_recommendations(industry)
|
|
|
|
async def _generate_optimal_timing_with_db_data(self, industry: str, user_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Generate optimal posting times using database insights."""
|
|
try:
|
|
performance_data = user_data.get("performance_data", {})
|
|
onboarding_data = user_data.get("onboarding_data", {})
|
|
|
|
prompt = f"""
|
|
Generate optimal posting times for different social media platforms for a {industry} business using performance data:
|
|
|
|
PERFORMANCE INSIGHTS:
|
|
- Historical Performance: {performance_data}
|
|
- Audience Demographics: {onboarding_data.get('target_audience', {})}
|
|
- Website Analysis: {onboarding_data.get('website_analysis', {})}
|
|
|
|
Requirements:
|
|
- Consider industry-specific audience behavior
|
|
- Use historical performance data to optimize timing
|
|
- Include multiple platforms (LinkedIn, Instagram, Twitter, YouTube)
|
|
- Provide specific time recommendations based on audience data
|
|
- Include frequency guidelines
|
|
- Consider timezone considerations
|
|
|
|
Return structured timing recommendations based on actual performance data.
|
|
"""
|
|
|
|
response = await self.ai_engine.generate_structured_response(
|
|
prompt=prompt,
|
|
schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"optimal_timing": {
|
|
"type": "object",
|
|
"properties": {
|
|
"linkedin": {"type": "object"},
|
|
"instagram": {"type": "object"},
|
|
"twitter": {"type": "object"},
|
|
"youtube": {"type": "object"},
|
|
"website": {"type": "object"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
return response.get("optimal_timing", {})
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating optimal timing with DB data: {str(e)}")
|
|
return self._get_default_optimal_timing()
|
|
|
|
async def _generate_performance_predictions_with_db_data(self, industry: str, user_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Generate performance predictions using database insights."""
|
|
try:
|
|
performance_data = user_data.get("performance_data", {})
|
|
gap_analysis = user_data.get("gap_analysis", {})
|
|
onboarding_data = user_data.get("onboarding_data", {})
|
|
|
|
prompt = f"""
|
|
Generate performance predictions for different content types in the {industry} industry using database insights:
|
|
|
|
HISTORICAL PERFORMANCE:
|
|
- Performance Data: {performance_data}
|
|
- Engagement Patterns: {performance_data.get('engagement_patterns', {})}
|
|
- Conversion Data: {performance_data.get('conversion_data', {})}
|
|
|
|
CONTENT OPPORTUNITIES:
|
|
- Content Gaps: {gap_analysis.get('content_gaps', [])}
|
|
- Keyword Opportunities: {gap_analysis.get('keyword_opportunities', [])}
|
|
|
|
AUDIENCE INSIGHTS:
|
|
- Target Demographics: {onboarding_data.get('target_audience', {})}
|
|
- Content Preferences: {onboarding_data.get('keyword_analysis', {}).get('content_topics', [])}
|
|
|
|
Requirements:
|
|
- Predict engagement rates based on historical data
|
|
- Estimate reach and impressions using audience insights
|
|
- Consider industry benchmarks
|
|
- Include conversion predictions based on gap analysis
|
|
- Provide ROI estimates using performance data
|
|
|
|
Return structured predictions based on actual database insights.
|
|
"""
|
|
|
|
response = await self.ai_engine.generate_structured_response(
|
|
prompt=prompt,
|
|
schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"performance_predictions": {
|
|
"type": "object",
|
|
"properties": {
|
|
"content_types": {"type": "object"},
|
|
"platforms": {"type": "object"},
|
|
"industry_benchmarks": {"type": "object"},
|
|
"roi_estimates": {"type": "object"},
|
|
"gap_opportunities": {"type": "object"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
return response.get("performance_predictions", {})
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating performance predictions with DB data: {str(e)}")
|
|
return self._get_default_performance_predictions()
|
|
|
|
async def _get_trending_topics_from_db(self, industry: str, user_data: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
"""Get trending topics using database insights."""
|
|
try:
|
|
gap_analysis = user_data.get("gap_analysis", {})
|
|
onboarding_data = user_data.get("onboarding_data", {})
|
|
|
|
# Use keyword researcher with database insights
|
|
keywords = [industry, "trending", "latest"]
|
|
if gap_analysis.get('keyword_opportunities'):
|
|
keywords.extend(gap_analysis['keyword_opportunities'][:5])
|
|
|
|
trending_data = await self.keyword_researcher.analyze_keywords(
|
|
keywords=keywords,
|
|
analysis_type="trend_analysis"
|
|
)
|
|
|
|
# Enhance with database insights
|
|
enhanced_trends = trending_data.get("trending_topics", [])
|
|
for trend in enhanced_trends:
|
|
trend["gap_relevance"] = self._assess_gap_relevance(trend, gap_analysis)
|
|
trend["audience_alignment"] = self._assess_audience_alignment(trend, onboarding_data)
|
|
|
|
return enhanced_trends
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting trending topics from DB: {str(e)}")
|
|
return []
|
|
|
|
async def _generate_repurposing_opportunities_with_db_data(self, user_data: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
"""Generate content repurposing opportunities using database insights."""
|
|
try:
|
|
gap_analysis = user_data.get("gap_analysis", {})
|
|
strategy_data = user_data.get("strategy_data", {})
|
|
recommendations = user_data.get("recommendations_data", [])
|
|
|
|
prompt = f"""
|
|
Generate content repurposing opportunities using database insights:
|
|
|
|
CONTENT GAPS:
|
|
- Identified Gaps: {gap_analysis.get('content_gaps', [])}
|
|
- Opportunities: {gap_analysis.get('opportunities', [])}
|
|
|
|
EXISTING CONTENT:
|
|
- Content Pillars: {strategy_data.get('content_pillars', [])}
|
|
- Recommendations: {recommendations}
|
|
|
|
Requirements:
|
|
- Identify how to adapt existing content to fill gaps
|
|
- Suggest content transformations based on opportunities
|
|
- Include platform-specific adaptations
|
|
- Consider audience preferences per platform
|
|
- Focus on addressing identified content gaps
|
|
|
|
Return structured repurposing opportunities that address specific database insights.
|
|
"""
|
|
|
|
response = await self.ai_engine.generate_structured_response(
|
|
prompt=prompt,
|
|
schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"repurposing_opportunities": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"original_content": {"type": "string"},
|
|
"platform_adaptations": {"type": "array", "items": {"type": "string"}},
|
|
"transformations": {"type": "array", "items": {"type": "string"}},
|
|
"implementation_tips": {"type": "array", "items": {"type": "string"}},
|
|
"gap_addresses": {"type": "array", "items": {"type": "string"}}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
return response.get("repurposing_opportunities", [])
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating repurposing opportunities with DB data: {str(e)}")
|
|
return []
|
|
|
|
async def _generate_ai_insights_with_db_data(self, user_data: Dict[str, Any], industry: str) -> List[Dict[str, Any]]:
|
|
"""Generate AI insights using database insights."""
|
|
try:
|
|
gap_analysis = user_data.get("gap_analysis", {})
|
|
strategy_data = user_data.get("strategy_data", {})
|
|
onboarding_data = user_data.get("onboarding_data", {})
|
|
performance_data = user_data.get("performance_data", {})
|
|
|
|
prompt = f"""
|
|
Generate AI insights for content planning in the {industry} industry using comprehensive database insights:
|
|
|
|
CONTENT GAPS:
|
|
- Identified Gaps: {gap_analysis.get('content_gaps', [])}
|
|
- Opportunities: {gap_analysis.get('opportunities', [])}
|
|
|
|
STRATEGY CONTEXT:
|
|
- Content Pillars: {strategy_data.get('content_pillars', [])}
|
|
- Target Audience: {strategy_data.get('target_audience', {})}
|
|
|
|
PERFORMANCE DATA:
|
|
- Historical Performance: {performance_data}
|
|
- Engagement Patterns: {performance_data.get('engagement_patterns', {})}
|
|
|
|
AUDIENCE INSIGHTS:
|
|
- Target Demographics: {onboarding_data.get('target_audience', {})}
|
|
- Website Analysis: {onboarding_data.get('website_analysis', {})}
|
|
|
|
Requirements:
|
|
- Provide strategic insights based on gap analysis
|
|
- Include content optimization tips using performance data
|
|
- Suggest audience engagement strategies
|
|
- Consider industry trends and competitor analysis
|
|
- Include performance optimization insights
|
|
|
|
Return structured insights that specifically address the database insights.
|
|
"""
|
|
|
|
response = await self.ai_engine.generate_structured_response(
|
|
prompt=prompt,
|
|
schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"ai_insights": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"insight_type": {"type": "string"},
|
|
"title": {"type": "string"},
|
|
"description": {"type": "string"},
|
|
"recommendations": {"type": "array", "items": {"type": "string"}},
|
|
"priority": {"type": "string"},
|
|
"data_source": {"type": "string"},
|
|
"gap_addresses": {"type": "array", "items": {"type": "string"}}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
return response.get("ai_insights", [])
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating AI insights with DB data: {str(e)}")
|
|
return []
|
|
|
|
async def _analyze_competitors_with_db_data(self, user_data: Dict[str, Any], industry: str) -> Dict[str, Any]:
|
|
"""Analyze competitors using database insights."""
|
|
try:
|
|
gap_analysis = user_data.get("gap_analysis", {})
|
|
onboarding_data = user_data.get("onboarding_data", {})
|
|
|
|
# Use competitor analyzer with database insights
|
|
competitor_data = await self.competitor_analyzer.analyze_competitors(
|
|
industry=industry,
|
|
analysis_type="content_gaps",
|
|
competitor_urls=onboarding_data.get('competitor_analysis', {}).get('top_performers', [])
|
|
)
|
|
|
|
# Enhance with gap analysis insights
|
|
enhanced_competitor_data = competitor_data or {}
|
|
enhanced_competitor_data["gap_opportunities"] = gap_analysis.get("opportunities", [])
|
|
enhanced_competitor_data["content_differentiation"] = gap_analysis.get("competitor_insights", [])
|
|
|
|
return enhanced_competitor_data
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error analyzing competitors with DB data: {str(e)}")
|
|
return {}
|
|
|
|
def _assess_gap_relevance(self, trend: Dict[str, Any], gap_analysis: Dict[str, Any]) -> str:
|
|
"""Assess how relevant a trending topic is to identified gaps."""
|
|
try:
|
|
content_gaps = gap_analysis.get("content_gaps", [])
|
|
trend_title = trend.get("keyword", "").lower()
|
|
|
|
for gap in content_gaps:
|
|
if any(word in trend_title for word in gap.lower().split()):
|
|
return "high"
|
|
|
|
return "medium"
|
|
except Exception:
|
|
return "low"
|
|
|
|
def _assess_audience_alignment(self, trend: Dict[str, Any], onboarding_data: Dict[str, Any]) -> str:
|
|
"""Assess how well a trending topic aligns with target audience."""
|
|
try:
|
|
target_audience = onboarding_data.get("target_audience", {})
|
|
trend_title = trend.get("keyword", "").lower()
|
|
|
|
# Simple keyword matching - could be enhanced with more sophisticated analysis
|
|
audience_keywords = ["professional", "business", "industry", "technology", "marketing"]
|
|
|
|
if any(keyword in trend_title for keyword in audience_keywords):
|
|
return "high"
|
|
|
|
return "medium"
|
|
except Exception:
|
|
return "low"
|
|
|
|
def _get_default_daily_schedule(self, calendar_type: str) -> List[Dict[str, Any]]:
|
|
"""Get default daily schedule if AI generation fails."""
|
|
return [
|
|
{
|
|
"day": "Monday",
|
|
"theme": "Educational Content",
|
|
"content_types": ["blog_post", "how_to_guide"],
|
|
"platforms": ["website", "linkedin"],
|
|
"optimal_times": ["9:00 AM", "2:00 PM"],
|
|
"content_mix": {"educational": 0.6, "thought_leadership": 0.4}
|
|
},
|
|
{
|
|
"day": "Tuesday",
|
|
"theme": "Industry Insights",
|
|
"content_types": ["industry_analysis", "trend_report"],
|
|
"platforms": ["linkedin", "twitter"],
|
|
"optimal_times": ["10:00 AM", "3:00 PM"],
|
|
"content_mix": {"thought_leadership": 0.7, "educational": 0.3}
|
|
}
|
|
]
|
|
|
|
def _get_default_weekly_themes(self, calendar_type: str) -> List[Dict[str, Any]]:
|
|
"""Get default weekly themes if AI generation fails."""
|
|
return [
|
|
{
|
|
"week": "Week 1",
|
|
"theme": "Industry Fundamentals",
|
|
"focus_areas": ["Educational content", "Basic concepts"],
|
|
"trending_topics": ["Industry trends", "Best practices"],
|
|
"content_types": ["blog_posts", "infographics"]
|
|
}
|
|
]
|
|
|
|
def _get_default_content_recommendations(self, industry: str) -> List[Dict[str, Any]]:
|
|
"""Get default content recommendations if AI generation fails."""
|
|
return [
|
|
{
|
|
"title": f"Complete Guide to {industry.title()} Best Practices",
|
|
"description": f"A comprehensive guide covering essential {industry} practices and strategies.",
|
|
"content_type": "blog_post",
|
|
"platforms": ["website", "linkedin"],
|
|
"target_audience": "Industry professionals",
|
|
"estimated_performance": {"engagement_rate": 0.08, "reach": 5000},
|
|
"implementation_tips": ["Use industry keywords", "Include expert quotes", "Add visual elements"]
|
|
}
|
|
]
|
|
|
|
def _get_default_optimal_timing(self) -> Dict[str, Any]:
|
|
"""Get default optimal timing if AI generation fails."""
|
|
return {
|
|
"linkedin": {"optimal_times": ["9:00 AM", "2:00 PM"], "frequency": "daily"},
|
|
"instagram": {"optimal_times": ["12:00 PM", "7:00 PM"], "frequency": "daily"},
|
|
"twitter": {"optimal_times": ["8:00 AM", "12:00 PM", "5:00 PM"], "frequency": "3-5 per day"},
|
|
"youtube": {"optimal_times": ["2:00 PM", "7:00 PM"], "frequency": "weekly"},
|
|
"website": {"optimal_times": ["10:00 AM"], "frequency": "2-3 per week"}
|
|
}
|
|
|
|
def _get_default_performance_predictions(self) -> Dict[str, Any]:
|
|
"""Get default performance predictions if AI generation fails."""
|
|
return {
|
|
"content_types": {
|
|
"blog_posts": {"engagement_rate": 0.06, "reach": 3000},
|
|
"videos": {"engagement_rate": 0.12, "reach": 5000},
|
|
"infographics": {"engagement_rate": 0.15, "reach": 8000}
|
|
},
|
|
"platforms": {
|
|
"linkedin": {"engagement_rate": 0.08, "reach": 4000},
|
|
"instagram": {"engagement_rate": 0.10, "reach": 6000},
|
|
"twitter": {"engagement_rate": 0.05, "reach": 2000}
|
|
}
|
|
}
|
|
|
|
async def _generate_calendar_with_advanced_ai(
|
|
self,
|
|
user_data: Dict[str, Any],
|
|
calendar_type: str,
|
|
industry: str,
|
|
business_size: str
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Generate calendar using advanced AI with comprehensive database insights.
|
|
"""
|
|
try:
|
|
# Extract key data points
|
|
gap_analysis = user_data.get("gap_analysis", {})
|
|
ai_analysis = user_data.get("ai_analysis_results", {})
|
|
strategy_data = user_data.get("strategy_data", {})
|
|
|
|
# Generate content pillars based on gap analysis
|
|
content_pillars = self._generate_content_pillars_from_gaps(
|
|
gap_analysis, industry, business_size
|
|
)
|
|
|
|
# Generate daily schedule addressing specific gaps
|
|
daily_schedule = await self._generate_daily_schedule_addressing_gaps(
|
|
calendar_type, gap_analysis, content_pillars, user_data
|
|
)
|
|
|
|
# Generate weekly themes based on AI insights
|
|
weekly_themes = await self._generate_weekly_themes_from_ai_insights(
|
|
ai_analysis, content_pillars, calendar_type
|
|
)
|
|
|
|
# Generate platform-specific strategies
|
|
platform_strategies = self._generate_platform_strategies(
|
|
industry, business_size, content_pillars
|
|
)
|
|
|
|
# Generate optimal content mix
|
|
content_mix = self._generate_optimal_content_mix(
|
|
gap_analysis, ai_analysis, industry
|
|
)
|
|
|
|
# Generate content recommendations
|
|
content_recommendations = await self._generate_content_recommendations(
|
|
gap_analysis, ai_analysis, content_pillars
|
|
)
|
|
|
|
# Generate optimal timing
|
|
optimal_timing = await self._generate_optimal_timing(
|
|
user_data, industry, business_size
|
|
)
|
|
|
|
# Generate AI insights
|
|
ai_insights = await self._generate_calendar_ai_insights(
|
|
gap_analysis, ai_analysis, content_pillars
|
|
)
|
|
|
|
return {
|
|
"content_pillars": content_pillars,
|
|
"daily_schedule": daily_schedule,
|
|
"weekly_themes": weekly_themes,
|
|
"platform_strategies": platform_strategies,
|
|
"content_mix": content_mix,
|
|
"content_recommendations": content_recommendations,
|
|
"optimal_timing": optimal_timing,
|
|
"ai_insights": ai_insights
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in advanced AI calendar generation: {str(e)}")
|
|
raise
|
|
|
|
def _generate_content_pillars_from_gaps(
|
|
self,
|
|
gap_analysis: Dict[str, Any],
|
|
industry: str,
|
|
business_size: str
|
|
) -> List[str]:
|
|
"""
|
|
Generate content pillars based on identified gaps and industry best practices.
|
|
"""
|
|
# Get industry-specific content pillars
|
|
industry_pillars = self.content_pillars.get(industry, [
|
|
"Educational Content",
|
|
"Thought Leadership",
|
|
"Product Updates",
|
|
"Industry Insights",
|
|
"Team Culture"
|
|
])
|
|
|
|
# Add gap-specific pillars
|
|
gap_pillars = []
|
|
if gap_analysis.get("content_gaps"):
|
|
for gap in gap_analysis["content_gaps"][:3]: # Top 3 gaps
|
|
gap_type = gap.get("type", "Content Creation")
|
|
if gap_type not in gap_pillars:
|
|
gap_pillars.append(gap_type)
|
|
|
|
# Combine and prioritize
|
|
all_pillars = industry_pillars + gap_pillars
|
|
return list(dict.fromkeys(all_pillars))[:5] # Top 5 unique pillars
|
|
|
|
async def _generate_daily_schedule_addressing_gaps(
|
|
self,
|
|
calendar_type: str,
|
|
gap_analysis: Dict[str, Any],
|
|
content_pillars: List[str],
|
|
user_data: Dict[str, Any]
|
|
) -> List[Dict[str, Any]]:
|
|
"""
|
|
Generate daily schedule that specifically addresses identified content gaps.
|
|
"""
|
|
try:
|
|
# Get AI service for advanced scheduling
|
|
ai_manager = AIServiceManager()
|
|
|
|
# Prepare prompt with gap analysis data
|
|
gap_data = {
|
|
"content_gaps": gap_analysis.get("content_gaps", []),
|
|
"keyword_opportunities": gap_analysis.get("keyword_opportunities", []),
|
|
"recommendations": gap_analysis.get("recommendations", []),
|
|
"content_pillars": content_pillars,
|
|
"calendar_type": calendar_type,
|
|
"industry": user_data.get("industry", "technology"),
|
|
"business_size": user_data.get("business_size", "sme")
|
|
}
|
|
|
|
# Generate schedule using AI
|
|
schedule_prompt = f"""
|
|
Create a comprehensive {calendar_type} content schedule that addresses specific content gaps:
|
|
|
|
CONTENT GAPS TO ADDRESS:
|
|
{gap_analysis.get('content_gaps', [])}
|
|
|
|
KEYWORD OPPORTUNITIES:
|
|
{gap_analysis.get('keyword_opportunities', [])}
|
|
|
|
CONTENT PILLARS:
|
|
{content_pillars}
|
|
|
|
Requirements:
|
|
1. Address each identified content gap with specific content pieces
|
|
2. Incorporate keyword opportunities naturally
|
|
3. Balance content pillars throughout the schedule
|
|
4. Include specific titles, descriptions, and content types
|
|
5. Optimize for engagement and SEO
|
|
6. Consider industry best practices for {user_data.get('industry', 'technology')}
|
|
|
|
Return a structured schedule with daily content pieces.
|
|
"""
|
|
|
|
ai_response = await ai_manager.generate_content_schedule(schedule_prompt)
|
|
|
|
# Parse and structure the response
|
|
if isinstance(ai_response, dict) and "schedule" in ai_response:
|
|
return ai_response["schedule"]
|
|
else:
|
|
# Fallback to template-based generation
|
|
return self._generate_fallback_schedule(calendar_type, content_pillars)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating daily schedule: {str(e)}")
|
|
return self._generate_fallback_schedule(calendar_type, content_pillars)
|
|
|
|
async def _generate_weekly_themes_from_ai_insights(
|
|
self,
|
|
ai_analysis: Dict[str, Any],
|
|
content_pillars: List[str],
|
|
calendar_type: str
|
|
) -> List[Dict[str, Any]]:
|
|
"""
|
|
Generate weekly themes based on AI analysis insights.
|
|
"""
|
|
try:
|
|
themes = []
|
|
|
|
# Extract themes from AI analysis
|
|
if ai_analysis.get("market_positioning"):
|
|
positioning = ai_analysis["market_positioning"]
|
|
themes.append({
|
|
"week": 1,
|
|
"theme": f"Establishing {positioning.get('competitive_advantage', 'Content Quality')}",
|
|
"focus": "Building competitive advantage through content",
|
|
"content_types": ["thought_leadership", "case_studies", "expert_insights"]
|
|
})
|
|
|
|
# Add gap-based themes
|
|
if ai_analysis.get("gap_analysis"):
|
|
gap_themes = self._extract_themes_from_gaps(ai_analysis["gap_analysis"])
|
|
themes.extend(gap_themes)
|
|
|
|
# Add industry-specific themes
|
|
industry_themes = self._get_industry_themes(ai_analysis.get("industry", "technology"))
|
|
themes.extend(industry_themes)
|
|
|
|
return themes[:4] # Return top 4 themes
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating weekly themes: {str(e)}")
|
|
return []
|
|
|
|
def _generate_platform_strategies(
|
|
self,
|
|
industry: str,
|
|
business_size: str,
|
|
content_pillars: List[str]
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Generate platform-specific content strategies.
|
|
"""
|
|
return {
|
|
"website": {
|
|
"content_types": ["blog_posts", "case_studies", "whitepapers", "product_pages"],
|
|
"frequency": "2-3 per week",
|
|
"optimal_length": "1500+ words",
|
|
"tone": "professional, educational",
|
|
"content_pillars": content_pillars
|
|
},
|
|
"linkedin": {
|
|
"content_types": ["industry_insights", "professional_tips", "company_updates", "employee_spotlights"],
|
|
"frequency": "daily",
|
|
"optimal_length": "100-300 words",
|
|
"tone": "professional, thought leadership",
|
|
"content_pillars": content_pillars
|
|
},
|
|
"instagram": {
|
|
"content_types": ["behind_scenes", "product_demos", "team_culture", "infographics"],
|
|
"frequency": "daily",
|
|
"optimal_length": "visual focus",
|
|
"tone": "casual, engaging",
|
|
"content_pillars": content_pillars
|
|
},
|
|
"youtube": {
|
|
"content_types": ["tutorial_videos", "product_demos", "customer_testimonials", "industry_interviews"],
|
|
"frequency": "weekly",
|
|
"optimal_length": "5-15 minutes",
|
|
"tone": "educational, engaging",
|
|
"content_pillars": content_pillars
|
|
},
|
|
"twitter": {
|
|
"content_types": ["industry_news", "quick_tips", "event_announcements", "community_engagement"],
|
|
"frequency": "3-5 per day",
|
|
"optimal_length": "280 characters",
|
|
"tone": "informative, engaging",
|
|
"content_pillars": content_pillars
|
|
}
|
|
}
|
|
|
|
def _generate_optimal_content_mix(
|
|
self,
|
|
gap_analysis: Dict[str, Any],
|
|
ai_analysis: Dict[str, Any],
|
|
industry: str
|
|
) -> Dict[str, float]:
|
|
"""
|
|
Generate optimal content mix based on gap analysis and AI insights.
|
|
"""
|
|
# Base mix for industry
|
|
base_mix = {
|
|
"educational": 40,
|
|
"thought_leadership": 30,
|
|
"engagement": 20,
|
|
"promotional": 10
|
|
}
|
|
|
|
# Adjust based on gap analysis
|
|
if gap_analysis.get("content_gaps"):
|
|
educational_gaps = len([g for g in gap_analysis["content_gaps"] if "educational" in g.get("type", "").lower()])
|
|
thought_leadership_gaps = len([g for g in gap_analysis["content_gaps"] if "leadership" in g.get("type", "").lower()])
|
|
|
|
if educational_gaps > thought_leadership_gaps:
|
|
base_mix["educational"] += 10
|
|
base_mix["thought_leadership"] -= 5
|
|
base_mix["engagement"] -= 5
|
|
elif thought_leadership_gaps > educational_gaps:
|
|
base_mix["thought_leadership"] += 10
|
|
base_mix["educational"] -= 5
|
|
base_mix["engagement"] -= 5
|
|
|
|
return base_mix
|
|
|
|
async def _predict_calendar_performance(
|
|
self,
|
|
calendar_data: Dict[str, Any],
|
|
user_data: Dict[str, Any]
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Predict calendar performance based on AI analysis and historical data.
|
|
"""
|
|
try:
|
|
# Extract performance indicators
|
|
ai_analysis = user_data.get("ai_analysis_results", {})
|
|
strategic_scores = ai_analysis.get("strategic_scores", {})
|
|
|
|
# Calculate performance predictions
|
|
base_traffic_growth = 25
|
|
base_engagement_rate = 15
|
|
base_conversion_rate = 10
|
|
|
|
# Adjust based on strategic scores
|
|
if strategic_scores:
|
|
market_positioning_score = strategic_scores.get("market_positioning_score", 0.7)
|
|
content_strategy_score = strategic_scores.get("content_strategy_score", 0.7)
|
|
|
|
# Adjust predictions based on scores
|
|
traffic_growth = base_traffic_growth * (0.8 + market_positioning_score * 0.4)
|
|
engagement_rate = base_engagement_rate * (0.8 + content_strategy_score * 0.4)
|
|
conversion_rate = base_conversion_rate * (0.8 + (market_positioning_score + content_strategy_score) / 2 * 0.4)
|
|
else:
|
|
traffic_growth = base_traffic_growth
|
|
engagement_rate = base_engagement_rate
|
|
conversion_rate = base_conversion_rate
|
|
|
|
return {
|
|
"traffic_growth": round(traffic_growth, 1),
|
|
"engagement_rate": round(engagement_rate, 1),
|
|
"conversion_rate": round(conversion_rate, 1),
|
|
"roi_prediction": round(traffic_growth * 0.3 + engagement_rate * 0.4 + conversion_rate * 0.3, 1),
|
|
"confidence_score": 0.85
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error predicting calendar performance: {str(e)}")
|
|
return {
|
|
"traffic_growth": 25,
|
|
"engagement_rate": 15,
|
|
"conversion_rate": 10,
|
|
"roi_prediction": 15,
|
|
"confidence_score": 0.7
|
|
}
|
|
|
|
async def _get_trending_topics_for_calendar(
|
|
self,
|
|
user_data: Dict[str, Any],
|
|
industry: str
|
|
) -> List[Dict[str, Any]]:
|
|
"""
|
|
Get trending topics relevant to the calendar and industry.
|
|
"""
|
|
try:
|
|
# Extract keywords from gap analysis
|
|
keywords = user_data.get("gap_analysis", {}).get("keyword_opportunities", [])
|
|
|
|
# Generate trending topics based on keywords and industry
|
|
trending_topics = []
|
|
for keyword in keywords[:5]: # Top 5 keywords
|
|
trending_topics.append({
|
|
"topic": keyword,
|
|
"relevance_score": 0.9,
|
|
"trend_direction": "rising",
|
|
"content_opportunities": [
|
|
f"Create content around {keyword}",
|
|
f"Develop case studies featuring {keyword}",
|
|
f"Create how-to guides for {keyword}"
|
|
]
|
|
})
|
|
|
|
return trending_topics
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting trending topics: {str(e)}")
|
|
return []
|
|
|
|
async def _identify_repurposing_opportunities(
|
|
self,
|
|
calendar_data: Dict[str, Any],
|
|
user_data: Dict[str, Any]
|
|
) -> List[Dict[str, Any]]:
|
|
"""
|
|
Identify content repurposing opportunities for the calendar.
|
|
"""
|
|
try:
|
|
opportunities = []
|
|
|
|
# Identify opportunities from content pillars
|
|
content_pillars = calendar_data.get("content_pillars", [])
|
|
for pillar in content_pillars:
|
|
opportunities.append({
|
|
"original_content": f"{pillar} content piece",
|
|
"repurposing_options": [
|
|
f"Convert to {pillar} blog post",
|
|
f"Create {pillar} social media series",
|
|
f"Develop {pillar} video content",
|
|
f"Design {pillar} infographic"
|
|
],
|
|
"platforms": ["website", "linkedin", "instagram", "youtube"],
|
|
"estimated_reach_increase": "40%"
|
|
})
|
|
|
|
return opportunities
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error identifying repurposing opportunities: {str(e)}")
|
|
return []
|
|
|
|
def _generate_fallback_schedule(
|
|
self,
|
|
calendar_type: str,
|
|
content_pillars: List[str]
|
|
) -> List[Dict[str, Any]]:
|
|
"""
|
|
Generate fallback schedule when AI generation fails.
|
|
"""
|
|
schedule = []
|
|
days = 30 if calendar_type == "monthly" else 7 if calendar_type == "weekly" else 90
|
|
|
|
for day in range(1, days + 1):
|
|
pillar = content_pillars[day % len(content_pillars)]
|
|
schedule.append({
|
|
"day": day,
|
|
"title": f"{pillar} Content Day {day}",
|
|
"description": f"Create engaging {pillar.lower()} content",
|
|
"content_type": "blog_post",
|
|
"platform": "website",
|
|
"pillar": pillar,
|
|
"priority": "medium"
|
|
})
|
|
|
|
return schedule
|
|
|
|
def _extract_themes_from_gaps(self, gap_analysis: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
"""
|
|
Extract weekly themes from gap analysis.
|
|
"""
|
|
themes = []
|
|
if gap_analysis.get("content_gaps"):
|
|
for i, gap in enumerate(gap_analysis["content_gaps"][:3]):
|
|
themes.append({
|
|
"week": i + 1,
|
|
"theme": f"Addressing {gap.get('type', 'Content Gap')}",
|
|
"focus": gap.get("title", "Content gap"),
|
|
"content_types": ["blog_posts", "case_studies", "how_to_guides"]
|
|
})
|
|
return themes
|
|
|
|
def _get_industry_themes(self, industry: str) -> List[Dict[str, Any]]:
|
|
"""
|
|
Get industry-specific themes.
|
|
"""
|
|
industry_themes = {
|
|
"technology": [
|
|
{
|
|
"week": 4,
|
|
"theme": "Technology Innovation",
|
|
"focus": "Latest tech trends and innovations",
|
|
"content_types": ["industry_insights", "product_updates", "expert_interviews"]
|
|
}
|
|
],
|
|
"healthcare": [
|
|
{
|
|
"week": 4,
|
|
"theme": "Healthcare Insights",
|
|
"focus": "Patient care and medical innovations",
|
|
"content_types": ["patient_education", "medical_insights", "health_tips"]
|
|
}
|
|
],
|
|
"finance": [
|
|
{
|
|
"week": 4,
|
|
"theme": "Financial Education",
|
|
"focus": "Investment strategies and market analysis",
|
|
"content_types": ["financial_education", "market_analysis", "investment_tips"]
|
|
}
|
|
]
|
|
}
|
|
return industry_themes.get(industry, [])
|
|
|
|
async def _generate_content_recommendations(
|
|
self,
|
|
gap_analysis: Dict[str, Any],
|
|
ai_analysis: Dict[str, Any],
|
|
content_pillars: List[str]
|
|
) -> List[Dict[str, Any]]:
|
|
"""
|
|
Generate content recommendations based on gap analysis and AI insights.
|
|
"""
|
|
recommendations = []
|
|
|
|
# Add recommendations from gap analysis
|
|
if gap_analysis.get("recommendations"):
|
|
for rec in gap_analysis["recommendations"][:5]:
|
|
recommendations.append({
|
|
"title": rec.get("title", "Content recommendation"),
|
|
"description": rec.get("description", "Based on gap analysis"),
|
|
"priority": rec.get("priority", "medium"),
|
|
"content_type": rec.get("type", "blog_post"),
|
|
"estimated_impact": rec.get("estimated_impact", "Medium"),
|
|
"implementation_time": rec.get("implementation_time", "2-4 weeks")
|
|
})
|
|
|
|
# Add AI-generated recommendations
|
|
if ai_analysis.get("recommendations"):
|
|
for rec in ai_analysis["recommendations"][:3]:
|
|
recommendations.append({
|
|
"title": rec.get("title", "AI recommendation"),
|
|
"description": rec.get("description", "AI-generated insight"),
|
|
"priority": "high",
|
|
"content_type": "blog_post",
|
|
"estimated_impact": "High",
|
|
"implementation_time": "1-2 weeks"
|
|
})
|
|
|
|
return recommendations
|
|
|
|
async def _generate_optimal_timing(
|
|
self,
|
|
user_data: Dict[str, Any],
|
|
industry: str,
|
|
business_size: str
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Generate optimal timing recommendations based on industry and business size.
|
|
"""
|
|
# Industry-specific timing
|
|
industry_timing = {
|
|
"technology": {
|
|
"best_days": ["Tuesday", "Wednesday", "Thursday"],
|
|
"best_times": ["9:00 AM", "2:00 PM", "7:00 PM"],
|
|
"optimal_frequency": "2-3 per week"
|
|
},
|
|
"healthcare": {
|
|
"best_days": ["Monday", "Wednesday", "Friday"],
|
|
"best_times": ["8:00 AM", "12:00 PM", "6:00 PM"],
|
|
"optimal_frequency": "1-2 per week"
|
|
},
|
|
"finance": {
|
|
"best_days": ["Tuesday", "Thursday", "Friday"],
|
|
"best_times": ["9:00 AM", "1:00 PM", "5:00 PM"],
|
|
"optimal_frequency": "2-3 per week"
|
|
}
|
|
}
|
|
|
|
timing = industry_timing.get(industry, {
|
|
"best_days": ["Monday", "Wednesday", "Friday"],
|
|
"best_times": ["9:00 AM", "2:00 PM", "7:00 PM"],
|
|
"optimal_frequency": "2-3 per week"
|
|
})
|
|
|
|
# Adjust for business size
|
|
if business_size == "startup":
|
|
timing["optimal_frequency"] = "1-2 per week"
|
|
elif business_size == "enterprise":
|
|
timing["optimal_frequency"] = "3-4 per week"
|
|
|
|
return timing
|
|
|
|
async def _generate_calendar_ai_insights(
|
|
self,
|
|
gap_analysis: Dict[str, Any],
|
|
ai_analysis: Dict[str, Any],
|
|
content_pillars: List[str]
|
|
) -> List[Dict[str, Any]]:
|
|
"""
|
|
Generate AI insights specifically for the calendar.
|
|
"""
|
|
insights = []
|
|
|
|
# Add insights from gap analysis
|
|
if gap_analysis.get("content_gaps"):
|
|
insights.append({
|
|
"type": "opportunity",
|
|
"title": "Content Gap Opportunity",
|
|
"description": f"Address {len(gap_analysis['content_gaps'])} identified content gaps",
|
|
"priority": "high",
|
|
"impact": "High - Increased lead generation and brand authority"
|
|
})
|
|
|
|
# Add insights from AI analysis
|
|
if ai_analysis.get("market_positioning"):
|
|
positioning = ai_analysis["market_positioning"]
|
|
insights.append({
|
|
"type": "strategy",
|
|
"title": "Market Positioning",
|
|
"description": f"Focus on {positioning.get('competitive_advantage', 'content quality')}",
|
|
"priority": "high",
|
|
"impact": "High - Competitive differentiation"
|
|
})
|
|
|
|
# Add content pillar insights
|
|
insights.append({
|
|
"type": "strategy",
|
|
"title": "Content Pillars",
|
|
"description": f"Focus on {len(content_pillars)} core content pillars",
|
|
"priority": "medium",
|
|
"impact": "Medium - Consistent content strategy"
|
|
})
|
|
|
|
return insights |