110 lines
2.7 KiB
Go
110 lines
2.7 KiB
Go
package twitch
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"velox-bot/internal/db/repos/twitchrepo"
|
|
)
|
|
|
|
type Service struct {
|
|
repo *twitchrepo.Repo
|
|
client *http.Client
|
|
twitchClient string
|
|
}
|
|
|
|
func New(repo *twitchrepo.Repo, twitchClientID string) *Service {
|
|
return &Service{
|
|
repo: repo,
|
|
client: &http.Client{
|
|
Timeout: 5 * time.Second,
|
|
},
|
|
twitchClient: twitchClientID,
|
|
}
|
|
}
|
|
|
|
func (s *Service) ListGuilds(ctx context.Context) ([]int64, error) {
|
|
return s.repo.ListGuilds(ctx)
|
|
}
|
|
|
|
func (s *Service) ListUsersForGuild(ctx context.Context, guildID int64) ([]string, error) {
|
|
return s.repo.ListUsersForGuild(ctx, guildID)
|
|
}
|
|
|
|
func (s *Service) GetStatus(ctx context.Context, guildID int64, username string) (string, bool, error) {
|
|
return s.repo.GetStatus(ctx, guildID, username)
|
|
}
|
|
|
|
func (s *Service) UpdateStatus(ctx context.Context, guildID int64, username, status string) error {
|
|
return s.repo.UpdateStatus(ctx, guildID, username, status)
|
|
}
|
|
|
|
func (s *Service) UpsertStreamer(ctx context.Context, guildID int64, username string) error {
|
|
return s.repo.UpsertStreamer(ctx, guildID, username)
|
|
}
|
|
|
|
func (s *Service) RemoveStreamer(ctx context.Context, guildID int64, username string) error {
|
|
return s.repo.RemoveStreamer(ctx, guildID, username)
|
|
}
|
|
|
|
func (s *Service) GetNotificationChannel(ctx context.Context, guildID int64) (int64, bool, error) {
|
|
return s.repo.GetNotificationChannel(ctx, guildID)
|
|
}
|
|
|
|
func (s *Service) SetNotificationChannel(ctx context.Context, guildID, channelID int64) error {
|
|
return s.repo.SetNotificationChannel(ctx, guildID, channelID)
|
|
}
|
|
|
|
func (s *Service) IsUserStreaming(ctx context.Context, username string) (bool, error) {
|
|
type gqlRequest struct {
|
|
Query string `json:"query"`
|
|
Variables map[string]any `json:"variables"`
|
|
}
|
|
type gqlResponse struct {
|
|
Data struct {
|
|
User *struct {
|
|
Stream *struct {
|
|
ID string `json:"id"`
|
|
} `json:"stream"`
|
|
} `json:"user"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
q := fmt.Sprintf(`query { user(login: "%s") { stream { id } } }`, username)
|
|
body, err := json.Marshal(gqlRequest{
|
|
Query: q,
|
|
Variables: map[string]any{},
|
|
})
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://gql.twitch.tv/gql", bytes.NewReader(body))
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Client-Id", s.twitchClient)
|
|
|
|
resp, err := s.client.Do(req)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
var respBody gqlResponse
|
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if respBody.Data.User == nil {
|
|
return false, nil
|
|
}
|
|
return respBody.Data.User.Stream != nil, nil
|
|
}
|
|
|