Zum Hauptinhalt springen

Instagram & Collector Services

Die Instagram-Datenerhebung erfolgt asynchron über einen externen Collector-Service. Die Services in diesem Bereich verwalten das Job-Dispatching, die Ergebnis-Verarbeitung und die Keyword-Extraktion für Instagram-Profile.

CollectorJobDispatcher

Location: app/Services/Collector/CollectorJobDispatcher.php

Erstellt Collector-Jobs in der collector_jobs-Tabelle und steuert die Priorität. Der externe Collector pollt diese Tabelle via REST-API, least Jobs und meldet Ergebnisse zurück.

Public Methods

MethodParameterReturnBeschreibung
dispatch()string $source, string $handle, string $jobType, array $payload = [], int $priority = 0CollectorJobCollector-Job erstellen

Job-Typen

Job TypeBeschreibungPriorität
daily_scrapeTägliches Profil-UpdateKonfigurierbar via postbox.instagram_priority_*
watcher_importNeues Profil importieren (User-Aktion)Höchste Priorität (50)
profile_retryRetry eines deaktivierten ProfilsNiedrige Priorität

Job-Lifecycle

dispatch() → Queued → Leased (Collector pollt) → Completed/Failed
  1. dispatch() erstellt einen CollectorJob mit Status Queued
  2. Collector-API least den Job (Status -> Leased, leased_by gesetzt)
  3. Collector meldet Ergebnis: Completed mit Payload oder Failed mit Fehler
  4. InstagramDailyScrapeProcessor oder InstagramWatcherImportProcessor verarbeitet das Ergebnis

Prioritäts-System

Jobs werden in Reihenfolge der Priorität geleased (höhere Zahl = höhere Priorität):

  • Priority 50: Watcher-Import (User wartet aktiv)
  • Priority 30: Rescrape nach Follower-Range
  • Priority 10: Daily Scrape (Standard)
  • Priority 0: Profile Retry, Background-Tasks

Abhängigkeiten

  • CollectorJob Model, Config (postbox.instagram_priority_*)

Verwendet von

  • QueueDailyInstagramScrapes-Command, Watcher-Import, RetryInactiveProfiles-Command

InstagramWatcherImportProcessor

Location: app/Services/Collector/InstagramWatcherImportProcessor.php

Verarbeitet abgeschlossene Collector-Jobs vom Typ watcher_import. Erstellt oder aktualisiert das SocialProfile, legt die erste SocialProfileDailyMetric an und verknüpft das Profil mit dem Watcher.

Public Methods

MethodParameterReturnBeschreibung
handleCompletion()CollectorJob $jobvoidErfolgreichen Import verarbeiten
handleFailure()CollectorJob $jobvoidFehlgeschlagenen Import verarbeiten

Ablauf handleCompletion()

  1. Collector-Payload parsen (Follower, Following, Posts, Bio, etc.)
  2. SocialProfile erstellen oder aktualisieren (Deduplizierung via Handle)
  3. SocialProfileDailyMetric für heute anlegen
  4. Profil-Bild herunterladen via ProfileImageUpdater
  5. Bio parsen via ProfileDescriptionParser
  6. Keywords extrahieren via ProfileKeywordExtractor
  7. WatcherSource mit dem Profil verknüpfen
  8. Admin-Workspace-Spiegelung via AdminWorkspaceManager::ensureProfileWatcher()
  9. WatcherImportProgress-Event dispatchen (WebSocket)

Fehlerbehandlung (handleFailure())

  • Job wird als Failed markiert
  • WatcherImportProgress-Event mit Fehlerstatus dispatchen
  • Kein Retry auf Processor-Ebene (Collector hat eigene Retry-Logik)

Abhängigkeiten

  • ProfileImageUpdater, ProfileDescriptionParser, ProfileKeywordExtractor, AdminWorkspaceManager
  • WatcherImportProgress Event

Verwendet von

  • CollectorJobsController (API-Callback bei Job-Completion)

InstagramDailyScrapeProcessor

Location: app/Services/Collector/InstagramDailyScrapeProcessor.php

Verarbeitet die Ergebnisse täglicher Instagram-Scrapes. Aktualisiert Metriken, Bio-Daten, Profil-Bilder und erkennt Profilname-Änderungen.

Public Methods

MethodParameterReturnBeschreibung
handleCompletion()CollectorJob $jobvoidErfolgreichen Daily Scrape verarbeiten
handleFailure()CollectorJob $jobvoidFehlgeschlagenen Daily Scrape verarbeiten

