このコミットが含まれているのは:
2026-05-02 02:48:40 +09:00
コミット 39101ca422
9個のファイルの変更474行の追加0行の削除
+87
ファイルの表示
@@ -0,0 +1,87 @@
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