Zum Hauptinhalt springen

Data Collection Commands

Commands für das tägliche Scraping und Sammeln von Social-Media-Daten. Beide Plattformen nutzen ein Rotation-Bucket-System, um die Last über mehrere Tage zu verteilen.


social:scrape-daily-followers

Täglicher Scrape für YouTube mit Rotation-Bucket-Support. Profile werden über N Tage (Default: 3) verteilt, sodass jedes Profil alle 3 Tage gescraped wird.

social:scrape-daily-followers
{--force-today : Scrape für heute erzwingen}
{--watcher-id= : Nur bestimmte Watcher scrapen (kommaseparierte IDs)}
{--dry-run : Zeigt was gescraped würde, ohne auszuführen}

Beispiele

# Standard-Lauf (YouTube, heutiger Rotation-Bucket)
php artisan social:scrape-daily-followers

# Bestimmte Watcher sofort scrapen
php artisan social:scrape-daily-followers --force-today --watcher-id=12,15

# Vorschau ohne Ausführung
php artisan social:scrape-daily-followers --dry-run

Optionen

OptionBeschreibung
--force-todayScrape für heute erzwingen, unabhängig vom Rotation-Bucket
--watcher-id=Kommaseparierte Watcher-IDs (nur diese werden gescraped)
--dry-runZeigt an was passieren würde, keine Jobs werden dispatched

Rotation-Logik

  • Bucket-Berechnung: CRC32(handle) % rotation_days
  • Heutiger Bucket: dayOfYear % rotation_days
  • Reguläre Profile (>= Follower-Threshold): Rotation über youtube_rotation_days (max 4 Tage)
  • Low-Priority-Profile (< Follower-Threshold): Rotation über low_priority_rotation_days (max 7 Tage)
  • Priority-Profile umgehen jede Rotation (täglich gescrapt)

Priority-Profile (täglich, umgehen Rotation)

KategorieKriterium
PROYouTubeVideoSync.auto_sync_enabled = true oder pro_enabled = true
LeadersTop/Flop 100 aus Leaderboards
CandidatesRising-Profile die in Top 100 kommen könnten
FavoritesUser-favorisierte Profile
NewNoch nie gescraped (last_scraped_at = null)
CatchUpVerpasstes Rotation-Fenster

Low-Priority-Rotation

Profile werden als Low-Priority eingestuft wenn eines der folgenden Kriterien zutrifft:

  • followers_count < POSTBOX_LOW_PRIORITY_FOLLOWER_COUNT (Default: 100)
  • is_private = true (private Instagram-Profile liefern kaum verwertbare Daten)

Low-Priority-Profile nutzen einen separaten, langsameren Rotation-Bucket (low_priority_rotation_days, Default: 7 Tage). Ausnahmen: Favorites, PRO, Leaders und Candidates werden immer mit normaler Rotation behandelt. Wird ein privates Profil oeffentlich, setzt der naechste Scrape is_private=false und es kehrt automatisch zur regulaeren Rotation zurueck.

Interne Schritte

  1. Rotation-Bucket für heute bestimmen (regulär + low-priority)
  2. Priority-Profile sammeln (PRO, Leaders, Candidates, Favorites, New, CatchUp)
  3. Reguläre Profile im heutigen Bucket laden (getrennt nach regular/low-priority)
  4. ImportWatcherFromUrl Jobs auf imports-youtube / imports-youtube-priority dispatchen
  5. DailySyncRun mit expected/processed Counts erstellen

Schedule

Alle 2 Stunden (ungerade: 01:00, 03:00, 05:00, ...) mit .withoutOverlapping(30).

Fail-Streak-Cooldown

Profile mit scrape_fail_streak >= 3 (aber unter dem Deaktivierungs-Threshold von 14) werden nicht mehr täglich gescrapt, sondern nur alle 3 Tage. Die Prüfung basiert auf last_scrape_failed_at — wenn weniger als 3 Tage seit dem letzten Fehlversuch vergangen sind, wird das Profil übersprungen. Übersprungene Profile werden in der Summary als skipped_fail_streak gezählt.

Konfiguration

POSTBOX_YOUTUBE_ROTATION_DAYS=3            # Reguläre Profile über 3 Tage verteilen (max 4)
POSTBOX_LOW_PRIORITY_FOLLOWER_COUNT=100 # Threshold für Low-Priority
POSTBOX_LOW_PRIORITY_ROTATION_DAYS=7 # Low-Priority über 7 Tage verteilen (max 7)
POSTBOX_FAIL_STREAK_COOLDOWN_AFTER=3 # Ab welchem Fail-Streak der Cooldown greift
POSTBOX_FAIL_STREAK_COOLDOWN_DAYS=3 # Tage zwischen Retry-Versuchen im Cooldown

Location: app/Console/Commands/SocialScrapeDailyFollowers.php


social:queue-daily-instagram

Queued Instagram-Scrapes via Collector-Queue mit Rotation-Buckets. Profile werden in Buckets aufgeteilt, sodass jedes Profil alle N Tage gescraped wird.

social:queue-daily-instagram
{--force-today : Re-Queue auch wenn heute schon gescraped/gequeued}
{--watcher-id= : Nur bestimmte Watcher queuen (kommaseparierte IDs)}
{--reset-open : Offene daily_scrape Jobs zurücksetzen}

Beispiele

# Standard-Lauf
php artisan social:queue-daily-instagram

# Erneut queuen, auch wenn schon gescraped heute
php artisan social:queue-daily-instagram --force-today

# Bestimmte Watcher queuen
php artisan social:queue-daily-instagram --watcher-id=12,15

