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}";