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
| Option | Beschreibung |
|---|---|
--force-today | Scrape für heute erzwingen, unabhängig vom Rotation-Bucket |
--watcher-id= | Kommaseparierte Watcher-IDs (nur diese werden gescraped) |
--dry-run | Zeigt 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)
| Kategorie | Kriterium |
|---|---|
| PRO | YouTubeVideoSync.auto_sync_enabled = true oder pro_enabled = true |
| Leaders | Top/Flop 100 aus Leaderboards |
| Candidates | Rising-Profile die in Top 100 kommen könnten |
| Favorites | User-favorisierte Profile |
| New | Noch nie gescraped (last_scraped_at = null) |
| CatchUp | Verpasstes 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
- Rotation-Bucket für heute bestimmen (regulär + low-priority)
- Priority-Profile sammeln (PRO, Leaders, Candidates, Favorites, New, CatchUp)
- Reguläre Profile im heutigen Bucket laden (getrennt nach regular/low-priority)
ImportWatcherFromUrlJobs aufimports-youtube/imports-youtube-prioritydispatchenDailySyncRunmit 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
| Option | Beschreibung |
|---|---|
--force-today | Re-Queue auch bei bereits vorhandenen Jobs/Scrapes |
--watcher-id= | Kommaseparierte Watcher-IDs |
--reset-open | Queued/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
- Rotation-Bucket für heute bestimmen (regulär + low-priority)
- PRO-Profile, Leaders, Candidates, Favorites, New, CatchUp sammeln
- Reguläre und Low-Priority-Profile im jeweiligen Bucket laden
- Offene Jobs prüfen (queued/leased) um Duplikate zu vermeiden
- Stale Jobs > 2 Tage prunen
- Collector-Jobs via
CollectorJobDispatchererstellen (Chunks à 1000, 250ms Delay) - Cache-Marker
health:instagram_queue_ran:{date}mit akkumuliertem Queued-Count setzen
Priority-System
| Priorität | Konfiguration | Default |
|---|---|---|
| New Profile | POSTBOX_INSTAGRAM_PRIORITY_NEW_PROFILE | 30 |
| Favorite | POSTBOX_INSTAGRAM_PRIORITY_FAVORITE | 20 |
| CatchUp | POSTBOX_INSTAGRAM_PRIORITY_CATCH_UP | 10 |
| Default | POSTBOX_INSTAGRAM_PRIORITY_DEFAULT | 0 |
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
| Option | Beschreibung |
|---|---|
--limit=100 | Max Profile für synchrone Verarbeitung |
--force | Re-Detection auch bei vorhandenen Daten |
--profile= | Einzelnes Profil via ID |
--queue | Asynchroner Queue-Modus |
--queue-limit=500 | Max Profile pro Queue-Dispatch |
--flush | Alle pending ai-detection Jobs entfernen |
Interne Schritte (Queue-Modus)
- Hard-Cap prüfen: Überspringen wenn Queue bereits voll
- Profile ohne Sprach-/Land-Daten laden (sortiert nach Follower-Anzahl)
- Cooldown beachten (Default: 365 Tage)
DetectProfileLanguageJobs 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
| Option | Beschreibung |
|---|---|
type | Plattform: instagram oder youtube |
--min-follower= / --max-follower= | Follower-Range |
--min-following= / --max-following= | Following-Range |
--min-posts= / --max-posts= | Post/Video-Range |
--force | Instagram: force=true im Collector-Job setzen |
Interne Schritte
- Profile nach Latest-Metriken filtern (mindestens ein Filter erforderlich)
- Ergebnisse nach Workspace gruppieren
- Instagram: Collector-Jobs erstellen / YouTube:
ImportWatcherFromUrlJobs dispatchen - Pro Workspace ein Run erstellen
Schedule
Manuell (kein automatischer Schedule).
Location: app/Console/Commands/QueueFollowerRangeRescrape.php