Zum Hauptinhalt springen

Admin/YouTubeResearch/Index

YouTube Data API Channel-Suche mit Topic-ID-Filter, Batch-Suche mit Qualitaetsfilter, Keyword-Suggestions, Ergebnis-Archivierung und Import in den Admin-Workspace.

Route: /admin/youtube-research View: resources/views/livewire/admin/youtube-research/index.blade.php Location: app/Livewire/Admin/YouTubeResearch/Index.php Autorisierung: Admin Gate via Middleware

Public Properties

PropertyTypDefaultBeschreibung
$querystring''Suchbegriff (Einzelsuche)
$topicIdstring''YouTube Topic-ID Filter
$topicOptionsarray[...]Verfuegbare Topic-IDs (statisch geladen in mount())
$batchKeywordsstring''Keywords fuer Batch-Suche (eine pro Zeile)
$batchTopicIdstring''Topic-ID fuer Batch
$batchLanguagestring''Sprache fuer Batch
$batchRegionstring''Region fuer Batch
$batchMinSubscribersint|nullnullMin. Subscriber fuer Batch
$batchMinVideosint|nullnullMin. Videos fuer Batch
$batchProgressarray|nullnullEchtzeit-Fortschritt der laufenden Batch
$showJsonModalboolfalseJSON-Payload Modal offen
$showUrlsModalboolfalseURL-Export Modal offen
$showErrorModalboolfalseError-Payload Modal offen
$selectedQueryIdint|nullnullAktuell ausgewaehlte Query-ID
$selectedUrlsarray[]URLs der ausgewaehlten Query
$selectedPayloadarray|nullnullJSON-Payload der ausgewaehlten Query
$selectedErrorPayloadarray|nullnullError-Payload
$lastImportedQueryIdint|nullnullZuletzt importierte Query-ID

Topic-IDs

Die Component laedt ueber 60 YouTube Topic-IDs in mount(), gruppiert nach Kategorien:

KategorieBeispiel-Topics
MusicMusic (parent), Pop, Rock, Hip Hop, Jazz, Classical
GamingGaming (parent), Action, RPG, Casual, Racing
SportsSports (parent), Football, Basketball, Tennis, MMA
EntertainmentEntertainment (parent), Movies, TV Shows, Humor
LifestyleLifestyle (parent), Fashion, Fitness, Food, Beauty
SocietySociety (parent), Business, Health, Politics, Religion
KnowledgeKnowledge

Actions

MethodBeschreibung
runSearch(YouTubeDataApiClient $api)Einzelsuche ausfuehren, Ergebnisse in DB speichern
startBatchSearch()Batch-Suche starten: Keywords parsen, ProcessYouTubeResearchBatch-Job dispatchen
openJsonModal(int $queryId)Raw JSON-Response anzeigen
openUrlsModal(int $queryId)URL-Liste anzeigen
openErrorModal(int $queryId)Error-Payload anzeigen
closeModals()Alle Modals schliessen
importUrls(int $queryId, AdminWorkspaceManager $manager)URLs in Admin-Workspace importieren
importBatchUrls(string $batchId, AdminWorkspaceManager $manager)Alle URLs einer Batch importieren
getKeywordSuggestions()AI-Keywords aus Profilen laden (mit Cooldown)
fetchYouTubeSuggestions(string $partial)YouTube Autocomplete-Vorschlaege laden

Einzelsuche

runSearch()
→ validate(query: required|min:2|max:200, topicId: nullable)
→ fetchYouTubeChannels()
→ rawGetWithKeyPool('search', params, 'research')
→ Paginierung ueber nextPageToken (max 1000 Ergebnisse)
→ Channel-URLs extrahieren
→ YouTubeResearchQuery::create(...)
→ resetPage()

Die Suche nutzt rawGetWithKeyPool() mit dem Pool 'research' fuer dedizierten API-Key-Verbrauch. Paginierung ueber nextPageToken sammelt bis zu 1000 Channel-URLs.

Batch-Suche

