fix: link collaborative related video channels

This commit is contained in:
webhop123 2026-08-03 16:17:02 +01:00
parent 47b5d79ec7
commit 74fb6a8f92
3 changed files with 122 additions and 1 deletions

View File

@ -0,0 +1,74 @@
require "../../parsers_helper"
Spectator.describe Invidious::Videos::Parser do
describe ".parse_related_video" do
it "uses the first creator channel for a collaborative byline" do
related = JSON.parse(%(
{
"videoId": "BTJGr78-zyw",
"title": {
"simpleText": "Collaborative video"
},
"shortBylineText": {
"runs": [
{
"text": "The Diary Of A CEO and Predictive History",
"navigationEndpoint": {
"showDialogCommand": {
"panelLoadingStrategy": {
"inlineContent": {
"dialogViewModel": {
"customContent": {
"listViewModel": {
"listItems": [
{
"listItemViewModel": {
"rendererContext": {
"commandContext": {
"onTap": {
"innertubeCommand": {
"browseEndpoint": {
"browseId": "UCGq-a57w-aPwyi3pW7XLiHw"
}
}
}
}
}
}
},
{
"listItemViewModel": {
"rendererContext": {
"commandContext": {
"onTap": {
"innertubeCommand": {
"browseEndpoint": {
"browseId": "UC11aHtNnc5bEPLI4jf6mnYg"
}
}
}
}
}
}
}
]
}
}
}
}
}
}
}
}
]
}
}
))
parsed = Invidious::Videos::Parser.parse_related_video(related).not_nil!
expect(parsed["author"].as_s).to eq("The Diary Of A CEO and Predictive History")
expect(parsed["ucid"].as_s).to eq("UCGq-a57w-aPwyi3pW7XLiHw")
end
end
end

View File

@ -0,0 +1,25 @@
require "../../parsers_helper"
Spectator.describe HelperExtractors do
describe ".get_browse_id" do
it "extracts a direct browse endpoint" do
container = JSON.parse(%(
{
"navigationEndpoint": {
"browseEndpoint": {
"browseId": "UCdirect"
}
}
}
))
expect(HelperExtractors.get_browse_id(container)).to eq("UCdirect")
end
it "returns an empty string when no browse endpoint exists" do
container = JSON.parse(%({"navigationEndpoint":{"showDialogCommand":{}}}))
expect(HelperExtractors.get_browse_id(container)).to be_empty
end
end
end

View File

@ -1141,7 +1141,29 @@ module HelperExtractors
# Retrieves the ID required for querying the InnerTube browse endpoint.
# Returns an empty string when it's unable to do so
def self.get_browse_id(container)
return container.dig?("navigationEndpoint", "browseEndpoint", "browseId").try &.as_s || ""
browse_id = container.dig?("navigationEndpoint", "browseEndpoint", "browseId")
return browse_id.as_s if browse_id
# Collaborative bylines open a dialog instead of linking to a channel.
# Use the first listed creator because video items store a single channel.
return container.dig?(
"navigationEndpoint",
"showDialogCommand",
"panelLoadingStrategy",
"inlineContent",
"dialogViewModel",
"customContent",
"listViewModel",
"listItems",
0,
"listItemViewModel",
"rendererContext",
"commandContext",
"onTap",
"innertubeCommand",
"browseEndpoint",
"browseId"
).try &.as_s || ""
end
end