|
- module VideoSources
- module Youtube
- class Client
- API_BASE = 'https://www.googleapis.com/youtube/v3'
-
- def initialize api_key: ENV.fetch('YOUTUBE_API_KEY')
- @api_key = api_key
- end
-
- def videos video_ids
- return [] if video_ids.empty?
-
- response = connection.get('videos', part: 'snippet,statistics',
- id: video_ids.join(','),
- key: @api_key)
-
- JSON.parse(response.body).fetch('items', []).map do |item|
- build_video(item)
- end
- end
-
- def comments video_id
- comments = []
- page_token = nil
-
- loop do
- response = connection.get('commentThreads', {
- part: 'snippet',
- videoId: video_id,
- maxResults: 100,
- textFormat: 'plainText',
- pageToken: page_token,
- key: @api_key }.compact)
-
- body = JSON.parse(response.body)
-
- comments.concat(body.fetch('items', []).map { |item| build_comment(item) })
-
- page_token = body['nextPageToken']
- break if page_token.blank?
- end
-
- comments
- rescue Faraday::ForbiddenError
- []
- end
-
- private
-
- def connection
- @connection ||= Faraday.new(url: API_BASE) do |faraday|
- faraday.response :raise_error
- end
- end
-
- def build_video item
- snippet = item.fetch('snippet')
- statistics = item.fetch('statistics', { })
-
- { provider: 'youtube',
- code: item.fetch('id'),
- user_code: snippet['channelId'],
- title: snippet['title'].to_s,
- description: snippet['description'].to_s,
- tag_names: snippet.fetch('tags', []),
- views_count: statistics.fetch('viewCount', 0).to_i,
- uploaded_at: Time.zone.parse(snippet.fetch('publishedAt')) }
- end
-
- def build_comment item
- snippet =
- item
- .fetch('snippet')
- .fetch('topLevelComment')
- .fetch('snippet')
-
- { provider_comment_id: item.fetch('id'),
- user_code: snippet['authorChannelId']&.fetch('value', nil),
- content: snippet['textDisplay'].to_s,
- posted_at: Time.zone.parse(snippet.fetch('publishedAt')),
- reaction_count: snippet.fetch('likeCount', 0).to_i,
- comment_no: nil,
- vpos_ms: nil }
- end
- end
- end
- end
|