From d58e5045bd7a8d068017f073b5a5334023de0d59 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Tue, 5 Aug 2025 14:11:06 -0400 Subject: [PATCH] Streaming is theoretically implemented. My server does not support it, and most servers do not, but if any do it should work. Of course with no way to test, I'm just not sure. --- ttyverse.pl | 79 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/ttyverse.pl b/ttyverse.pl index 3026559..ca751ef 100755 --- a/ttyverse.pl +++ b/ttyverse.pl @@ -400,7 +400,7 @@ EOF $directurl = "${apibase}/conversations"; $listurl = "${apibase}/lists/%I/accounts"; $murl = "${apibase}/timelines/home"; - $streamurl = "${oauthbase}/api/v1/streaming/user"; + $streamurl = "${oauthbase}/api/v1/streaming"; $publicurl = "${apibase}/timelines/public"; $searchurl = "${oauthbase}/api/v2/search"; $trendsurl = "${apibase}/trends"; @@ -5920,29 +5920,68 @@ sub start_streaming { # restart nurse process if it/curl died goto HELLOAGAINNURSE if(!$streampid); - # read a line of text (hopefully numbers) - chomp($buf = ); - # should be nothing but digits and whitespace. - # if anything else, we're getting garbage, and we - # should reconnect. - if ($buf =~ /[^0-9\r\l\n\s]+/s) { + if ($authtype eq 'oauth2') { + # Handle Mastodon Server-Sent Events format + my $event_type = ''; + my $event_data = ''; + + # Read lines until we get a complete event + while(defined($buf = )) { + chomp($buf); + + # Empty line marks end of event + if ($buf eq '') { + if ($event_data) { + # Package the event data for processing + $duf = "{ \"packet\" : \"data\", \"pid\" : \"$streampid\", \"curlpid\" : \"$curlpid\", \"payload\" : $event_data }"; + printf STDOUT ("%08x%s", length($duf), $duf); + $packets_read++; + } + $event_type = ''; + $event_data = ''; + next HELLONURSE; + } + + # Parse SSE fields + if ($buf =~ /^event:\s*(.*)$/) { + $event_type = $1; + } elsif ($buf =~ /^data:\s*(.*)$/) { + $event_data .= $1; + } + # Ignore other SSE fields like 'id:', 'retry:', etc. + } + + # If we reach here, the stream ended - reconnect close(NURSE); kill 9, $streampid if ($streampid); - # and SIGCHLD will reap kill 9, $curlpid if ($curlpid); goto HELLOAGAINNURSE; + + } else { + # Handle legacy Twitter-style length-prefixed format + chomp($buf = ); + # should be nothing but digits and whitespace. + # if anything else, we're getting garbage, and we + # should reconnect. + if ($buf =~ /[^0-9\r\l\n\s]+/s) { + close(NURSE); + kill 9, $streampid if ($streampid); + # and SIGCHLD will reap + kill 9, $curlpid if ($curlpid); + goto HELLOAGAINNURSE; + } + $datasize = 0+$buf; + next HELLONURSE if (!$datasize); + $datasize--; + read(NURSE, $duf, $datasize); + # don't send broken entries + next HELLONURSE if (length($duf) < $datasize); + # yank out all \r\n + 1 while $duf =~ s/[\r\n]//g; + $duf = "{ \"packet\" : \"data\", \"pid\" : \"$streampid\", \"curlpid\" : \"$curlpid\", \"payload\" : $duf }"; + printf STDOUT ("%08x%s", length($duf), $duf); + $packets_read++; } - $datasize = 0+$buf; - next HELLONURSE if (!$datasize); - $datasize--; - read(NURSE, $duf, $datasize); - # don't send broken entries - next HELLONURSE if (length($duf) < $datasize); - # yank out all \r\n - 1 while $duf =~ s/[\r\n]//g; - $duf = "{ \"packet\" : \"data\", \"pid\" : \"$streampid\", \"curlpid\" : \"$curlpid\", \"payload\" : $duf }"; - printf STDOUT ("%08x%s", length($duf), $duf); - $packets_read++; } } else { # within the nurse process @@ -5963,7 +6002,7 @@ sub start_streaming { my $stream_endpoint; if ($authtype eq 'oauth2') { # Mastodon streaming - use Server-Sent Events - $stream_endpoint = "$streamurl?stream=user"; + $stream_endpoint = "$streamurl/user"; } else { # fediverse legacy streaming $stream_endpoint = "$streamurl?delimited=length${replarg}";