update fetch_community_post_comments protobuf to match currently used protobuf, add sort_by option

This commit is contained in:
ChunkyProgrammer 2025-06-25 23:34:30 -04:00
parent 4155f15bf7
commit 436f955e0f
4 changed files with 29 additions and 14 deletions

View File

@ -24,6 +24,15 @@ def fetch_channel_community(ucid, cursor, locale, format, thin_mode)
return extract_channel_community(items, ucid: ucid, locale: locale, format: format, thin_mode: thin_mode) return extract_channel_community(items, ucid: ucid, locale: locale, format: format, thin_mode: thin_mode)
end end
def decode_ucid_from_post_protobuf(params)
decoded_protobuf = params.try { |i| URI.decode_www_form(i) }
.try { |i| Base64.decode(i) }
.try { |i| IO::Memory.new(i) }
.try { |i| Protodec::Any.parse(i) }
return decoded_protobuf.try(&.["56:0:embedded"]["2:0:string"].as_s)
end
def fetch_channel_community_post(ucid, post_id, locale, format, thin_mode) def fetch_channel_community_post(ucid, post_id, locale, format, thin_mode)
object = { object = {
"56:embedded" => { "56:embedded" => {

View File

@ -16,34 +16,38 @@ module Invidious::Comments
return parse_youtube(id, response, format, locale, thin_mode, sort_by) return parse_youtube(id, response, format, locale, thin_mode, sort_by)
end end
def fetch_community_post_comments(ucid, post_id) def fetch_community_post_comments(ucid, post_id, sort_by = "top")
object = { object = {
"2:string" => "community", "2:string" => "posts",
"25:embedded" => {
"22:string" => post_id,
},
"45:embedded" => {
"2:varint" => 1_i64,
"3:varint" => 1_i64,
},
"53:embedded" => { "53:embedded" => {
"4:embedded" => { "4:embedded" => {
"6:varint" => 0_i64, "6:varint" => 0_i64,
"27:varint" => 1_i64, "15:varint" => 2_i64,
"25:varint" => 0_i64,
"29:string" => post_id, "29:string" => post_id,
"30:string" => ucid, "30:string" => ucid,
}, },
"7:varint" => 0_i64,
"8:string" => "comments-section", "8:string" => "comments-section",
}, },
} }
case sort_by
when "top"
object["53:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 0_i64
when "new", "newest"
object["53:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 1_i64
else # top
object["53:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 0_i64
end
object_parsed = object.try { |i| Protodec::Any.cast_json(i) } object_parsed = object.try { |i| Protodec::Any.cast_json(i) }
.try { |i| Protodec::Any.from_json(i) } .try { |i| Protodec::Any.from_json(i) }
.try { |i| Base64.urlsafe_encode(i) } .try { |i| Base64.urlsafe_encode(i) }
object2 = { object2 = {
"80226972:embedded" => { "80226972:embedded" => {
"2:string" => ucid, "2:string" => "FEcomment_post_detail_page_web_top_level",
"3:string" => object_parsed, "3:string" => object_parsed,
}, },
} }

View File

@ -436,7 +436,7 @@ module Invidious::Routes::API::V1::Channels
if ucid.nil? if ucid.nil?
response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}") response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}")
return error_json(400, "Invalid post ID") if response["error"]? return error_json(400, "Invalid post ID") if response["error"]?
ucid = response.dig("endpoint", "browseEndpoint", "browseId").as_s ucid = decode_ucid_from_post_protobuf(response.dig("endpoint", "browseEndpoint", "params").as_s)
else else
ucid = ucid.to_s ucid = ucid.to_s
end end
@ -460,13 +460,15 @@ module Invidious::Routes::API::V1::Channels
format = env.params.query["format"]? format = env.params.query["format"]?
format ||= "json" format ||= "json"
sort_by = env.params.query["sort_by"]?.try &.downcase
sort_by ||= "top"
continuation = env.params.query["continuation"]? continuation = env.params.query["continuation"]?
case continuation case continuation
when nil, "" when nil, ""
ucid = env.params.query["ucid"] ucid = env.params.query["ucid"]
comments = Comments.fetch_community_post_comments(ucid, id) comments = Comments.fetch_community_post_comments(ucid, id, sort_by: sort_by)
else else
comments = YoutubeAPI.browse(continuation: continuation) comments = YoutubeAPI.browse(continuation: continuation)
end end

View File

@ -284,7 +284,7 @@ module Invidious::Routes::Channels
response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}") response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}")
return error_template(400, "Invalid post ID") if response["error"]? return error_template(400, "Invalid post ID") if response["error"]?
ucid = response.dig("endpoint", "browseEndpoint", "browseId").as_s ucid = decode_ucid_from_post_protobuf(response.dig("endpoint", "browseEndpoint", "params").as_s)
post_response = fetch_channel_community_post(ucid, id, locale, "json", thin_mode) post_response = fetch_channel_community_post(ucid, id, locale, "json", thin_mode)
end end