This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { GeminiService } from '../gemini/gemini.service';
|
||||
import { PredictionCardDto } from './dto/prediction-card.dto';
|
||||
|
||||
const SYSTEM_PROMPT = `Sen profesyonel bir spor analisti ve sosyal medya içerik üreticisisin.
|
||||
Verilen maç tahmin verisini kullanarak kısa, etkili ve ilgi çekici sosyal medya postları yazıyorsun.
|
||||
|
||||
KURALLAR:
|
||||
- Türkçe yaz
|
||||
- Maximum 250 karakter (X/Twitter uyumlu)
|
||||
- Emoji kullan ama abartma (2-4 emoji yeterli)
|
||||
- Skor tahminini vurgula
|
||||
- Güven yüzdesini belirt
|
||||
- İlgili hashtag'leri ekle (#PremierLeague, #SüperLig vb.)
|
||||
- KESİNLİKLE "kesin kazanır", "garanti" gibi ifadeler KULLANMA
|
||||
- "Tahminimiz", "Beklentimiz", "Analizimiz" gibi ifadeler kullan
|
||||
- Farklı maçlar için farklı tarzda yaz, tekdüze olma
|
||||
- Son satıra her zaman hashtag'leri koy`;
|
||||
|
||||
@Injectable()
|
||||
export class CaptionGeneratorService {
|
||||
private readonly logger = new Logger(CaptionGeneratorService.name);
|
||||
|
||||
constructor(private readonly geminiService: GeminiService) {}
|
||||
|
||||
/**
|
||||
* Generate a social media caption for a match prediction using Gemini AI.
|
||||
*/
|
||||
async generateCaption(card: PredictionCardDto): Promise<string> {
|
||||
if (!this.geminiService.isAvailable()) {
|
||||
this.logger.warn('Gemini not available, using template caption');
|
||||
return this.generateFallbackCaption(card);
|
||||
}
|
||||
|
||||
const prompt = this.buildPrompt(card);
|
||||
|
||||
try {
|
||||
const { text } = await this.geminiService.generateText(prompt, {
|
||||
systemPrompt: SYSTEM_PROMPT,
|
||||
temperature: 0.8,
|
||||
maxTokens: 300,
|
||||
});
|
||||
|
||||
// Ensure hashtags are present
|
||||
const caption = this.ensureHashtags(text, card);
|
||||
this.logger.log(
|
||||
`Caption generated for ${card.homeTeam} vs ${card.awayTeam}`,
|
||||
);
|
||||
return caption;
|
||||
} catch (error) {
|
||||
this.logger.error('Gemini caption generation failed', error);
|
||||
return this.generateFallbackCaption(card);
|
||||
}
|
||||
}
|
||||
|
||||
private buildPrompt(card: PredictionCardDto): string {
|
||||
const topPicksText = card.topPicks
|
||||
.map(
|
||||
(p, i) =>
|
||||
`${i + 1}. ${p.market} (${p.marketEn}) — ${p.pick} — Güven: %${p.confidence} — Oran: ${p.odds}`,
|
||||
)
|
||||
.join('\n');
|
||||
|
||||
return `Aşağıdaki maç tahmin verisini kullanarak bir sosyal medya postu oluştur:
|
||||
|
||||
MAÇ: ${card.homeTeam} vs ${card.awayTeam}
|
||||
LİG: ${card.leagueName}
|
||||
TARİH: ${card.matchDate}
|
||||
İLK YARI SKOR TAHMİNİ: ${card.htScore}
|
||||
MAÇ SONU SKOR TAHMİNİ: ${card.ftScore}
|
||||
SKOR GÜVEN: %${card.scoreConfidence}
|
||||
RİSK SEVİYESİ: ${card.riskLevel}
|
||||
|
||||
EN İYİ TAHMİNLER:
|
||||
${topPicksText}
|
||||
|
||||
Sadece post metnini yaz, başka hiçbir şey ekleme.`;
|
||||
}
|
||||
|
||||
private ensureHashtags(text: string, card: PredictionCardDto): string {
|
||||
// If no hashtags in text, add them
|
||||
if (!text.includes('#')) {
|
||||
const leagueTag = card.leagueName
|
||||
.replace(/\s+/g, '')
|
||||
.replace(/[^a-zA-Z0-9üöçşğıİÜÖÇŞĞ]/g, '');
|
||||
const homeTag = card.homeTeam.replace(/\s+/g, '');
|
||||
const awayTag = card.awayTeam.replace(/\s+/g, '');
|
||||
text += `\n\n#${leagueTag} #${homeTag} #${awayTag}`;
|
||||
}
|
||||
return text.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback caption when Gemini is not available.
|
||||
*/
|
||||
private generateFallbackCaption(card: PredictionCardDto): string {
|
||||
const topPick = card.topPicks[0];
|
||||
const leagueTag = card.leagueName
|
||||
.replace(/\s+/g, '')
|
||||
.replace(/[^a-zA-Z0-9üöçşğıİÜÖÇŞĞ]/g, '');
|
||||
|
||||
return `⚡ ${card.homeTeam} vs ${card.awayTeam}
|
||||
🎯 Tahminimiz: ${card.ftScore} (İY: ${card.htScore})
|
||||
📊 Güven: %${card.scoreConfidence}
|
||||
${topPick ? `🔥 ${topPick.market}: ${topPick.pick} (%${topPick.confidence})` : ''}
|
||||
|
||||
#${leagueTag} #SuggestBet #Bahis`.trim();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user