# Offene daily_scrape Jobs zurücksetzen (Watcher-Imports bleiben unberührt)
php artisan social:queue-daily-instagram --reset-open

Optionen

OptionBeschreibung
--force-todayRe-Queue auch bei bereits vorhandenen Jobs/Scrapes
--watcher-id=Kommaseparierte Watcher-IDs
--reset-openQueued/Expired daily_scrape Jobs zurücksetzen

Low-Priority-Rotation

Gleiche Logik wie bei YouTube (siehe oben), plus: Private Instagram-Profile (is_private = true) werden ebenfalls als Low-Priority eingestuft, da sie kaum verwertbare Daten liefern (keine Posts, kein Engagement). Favorites, PRO-Profile, Leaders und Candidates sind ausgenommen.

Interne Schritte

  1. Rotation-Bucket für heute bestimmen (regulär + low-priority)
  2. PRO-Profile, Leaders, Candidates, Favorites, New, CatchUp sammeln
  3. Reguläre und Low-Priority-Profile im jeweiligen Bucket laden
  4. Offene Jobs prüfen (queued/leased) um Duplikate zu vermeiden
  5. Stale Jobs > 2 Tage prunen
  6. Collector-Jobs via CollectorJobDispatcher erstellen (Chunks à 1000, 250ms Delay)
  7. Cache-Marker health:instagram_queue_ran:{date} mit akkumuliertem Queued-Count setzen

Priority-System

PrioritätKonfigurationDefault
New ProfilePOSTBOX_INSTAGRAM_PRIORITY_NEW_PROFILE30
FavoritePOSTBOX_INSTAGRAM_PRIORITY_FAVORITE20
CatchUpPOSTBOX_INSTAGRAM_PRIORITY_CATCH_UP10
DefaultPOSTBOX_INSTAGRAM_PRIORITY_DEFAULT0

Fail-Streak-Cooldown

Gleiche Logik wie bei YouTube: Profile mit scrape_fail_streak >= 3 werden nur alle 3 Tage gescrapt (basierend auf last_scrape_failed_at). Übersprungene Profile werden als skipped_fail_streak in der Summary gezählt.

Schedule

Alle 2 Stunden (gerade: 00:00, 02:00, 04:00, ...) mit .withoutOverlapping(30).

Location: app/Console/Commands/QueueDailyInstagramScrapes.php


social:detect-languages

Erkennt Sprache, Land und Kategorie von Social Profiles via Gemini AI. Unterstützt synchrone Verarbeitung und asynchrones Queue-Processing.

social:detect-languages
{--limit=100 : Maximale Anzahl Profile}
{--force : Auch bereits erkannte Profile neu erkennen}
{--profile= : Bestimmte Profile-ID}
{--queue : Jobs asynchron in Queue dispatchen}
{--queue-limit=500 : Maximale Profile pro Queue-Run}
{--flush : Alle pending ai-detection Jobs aus Queue entfernen}

Beispiele

# Synchrone Erkennung (100 Profile)
php artisan social:detect-languages --limit=100

# Asynchron in Queue dispatchen
php artisan social:detect-languages --queue --queue-limit=200

# Bestimmtes Profil erneut erkennen
php artisan social:detect-languages --profile=12345 --force

# Queue leeren
php artisan social:detect-languages --flush

Optionen

OptionBeschreibung
--limit=100Max Profile für synchrone Verarbeitung
--forceRe-Detection auch bei vorhandenen Daten
--profile=Einzelnes Profil via ID
--queueAsynchroner Queue-Modus
--queue-limit=500Max Profile pro Queue-Dispatch
--flushAlle pending ai-detection Jobs entfernen

Interne Schritte (Queue-Modus)

  1. Hard-Cap prüfen: Überspringen wenn Queue bereits voll
  2. Profile ohne Sprach-/Land-Daten laden (sortiert nach Follower-Anzahl)
  3. Cooldown beachten (Default: 365 Tage)
  4. DetectProfileLanguage Jobs dispatchen (Rate-Limited: 15 RPM via Job-Middleware)

Schedule

Alle 15 Minuten mit --queue und dynamischem --queue-limit (hourly_limit / 4).

Location: app/Console/Commands/DetectChannelLanguages.php


watchers:queue-rescrape

Queued Re-Scrapes für Watcher basierend auf Metriken-Ranges. Unterstützt Instagram (Collector) und YouTube (Queue Job).

watchers:queue-rescrape {type}
{--min-follower=} {--max-follower=}
{--min-following=} {--max-following=}
{--min-posts=} {--max-posts=}
{--force}

Beispiele

# Instagram: Re-Scrape für Follower-Range
php artisan watchers:queue-rescrape instagram --min-follower=123 --max-follower=999 --force

# YouTube: Re-Scrape für niedrige Follower
php artisan watchers:queue-rescrape youtube --min-follower=100 --max-follower=999

# Kombinierte Filter
php artisan watchers:queue-rescrape instagram --min-follower=500 --max-posts=200

Optionen

OptionBeschreibung
typePlattform: instagram oder youtube
--min-follower= / --max-follower=Follower-Range
--min-following= / --max-following=Following-Range
--min-posts= / --max-posts=Post/Video-Range
--forceInstagram: force=true im Collector-Job setzen

Interne Schritte

  1. Profile nach Latest-Metriken filtern (mindestens ein Filter erforderlich)
  2. Ergebnisse nach Workspace gruppieren
  3. Instagram: Collector-Jobs erstellen / YouTube: ImportWatcherFromUrl Jobs dispatchen
  4. Pro Workspace ein Run erstellen

Schedule

Manuell (kein automatischer Schedule).

Location: app/Console/Commands/QueueFollowerRangeRescrape.php