PostGen / backend /app /services /ai_service.py
Seth
update
6d1e595
raw
history blame
5.29 kB
import httpx
import os
from typing import List, Dict, Any, Optional
from openai import OpenAI
from app.schemas import AIContentRequest, AIContentResponse
class AIService:
def __init__(self):
self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY", ""))
self.model = os.getenv("OPENAI_MODEL", "gpt-4o")
async def generate_content(
self,
request: AIContentRequest,
assets_context: Optional[str] = None,
asset_insights: Optional[List[Dict[str, Any]]] = None
) -> AIContentResponse:
"""Generate LinkedIn post content using GPT with agentic context from assets"""
product_descriptions = {
"ocr": "Intelligent Document Parsing (OCR) - AI-powered document processing and data extraction",
"p2p": "Purchase To Pay (P2P) - End-to-end procurement and accounts payable automation",
"o2c": "Order to Cash (O2C) - Complete order management and accounts receivable workflow"
}
post_type_descriptions = {
"carousel": "A multi-slide carousel post with visual storytelling",
"cover_content": "A post with a cover image and engaging text content",
"content_only": "A text-only post focused on valuable insights",
"webinar": "A webinar invitation post to promote an upcoming event"
}
# Build rich context from analyzed assets
asset_context_text = ""
if asset_insights:
asset_context_text = "\n\nRelevant Asset Insights (use these to create authentic, specific content):\n"
for asset in asset_insights:
if asset.get("extracted_content"):
from app.services.asset_analyzer import AssetAnalyzer
analyzer = AssetAnalyzer()
insight = analyzer.extract_key_insights(asset.get("extracted_content"))
if insight:
asset_context_text += f"- {asset.get('name', 'Asset')}: {insight}\n"
elif assets_context:
asset_context_text = f"\n\nAvailable assets: {assets_context}"
system_prompt = f"""You are an expert LinkedIn content creator specializing in B2B SaaS marketing.
Create engaging, professional LinkedIn posts that:
- Are authentic and valuable to the audience
- Use specific insights from uploaded assets when available
- Include relevant hashtags (3-5 hashtags)
- Use emojis sparingly and appropriately
- Are optimized for engagement
- Follow LinkedIn best practices
Product: {product_descriptions.get(request.product_category, request.product_category)}
Post Type: {post_type_descriptions.get(request.post_type, request.post_type)}
"""
user_prompt = f"""Create a LinkedIn post about {product_descriptions.get(request.product_category, request.product_category)}.
Post type: {post_type_descriptions.get(request.post_type, request.post_type)}
{f'Additional context: {request.context}' if request.context else ''}
{asset_context_text}
Make it engaging, professional, and include relevant hashtags at the end.
If asset insights are provided, incorporate specific details from them to make the content more authentic and valuable."""
try:
response = self.client.chat.completions.create(
model=self.model,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
temperature=0.7,
max_tokens=1000
)
content = response.choices[0].message.content
# Extract hashtags
hashtags = []
lines = content.split('\n')
for line in lines:
if '#' in line:
hashtags.extend([tag.strip() for tag in line.split() if tag.startswith('#')])
# If no hashtags found, generate some
if not hashtags:
hashtags = self._generate_hashtags(request.product_category)
return AIContentResponse(
content=content,
suggested_hashtags=hashtags[:5]
)
except Exception as e:
# Fallback content if AI fails
return AIContentResponse(
content=f"๐Ÿš€ Exciting news about {product_descriptions.get(request.product_category, 'our product')}!\n\nStay tuned for more updates.\n\n#Innovation #Technology",
suggested_hashtags=["#Innovation", "#Technology", "#Business"]
)
def _generate_hashtags(self, product_category: str) -> List[str]:
"""Generate relevant hashtags based on product category"""
hashtag_map = {
"ocr": ["#DocumentAutomation", "#OCR", "#AITechnology", "#DigitalTransformation", "#BusinessEfficiency"],
"p2p": ["#Procurement", "#AccountsPayable", "#FinanceAutomation", "#BusinessProcess", "#Efficiency"],
"o2c": ["#OrderManagement", "#AccountsReceivable", "#SalesAutomation", "#BusinessGrowth", "#CustomerExperience"]
}
return hashtag_map.get(product_category, ["#Innovation", "#Technology", "#Business"])