# Social Poster Modülü — Otomatik Sosyal Medya Paylaşım Sistemi Son güncelleme: 1 Mart 2026 --- ## 1. Amaç Top liglerdeki maçların AI tahminlerini **otomatik olarak görselleştirip** Instagram, Facebook ve X (Twitter) üzerinden paylaşmak. Her maç için 30 dakika önceden tahmin alınıp, 1080×1920 (9:16 Instagram Story) formatında poster üretilir. --- ## 2. Mimari Akış ``` Cron (*/10 dk) → LiveMatch sorgusu (top_leagues.json filtresi) → AI Engine V20+ POST /v20plus/analyze/{match_id} → PredictionCardDto oluştur → Node Canvas ile 1080x1920 PNG render → Gemini ile Türkçe caption üret → Twitter / Facebook / Instagram API'ye paylaş ``` --- ## 3. Dosya Yapısı ``` src/modules/social-poster/ ├── social-poster.module.ts # NestJS modül tanımı ├── social-poster.controller.ts # Test endpointleri (preview, post) ├── social-poster.service.ts # Ana orkestrasyon servisi ├── image-renderer.service.ts # Node Canvas ile görsel üretimi ├── caption-generator.service.ts # Gemini ile post metni üretimi ├── twitter.service.ts # Twitter/X API entegrasyonu ├── meta.service.ts # Facebook + Instagram Graph API └── dto/ └── prediction-card.dto.ts # PredictionCardDto, TopPick, SocialPostResult ``` --- ## 4. Temel Servisler ### 4.1 SocialPosterService **Cron:** Her 10 dakikada bir çalışır. 25–40 dakika içinde başlayacak maçları `top_leagues.json` filtresiyle bulur. **Pipeline:** `predictAndPost(match)` → Tahmin al → Görsel üret → Caption üret → Paylaş **AI Engine İsteği:** ```typescript // POST — GET değil! AI Engine v20plus POST bekler. axios.post(`${aiEngineUrl}/v20plus/analyze/${matchId}`, null, { timeout: 30000 }) ``` **Veri Haritalandırma (V20+ → CardDto):** | V20+ Response Alanı | CardDto Alanı | |---|---| | `score_prediction.ht` | `htScore` (ör: "1-1") | | `score_prediction.ft` | `ftScore` (ör: "2-1") | | `main_pick.confidence` | `scoreConfidence` (ör: 65) | | `bet_summary[]` (array) | `topPicks[]` (ilk 3, confidence'a göre sıralı) | | `risk.level` | `riskLevel` (LOW/MEDIUM/HIGH/EXTREME) | | `match_info.home_team` | `homeTeam` (fallback) | **Bet Summary Market Kodları:** | Kod | Türkçe | English | |---|---|---| | MS | Maç Sonucu | Match Result | | OU15 | Üst 1.5 Gol | Over 1.5 | | OU25 | Üst 2.5 Gol | Over 2.5 | | OU35 | Üst 3.5 Gol | Over 3.5 | | BTTS | Karşılıklı Gol | Both Teams Score | | DC | Çifte Şans | Double Chance | | HT | İlk Yarı Sonucu | Half Time Result | | HT_OU05 | İY 0.5 Üst/Alt | HT Over/Under 0.5 | | OE | Tek/Çift | Odd/Even | | HTFT | İY/MS | HT/FT | ### 4.2 ImageRendererService **Motor:** `node-canvas` (Puppeteer/HTML yok — sunucu performansı için) **Çıktı:** `public/predictions/prediction_{matchId}_{timestamp}.png` **Boyut:** 1080×1920 px (Instagram Story / Reels uyumlu) **Özellikler:** - Koyu gradient arka plan (#0a0e27 → #1a1040 → #0d1b2a) - Lig adı + tarih başlık satırı - Takım logoları (200×200px) — `public/uploads/teams/` altından okunur - İlk Yarı / Maç Sonu skor kutuları - Güven yüzdesi badge'i - En iyi 3 tahmin (progress bar + yüzde) - Risk seviyesi badge'i (renk kodlu) - `iddaai.com` filigran (saydam, tekrarlı, döndürülmüş) - Alt bilgi: "⚡ AI Powered by SuggestBet" **Logo Çözümleme:** ``` 1. Yerel dosya varsa → public/uploads/teams/xxx.png oku 2. URL http ile başlıyorsa → HTTP ile indir 3. Bulunamazsa → logo olmadan devam et (graceful fallback) ``` ### 4.3 CaptionGeneratorService Gemini API kullanarak maç verisi JSON'ından Türkçe post metni üretir. ### 4.4 TwitterService & MetaService Üretilen görsel + caption'ı ilgili platformlara yükler. --- ## 5. API Endpointleri | Method | Path | Auth | Açıklama | |---|---|---|---| | GET | `/api/social-poster/preview/:matchId` | @Public | Sadece görsel üret + caption üret (paylaşma) | | POST | `/api/social-poster/post/:matchId` | @Public | Görsel üret + caption üret + tüm platformlara paylaş | > **Not:** Test endpointleri `@Public()` dekoratörüyle auth bypass edilmiştir. Production'da kaldırılmalı veya admin-only yapılmalıdır. --- ## 6. Environment Değişkenleri | Key | Zorunlu | Varsayılan | Açıklama | |---|---|---|---| | `AI_ENGINE_URL` | ✅ | `http://localhost:8000` | AI Engine base URL | | `APP_BASE_URL` | ✅ | `http://localhost:3000` | Logo URL çözümleme için | | `SOCIAL_POSTER_ENABLED` | ❌ | `false` | Cron job'ı aktif/pasif | | `GOOGLE_API_KEY` | ❌ | — | Gemini caption için | | Twitter API keys | ❌ | — | Twitter paylaşım için | | Meta API keys | ❌ | — | FB/IG paylaşım için | --- ## 7. Bağımlılıklar ```json { "canvas": "^2.x", // Node Canvas — görsel üretimi "axios": "^1.x", // HTTP istekleri (AI Engine + logo indirme) "@nestjs/schedule": "*" // Cron job desteği } ``` > **Kaldırılan:** `puppeteer` — performans ve Raspberry Pi uyumluluğu için `canvas` ile değiştirildi. --- ## 8. Deploy Notları ### Raspberry Pi (ARM64) ```bash # canvas native bağımlılıkları (Dockerfile'da) RUN apk add --no-cache cairo-dev pango-dev jpeg-dev giflib-dev librsvg-dev ``` ### Port Yönetimi | Servis | Port | |---|---| | NestJS Backend | 3000 (production: 150X) | | AI Engine | 8000 (dev: 8005 — Windows port kısıtlaması) | ### Dosya Sistemi ``` public/ ├── uploads/teams/ # Takım logoları (PNG) └── predictions/ # Üretilen poster görselleri (PNG) ``` --- ## 9. Bilinen Sorunlar & Çözümler | Sorun | Sebep | Çözüm | |---|---|---| | `WinError 10013` port erişim hatası | Windows Hyper-V port rezervasyonu | Farklı port kullan (8005) | | `Invalid prisma.liveMatch.findUnique()` | Prisma client eskimiş | `npx prisma generate` çalıştır | | `405 Method Not Allowed` AI Engine | GET yerine POST gerekiyor | `axios.post()` kullan | | Logolar görünmüyor (lokal dev) | Logo dosyaları sunucuda, lokalde yok | Deploy'da çalışır, lokal'de graceful skip |