feat: add twitch live detection to streamer list
This commit is contained in:
@@ -33,6 +33,17 @@ type Channel struct {
|
||||
Login string
|
||||
}
|
||||
|
||||
// StreamInfo describes whether a channel is live.
|
||||
type StreamInfo struct {
|
||||
Online bool
|
||||
}
|
||||
|
||||
// PlaybackToken carries the Twitch playback token/signature pair for live HLS access.
|
||||
type PlaybackToken struct {
|
||||
Signature string
|
||||
Value string
|
||||
}
|
||||
|
||||
// StreamerStatus describes one row's resolution state in the UI.
|
||||
type StreamerStatus string
|
||||
|
||||
@@ -47,6 +58,7 @@ type StreamerEntry struct {
|
||||
ConfigLogin string
|
||||
Login string
|
||||
ChannelID string
|
||||
Live bool
|
||||
Status StreamerStatus
|
||||
Error string
|
||||
}
|
||||
@@ -106,3 +118,44 @@ func (s *Service) ResolveStreamer(ctx context.Context, login string) (*Channel,
|
||||
}
|
||||
return &Channel{ID: data.User.ID, Login: resolvedLogin}, nil
|
||||
}
|
||||
|
||||
// StreamInfo resolves whether the given channel ID is currently live.
|
||||
func (s *Service) StreamInfo(ctx context.Context, channelID string) (*StreamInfo, error) {
|
||||
var data struct {
|
||||
User *struct {
|
||||
Stream *struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"stream"`
|
||||
} `json:"user"`
|
||||
}
|
||||
if err := s.GQL.Do(ctx, gql.WithIsStreamLiveQuery(channelID), &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if data.User == nil {
|
||||
return nil, fmt.Errorf("stream info missing user for channel %s", channelID)
|
||||
}
|
||||
if data.User.Stream == nil {
|
||||
return &StreamInfo{Online: false}, nil
|
||||
}
|
||||
return &StreamInfo{Online: true}, nil
|
||||
}
|
||||
|
||||
// PlaybackAccessToken fetches the Twitch playback token needed to access a live stream.
|
||||
func (s *Service) PlaybackAccessToken(ctx context.Context, login string) (*PlaybackToken, error) {
|
||||
var data struct {
|
||||
StreamPlaybackAccessToken *struct {
|
||||
Signature string `json:"signature"`
|
||||
Value string `json:"value"`
|
||||
} `json:"streamPlaybackAccessToken"`
|
||||
}
|
||||
if err := s.GQL.Do(ctx, gql.PlaybackAccessToken(login), &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if data.StreamPlaybackAccessToken == nil || data.StreamPlaybackAccessToken.Signature == "" || data.StreamPlaybackAccessToken.Value == "" {
|
||||
return nil, fmt.Errorf("playback access token missing signature or value for %s", login)
|
||||
}
|
||||
return &PlaybackToken{
|
||||
Signature: data.StreamPlaybackAccessToken.Signature,
|
||||
Value: data.StreamPlaybackAccessToken.Value,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user