class Discovery::YoutubeVideoDiscoverer def initialize(client: Youtube::SearchClient.new) @client = client end def call discovery_query:, published_after:, published_before: body = @client.search_videos( query: discovery_query.query, published_after: published_after, published_before: published_before) body.fetch('items', []).each do |item| next unless item.dig('id', 'kind') == 'youtube#video' upsert_candidate!(discovery_query, item) end end private def upsert_candidate! discovery_query, item snippet = item.fetch('snippet') code = item.fetch('id').fetch('videoId') candidate = VideoCandidate.find_or_initialize_by(provider: 'youtube', code:) candidate.title = snippet['title'].to_s candidate.description = snippet['description'].to_s candidate.channel_code = snippet['channelId'] candidate.channel_title = snippet['channelTitle'] candidate.published_at = Time.zone.parse(snippet['publishedAt']) candidate.thumbnail_url = snippet.dig('thumbnails', 'high', 'url') candidate.raw_data = item candidate.last_discovered_at = Time.current candidate.save! VideoCandidateHit.find_or_create_by!( video_candidate: candidate, discovery_query: discovery_query ) do |hit| hit.matched_field = 'youtube_search' hit.score = 0 hit.searched_at = Time.current end end end