ぼざクリタグ広場 https://hub.nizika.monster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

88 lines
2.4 KiB

  1. module VideoSources
  2. module Youtube
  3. class Client
  4. API_BASE = 'https://www.googleapis.com/youtube/v3'
  5. def initialize api_key: ENV.fetch('YOUTUBE_API_KEY')
  6. @api_key = api_key
  7. end
  8. def videos video_ids
  9. return [] if video_ids.empty?
  10. response = connection.get('videos', part: 'snippet,statistics',
  11. id: video_ids.join(','),
  12. key: @api_key)
  13. JSON.parse(response.body).fetch('items', []).map do |item|
  14. build_video(item)
  15. end
  16. end
  17. def comments video_id
  18. comments = []
  19. page_token = nil
  20. loop do
  21. response = connection.get('commentThreads', {
  22. part: 'snippet',
  23. videoId: video_id,
  24. maxResults: 100,
  25. textFormat: 'plainText',
  26. pageToken: page_token,
  27. key: @api_key }.compact)
  28. body = JSON.parse(response.body)
  29. comments.concat(body.fetch('items', []).map { |item| build_comment(item) })
  30. page_token = body['nextPageToken']
  31. break if page_token.blank?
  32. end
  33. comments
  34. rescue Faraday::ForbiddenError
  35. []
  36. end
  37. private
  38. def connection
  39. @connection ||= Faraday.new(url: API_BASE) do |faraday|
  40. faraday.response :raise_error
  41. end
  42. end
  43. def build_video item
  44. snippet = item.fetch('snippet')
  45. statistics = item.fetch('statistics', { })
  46. { provider: 'youtube',
  47. code: item.fetch('id'),
  48. user_code: snippet['channelId'],
  49. title: snippet['title'].to_s,
  50. description: snippet['description'].to_s,
  51. tag_names: snippet.fetch('tags', []),
  52. views_count: statistics.fetch('viewCount', 0).to_i,
  53. uploaded_at: Time.zone.parse(snippet.fetch('publishedAt')) }
  54. end
  55. def build_comment item
  56. snippet =
  57. item
  58. .fetch('snippet')
  59. .fetch('topLevelComment')
  60. .fetch('snippet')
  61. { provider_comment_id: item.fetch('id'),
  62. user_code: snippet['authorChannelId']&.fetch('value', nil),
  63. content: snippet['textDisplay'].to_s,
  64. posted_at: Time.zone.parse(snippet.fetch('publishedAt')),
  65. reaction_count: snippet.fetch('likeCount', 0).to_i,
  66. comment_no: nil,
  67. vpos_ms: nil }
  68. end
  69. end
  70. end
  71. end