Ablauf handleCompletion()

  1. Collector-Payload parsen und validieren
  2. Profildaten sanitizen via sanitizeProfileData() (siehe Sanitization-Pipeline unten)
  3. SocialProfileDailyMetric erstellen/aktualisieren (Follower, Following, Posts)
  4. Profil-Daten aktualisieren (Title, Description, is_private, is_verified, profile_type)
  5. Bio-Änderung erkennen und ProfileDescriptionParser ausführen
  6. Profil-Bild aktualisieren falls URL geändert
  7. Keywords aktualisieren via ProfileKeywordExtractor
  8. Related Profiles aus Collector-Payload verarbeiten (falls vorhanden)
  9. Fail-Streak auf 0 zurücksetzen bei erfolgreichem Scrape
  10. DailyScrapeCompleted-Event dispatchen für WebSocket-Notification

Sanitization-Pipeline

Vor dem Speichern werden Scraper-Rohdaten bereinigt. Identische Logik in beiden Processoren (InstagramDailyScrapeProcessor und InstagramWatcherImportProcessor):

Bio-Sanitization (sanitizeBio()):

  • Erkennt \nmehr\n und \nmore\n Separatoren (Scraper liefert Preview + Volltext getrennt durch den "mehr"/"more"-Button-Text). Behält nur den Volltext nach dem Separator.
  • Entfernt trailing \nmehr / \nmore Marker am Ende der Bio.

Title-Sanitization (sanitizeTitle()):

  • Kategorie-Label erkennen: Vergleicht Title gegen profile_data.category (z.B. "Kuenstler/in", "Athlete"). Bei Gleichheit wird der Title verworfen und durch den Handle ersetzt.
  • "mehr"/"more"-Artefakte entfernen: Trailing ... mehr, … more, mehr werden gestrippt.
  • Bio-Preview-Duplikation erkennen: Wenn die erste Zeile der Bio (>= 10 Zeichen) im Title vorkommt und der Title laenger als 30 Zeichen ist, wird nur der Name-Anteil (vor dem Bio-Text) extrahiert.
  • Leerer Title: Fallback auf Handle wenn Title nach Sanitization NULL/leer. Kurze Titel wie "V" oder Emoji-Only "👑" bleiben erhalten.

Fail-Streak-Logik (handleFailure())

  • fail_streak Counter inkrementieren
  • Bei Überschreitung des konfigurierten Thresholds: deactivated_at setzen
  • Deaktivierte Profile werden vom RetryInactiveProfiles-Command nach konfigurierten Intervallen erneut versucht

Abhängigkeiten

  • ProfileImageUpdater, ProfileDescriptionParser, ProfileKeywordExtractor
  • DailyScrapeCompleted Event

Verwendet von

  • CollectorJobsController (API-Callback bei Job-Completion)

ProfileKeywordExtractor

Location: app/Services/Instagram/ProfileKeywordExtractor.php

Extrahiert relevante Keywords aus Instagram-Profil-Daten (Bio, Handle, Username) und speichert sie in der instagram_profile_keywords-Tabelle. Diese Keywords werden für Cross-Platform-Matching und Kategorie-Erkennung verwendet.

Public Methods

MethodParameterReturnBeschreibung
extractAndStore()SocialProfile $profilearrayKeywords extrahieren und in DB speichern
extract()SocialProfile $profilearrayKeywords extrahieren (ohne Speicherung)
extractFromText()string $textarrayKeywords aus beliebigem Text extrahieren
extractFromHandle()string $handlearrayKeywords aus Handle/Username extrahieren

Extraktions-Quellen

QuelleBeispielGewicht
Bio-Text"Fashion Blogger aus Berlin"Hoch
Handlefashion_blogger_deMittel
Username/Title"Lisa Fashion"Mittel

Keyword-Verarbeitung

  • Stopwords werden gefiltert (deutsch + englisch)
  • Mindestlänge: 3 Zeichen
  • Normalisierung auf Lowercase
  • Handle-Splitting: fashion_blogger -> ["fashion", "blogger"]

Abhängigkeiten

  • InstagramProfileKeyword Model

Verwendet von

  • InstagramDailyScrapeProcessor, InstagramWatcherImportProcessor, CrossPlatformRelatedCalculator, DetectChannelLanguages-Command