generated from fahricansecer/boilerplate-be
This commit is contained in:
303
src/modules/content-generation/content-generation.service.ts
Normal file
303
src/modules/content-generation/content-generation.service.ts
Normal file
@@ -0,0 +1,303 @@
|
||||
// Content Generation Service - Main orchestration
|
||||
// Path: src/modules/content-generation/content-generation.service.ts
|
||||
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { PrismaService } from '../../database/prisma.service';
|
||||
import { NicheService, Niche, NicheAnalysis } from './services/niche.service';
|
||||
import { DeepResearchService, ResearchResult, ResearchQuery } from './services/deep-research.service';
|
||||
import { PlatformGeneratorService, Platform, GeneratedContent, MultiPlatformContent } from './services/platform-generator.service';
|
||||
import { HashtagService, HashtagSet } from './services/hashtag.service';
|
||||
import { BrandVoiceService, BrandVoice, VoiceApplication } from './services/brand-voice.service';
|
||||
import { VariationService, VariationSet, VariationOptions } from './services/variation.service';
|
||||
import { SeoService, FullSeoAnalysis } from '../seo/seo.service';
|
||||
import { NeuroMarketingService } from '../neuro-marketing/neuro-marketing.service';
|
||||
|
||||
export interface ContentGenerationRequest {
|
||||
topic: string;
|
||||
niche?: string;
|
||||
platforms: Platform[];
|
||||
includeResearch?: boolean;
|
||||
includeHashtags?: boolean;
|
||||
brandVoiceId?: string;
|
||||
variationCount?: number;
|
||||
}
|
||||
|
||||
export interface SeoAnalysisResult {
|
||||
score: number;
|
||||
keywords: string[];
|
||||
suggestions: string[];
|
||||
meta: { title: string; description: string; };
|
||||
}
|
||||
|
||||
export interface NeuroAnalysisResult {
|
||||
score: number;
|
||||
triggersUsed: string[];
|
||||
emotionProfile: string[];
|
||||
improvements: string[];
|
||||
}
|
||||
|
||||
export interface GeneratedContentBundle {
|
||||
id: string;
|
||||
topic: string;
|
||||
niche?: NicheAnalysis;
|
||||
research?: ResearchResult;
|
||||
platforms: GeneratedContent[];
|
||||
variations: VariationSet[];
|
||||
seo?: SeoAnalysisResult;
|
||||
neuro?: NeuroAnalysisResult;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class ContentGenerationService {
|
||||
private readonly logger = new Logger(ContentGenerationService.name);
|
||||
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly nicheService: NicheService,
|
||||
private readonly researchService: DeepResearchService,
|
||||
private readonly platformService: PlatformGeneratorService,
|
||||
private readonly hashtagService: HashtagService,
|
||||
private readonly brandVoiceService: BrandVoiceService,
|
||||
private readonly variationService: VariationService,
|
||||
private readonly seoService: SeoService,
|
||||
private readonly neuroService: NeuroMarketingService,
|
||||
) { }
|
||||
|
||||
// ========== FULL GENERATION WORKFLOW ==========
|
||||
|
||||
/**
|
||||
* Complete content generation workflow
|
||||
*/
|
||||
async generateContent(request: ContentGenerationRequest): Promise<GeneratedContentBundle> {
|
||||
const {
|
||||
topic,
|
||||
niche,
|
||||
platforms,
|
||||
includeResearch = true,
|
||||
includeHashtags = true,
|
||||
brandVoiceId,
|
||||
variationCount = 3,
|
||||
} = request;
|
||||
|
||||
// Analyze niche if provided
|
||||
let nicheAnalysis: NicheAnalysis | undefined;
|
||||
if (niche) {
|
||||
nicheAnalysis = this.nicheService.analyzeNiche(niche) || undefined;
|
||||
}
|
||||
|
||||
// Perform research if requested
|
||||
let research: ResearchResult | undefined;
|
||||
if (includeResearch) {
|
||||
research = await this.researchService.research({
|
||||
topic,
|
||||
depth: 'standard',
|
||||
includeStats: true,
|
||||
includeQuotes: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Generate content for each platform using AI
|
||||
const platformContent: GeneratedContent[] = [];
|
||||
for (const platform of platforms) {
|
||||
try {
|
||||
// Use AI generation when available
|
||||
const aiContent = await this.platformService.generateAIContent(
|
||||
topic,
|
||||
research?.summary || `Everything you need to know about ${topic}`,
|
||||
platform,
|
||||
'standard',
|
||||
'tr',
|
||||
);
|
||||
|
||||
const config = this.platformService.getPlatformConfig(platform);
|
||||
let content: GeneratedContent = {
|
||||
platform,
|
||||
format: 'AI Generated',
|
||||
content: aiContent,
|
||||
hashtags: [],
|
||||
mediaRecommendations: [],
|
||||
postingRecommendation: `Best times: ${config.bestPostingTimes.join(', ')}`,
|
||||
characterCount: aiContent.length,
|
||||
isWithinLimit: aiContent.length <= config.maxCharacters,
|
||||
};
|
||||
|
||||
// Apply brand voice if specified
|
||||
if (brandVoiceId) {
|
||||
const voiceApplied = this.brandVoiceService.applyVoice(content.content, brandVoiceId);
|
||||
content.content = voiceApplied.branded;
|
||||
}
|
||||
|
||||
// Add hashtags if requested
|
||||
if (includeHashtags) {
|
||||
const hashtagSet = this.hashtagService.generateHashtags(topic, platform);
|
||||
content.hashtags = hashtagSet.hashtags.map((h) => h.hashtag);
|
||||
}
|
||||
|
||||
platformContent.push(content);
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to generate content for platform ${platform}: ${error.message}`);
|
||||
// Continue to next platform
|
||||
}
|
||||
}
|
||||
|
||||
// Generate variations for primary platform
|
||||
const variations: VariationSet[] = [];
|
||||
if (variationCount > 0 && platformContent.length > 0) {
|
||||
const primaryContent = platformContent[0].content;
|
||||
const variationSet = this.variationService.generateVariations(primaryContent, {
|
||||
count: variationCount,
|
||||
variationType: 'complete',
|
||||
});
|
||||
variations.push(variationSet);
|
||||
}
|
||||
|
||||
// SEO Analysis
|
||||
let seoResult: SeoAnalysisResult | undefined;
|
||||
if (platformContent.length > 0) {
|
||||
const primaryContent = platformContent[0].content;
|
||||
const seoScore = this.seoService.quickScore(primaryContent, topic);
|
||||
const lsiKeywords = this.seoService.getLSIKeywords(topic, 10);
|
||||
seoResult = {
|
||||
score: seoScore,
|
||||
keywords: lsiKeywords,
|
||||
suggestions: seoScore < 70 ? [
|
||||
'Add more keyword density',
|
||||
'Include long-tail keywords',
|
||||
'Add meta description',
|
||||
] : ['SEO is optimized'],
|
||||
meta: {
|
||||
title: `${topic} | Content Hunter`,
|
||||
description: research?.summary?.slice(0, 160) || `Learn about ${topic}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Neuro Marketing Analysis
|
||||
let neuroResult: NeuroAnalysisResult | undefined;
|
||||
if (platformContent.length > 0) {
|
||||
const primaryContent = platformContent[0].content;
|
||||
const analysis = this.neuroService.analyze(primaryContent, platforms[0]);
|
||||
neuroResult = {
|
||||
score: analysis.prediction.overallScore,
|
||||
triggersUsed: analysis.triggerAnalysis.used.map(t => t.name),
|
||||
emotionProfile: Object.keys(analysis.prediction.categories).filter(
|
||||
k => analysis.prediction.categories[k as keyof typeof analysis.prediction.categories] > 50
|
||||
),
|
||||
improvements: analysis.prediction.improvements,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
id: `gen-${Date.now()}`,
|
||||
topic,
|
||||
niche: nicheAnalysis,
|
||||
research,
|
||||
platforms: platformContent,
|
||||
variations,
|
||||
seo: seoResult,
|
||||
neuro: neuroResult,
|
||||
createdAt: new Date(),
|
||||
};
|
||||
}
|
||||
|
||||
// ========== NICHE OPERATIONS ==========
|
||||
|
||||
getNiches(): Niche[] {
|
||||
return this.nicheService.getAllNiches();
|
||||
}
|
||||
|
||||
analyzeNiche(nicheId: string): NicheAnalysis | null {
|
||||
return this.nicheService.analyzeNiche(nicheId);
|
||||
}
|
||||
|
||||
recommendNiches(interests: string[]): Niche[] {
|
||||
return this.nicheService.recommendNiches(interests);
|
||||
}
|
||||
|
||||
getContentIdeas(nicheId: string, count?: number): string[] {
|
||||
return this.nicheService.getContentIdeas(nicheId, count);
|
||||
}
|
||||
|
||||
// ========== RESEARCH OPERATIONS ==========
|
||||
|
||||
async research(query: ResearchQuery): Promise<ResearchResult> {
|
||||
return this.researchService.research(query);
|
||||
}
|
||||
|
||||
async factCheck(claim: string) {
|
||||
return this.researchService.factCheck(claim);
|
||||
}
|
||||
|
||||
async getContentResearch(topic: string) {
|
||||
return this.researchService.research({ topic, depth: 'standard', includeStats: true, includeQuotes: true });
|
||||
}
|
||||
|
||||
// ========== PLATFORM OPERATIONS ==========
|
||||
|
||||
getPlatforms() {
|
||||
return this.platformService.getAllPlatforms();
|
||||
}
|
||||
|
||||
getPlatformConfig(platform: Platform) {
|
||||
return this.platformService.getPlatformConfig(platform);
|
||||
}
|
||||
|
||||
generateForPlatform(platform: Platform, input: { topic: string; mainMessage: string }) {
|
||||
return this.platformService.generateForPlatform(platform, input);
|
||||
}
|
||||
|
||||
generateMultiPlatform(input: { topic: string; mainMessage: string; platforms: Platform[] }) {
|
||||
return this.platformService.generateMultiPlatform(input);
|
||||
}
|
||||
|
||||
adaptContent(content: string, from: Platform, to: Platform) {
|
||||
return this.platformService.adaptContent(content, from, to);
|
||||
}
|
||||
|
||||
// ========== HASHTAG OPERATIONS ==========
|
||||
|
||||
generateHashtags(topic: string, platform: string): HashtagSet {
|
||||
return this.hashtagService.generateHashtags(topic, platform);
|
||||
}
|
||||
|
||||
analyzeHashtag(hashtag: string) {
|
||||
return this.hashtagService.analyzeHashtag(hashtag);
|
||||
}
|
||||
|
||||
getTrendingHashtags(category?: string) {
|
||||
return this.hashtagService.getTrendingHashtags(category);
|
||||
}
|
||||
|
||||
// ========== BRAND VOICE OPERATIONS ==========
|
||||
|
||||
createBrandVoice(input: Partial<BrandVoice> & { name: string }): BrandVoice {
|
||||
return this.brandVoiceService.createBrandVoice(input);
|
||||
}
|
||||
|
||||
getBrandVoice(id: string): BrandVoice | null {
|
||||
return this.brandVoiceService.getBrandVoice(id);
|
||||
}
|
||||
|
||||
listBrandVoicePresets() {
|
||||
return this.brandVoiceService.listPresets();
|
||||
}
|
||||
|
||||
applyBrandVoice(content: string, voiceId: string): VoiceApplication {
|
||||
return this.brandVoiceService.applyVoice(content, voiceId);
|
||||
}
|
||||
|
||||
generateVoicePrompt(voiceId: string): string {
|
||||
return this.brandVoiceService.generateVoicePrompt(voiceId);
|
||||
}
|
||||
|
||||
// ========== VARIATION OPERATIONS ==========
|
||||
|
||||
generateVariations(content: string, options?: VariationOptions): VariationSet {
|
||||
return this.variationService.generateVariations(content, options);
|
||||
}
|
||||
|
||||
createABTest(content: string) {
|
||||
return this.variationService.createABTest(content);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user