package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "github.com/charmbracelet/log" "github.com/spf13/viper" "maunium.net/go/mautrix/id" ) type vtuberConfig struct { Name string `mapstructure:"name"` ChannelID string `mapstructure:"channelid"` LiveMsg string `mapstructure:"msg"` Announce bool `mapstructure:"Announce"` } // Vtuber represents a vtuber type Vtuber struct { Name string ChannelID string CurrentStream string CurrentStreamTitle string LiveMsg string AnnounceLive bool TotalStreams int Subs map[id.UserID]bool } func newVtuber(name, channelID, liveMsg string, announce bool) *Vtuber { return &Vtuber{ Name: name, ChannelID: channelID, CurrentStream: "", CurrentStreamTitle: "", LiveMsg: liveMsg, AnnounceLive: announce, TotalStreams: 0, Subs: make(map[id.UserID]bool), } } func loadVtubers() []*Vtuber { var vtubersRaw []vtuberConfig var vtubers []*Vtuber err := viper.UnmarshalKey("vtubers", &vtubersRaw) if err != nil { panic(err) } for _, vt := range vtubersRaw { log.Infof("adding vtuber %v", vt) vtubers = append(vtubers, newVtuber(vt.Name, vt.ChannelID, vt.LiveMsg, vt.Announce)) } return vtubers } // IsLive returns whether the specified Vtuber is live func (v *Vtuber) IsLive() bool { return v.CurrentStream != "" } // Update takes an apiKey and updates the vtuber struct func (v *Vtuber) Update(apiKey string) error { url := fmt.Sprintf( "https://holodex.net/api/v2/live?channel_id=%s&lang=all&sort=available_at&order=desc&limit=25&offset=0&paginated=%%3Cempty%%3E", v.ChannelID, ) req, err := http.NewRequest("GET", url, nil) req.Header.Set("X-APIKEY", apiKey) if err != nil { return fmt.Errorf("error creating GET %w", err) } res, err := http.DefaultClient.Do(req) if err != nil { return fmt.Errorf("error sending request %w", err) } defer res.Body.Close() if res.StatusCode != 200 { return fmt.Errorf("bad status code %v", res.StatusCode) } jsonBody, err := ioutil.ReadAll(res.Body) if err != nil { return fmt.Errorf("error reading response: %w", err) } var sl StreamList err = json.Unmarshal(jsonBody, &sl) if err != nil { return fmt.Errorf("error marshalling vtuber: %w %v", err, string(jsonBody)) } found := false for _, s := range sl.Streams { if s.Status == "live" { v.CurrentStream = s.ID v.CurrentStreamTitle = s.Title found = true } } if !found { v.CurrentStream = "" v.CurrentStreamTitle = "" } return nil }