graph TD
A[Admin gibt Keywords ein] --> B[startBatchSearch]
B --> C[Keywords parsen + deduplizieren]
C --> D[YouTubeResearchQuery pro Keyword erstellen]
D --> E[ProcessYouTubeResearchBatch Job dispatchen]
E --> F{Fuer jedes Keyword}
F --> G[YouTube Search API]
G --> H{Qualitaetsfilter?}
H -->|Ja| I[channels.list: Subscriber/Video Check]
H -->|Nein| J[Ergebnisse speichern]
I --> J
J --> K[YouTubeResearchBatchProgress Event]
K --> L[Echtzeit-UI-Update via WebSocket]
F --> M[Batch abgeschlossen]

Batch-Filter

FilterTypBeschreibung
topic_idstringYouTube Topic-ID (Music, Gaming, Sports, etc.)
relevance_languagestringISO 639-1 Sprache
region_codestringISO 3166-1 Region
min_subscribersintMindest-Subscriber-Anzahl
min_videosintMindest-Video-Anzahl

Batch-Limits

  • Max. 100 Keywords pro Batch (dedupliziert, vorher 20)
  • Max. 1000 Ergebnisse pro Keyword
  • Qualitaetsfilter: 50 Channels pro channels.list-Chunk (1 Quota-Unit/Call)
  • Overflow-Erhalt: Keywords ueber dem 100-Limit bleiben im Eingabefeld fuer den naechsten Batch. Info-Toast zeigt: "X Keywords gestartet, Y verbleiben im Feld"

Keyword-Suggestions

Zwei Quellen fuer Keyword-Vorschlaege:

AI-Keywords aus Profilen

YouTubeResearchKeywordSuggester extrahiert die haeufigsten AI-Keywords aus bestehenden YouTube-Profilen. Keywords auf 14-Tage-Cooldown werden uebersprungen. Zeigt Top-20 mit Frequency-Count.

YouTube Suggest API

YouTubeSuggestClient liefert Autocomplete-Vorschlaege von YouTubes oeffentlichem Suggest-Endpoint. Kein API-Key erforderlich. Response-Zeit ca. 200ms.

Import-Ablauf

importUrls($queryId)
→ AdminWorkspaceManager::ensureAdminWorkspace()
→ URLs parsen via YouTubeUrlParser::parse()
→ Deduplizierung (max 1000 unique URLs)
→ WatcherImportRun + WatcherImportItems erstellen (DB Transaction)
→ ProcessWatcherImportRun dispatchen (Queue: imports-youtube-priority)
→ YouTubeResearchQuery::update(['imported_at' => now()])
→ Toast: "X URLs zur Queue hinzugefuegt"

Der Import erstellt einen WatcherImportRun im Admin-Workspace und dispatcht einen einzelnen ProcessWatcherImportRun-Job (statt N+1 einzelne Jobs). Importierte Queries werden visuell markiert (imported_at).

Datenmodell

YouTubeResearchQuery

youtube_research_queries
├── query: string — Suchbegriff
├── topic_id: string|null — YouTube Topic-ID
├── batch_id: uuid|null — Batch-Identifier
├── relevance_language: string — Sprache-Filter
├── region_code: string — Region-Filter
├── min_subscribers: int|null — Min. Subscriber-Filter
├── min_videos: int|null — Min. Video-Filter
├── result_count: int — Anzahl gefundener Channels
├── filtered_count: int|null — Anzahl nach Qualitaetsfilter
├── result_urls: jsonb — Array der Channel-URLs
├── response_payload: jsonb — Raw API Response (alle Seiten)
├── error_payload: jsonb — Error Response bei Fehler
├── error_message: string — Fehlermeldung
├── status: string — pending/running/completed/failed
├── imported_at: timestamp — Wann in Workspace importiert
└── created_at: timestamp

YouTubeResearchKeywordCooldown

youtube_research_keyword_cooldowns
├── keyword: string (unique) — Keyword
├── used_at: timestamp — Letzter Verwendungszeitpunkt
└── created_at: timestamp

Events

RichtungEventBeschreibung
dispatchshow-toastImport-Erfolg/Fehler
listenYouTubeResearchBatchProgressEchtzeit-Fortschritt via WebSocket (admin-Channel)

Render

Die render()-Methode paginiert YouTubeResearchQuery (100 pro Seite, neueste zuerst) und zeigt nur die Minimal-Felder (id, query, topic_id, result_count, filtered_count, error_message, status, batch_id, imported_at, created_at).