From 436f955e0f20c9e398e3587175f3071dcec153d4 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Wed, 25 Jun 2025 23:34:30 -0400 Subject: [PATCH] update fetch_community_post_comments protobuf to match currently used protobuf, add sort_by option --- src/invidious/channels/community.cr | 9 +++++++++ src/invidious/comments/youtube.cr | 26 ++++++++++++++----------- src/invidious/routes/api/v1/channels.cr | 6 ++++-- src/invidious/routes/channels.cr | 2 +- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr index c0688416..8927c81b 100644 --- a/src/invidious/channels/community.cr +++ b/src/invidious/channels/community.cr @@ -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) 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) object = { "56:embedded" => { diff --git a/src/invidious/comments/youtube.cr b/src/invidious/comments/youtube.cr index 0716fcde..18403656 100644 --- a/src/invidious/comments/youtube.cr +++ b/src/invidious/comments/youtube.cr @@ -16,34 +16,38 @@ module Invidious::Comments return parse_youtube(id, response, format, locale, thin_mode, sort_by) end - def fetch_community_post_comments(ucid, post_id) + def fetch_community_post_comments(ucid, post_id, sort_by = "top") object = { - "2:string" => "community", - "25:embedded" => { - "22:string" => post_id, - }, - "45:embedded" => { - "2:varint" => 1_i64, - "3:varint" => 1_i64, - }, + "2:string" => "posts", "53:embedded" => { "4:embedded" => { "6:varint" => 0_i64, - "27:varint" => 1_i64, + "15:varint" => 2_i64, + "25:varint" => 0_i64, "29:string" => post_id, "30:string" => ucid, }, + "7:varint" => 0_i64, "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) } .try { |i| Protodec::Any.from_json(i) } .try { |i| Base64.urlsafe_encode(i) } object2 = { "80226972:embedded" => { - "2:string" => ucid, + "2:string" => "FEcomment_post_detail_page_web_top_level", "3:string" => object_parsed, }, } diff --git a/src/invidious/routes/api/v1/channels.cr b/src/invidious/routes/api/v1/channels.cr index a940ee68..503b8c05 100644 --- a/src/invidious/routes/api/v1/channels.cr +++ b/src/invidious/routes/api/v1/channels.cr @@ -436,7 +436,7 @@ module Invidious::Routes::API::V1::Channels if ucid.nil? response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}") 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 ucid = ucid.to_s end @@ -460,13 +460,15 @@ module Invidious::Routes::API::V1::Channels format = env.params.query["format"]? format ||= "json" + sort_by = env.params.query["sort_by"]?.try &.downcase + sort_by ||= "top" continuation = env.params.query["continuation"]? case continuation when nil, "" 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 comments = YoutubeAPI.browse(continuation: continuation) end diff --git a/src/invidious/routes/channels.cr b/src/invidious/routes/channels.cr index 508aa3e4..6d2b4465 100644 --- a/src/invidious/routes/channels.cr +++ b/src/invidious/routes/channels.cr @@ -284,7 +284,7 @@ module Invidious::Routes::Channels response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}") 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) end