This repository has been archived on 2023-09-29. You can view files and clone it, but cannot push or open issues or pull requests.
twitch_data_collector/main.go

144 lines
3.3 KiB
Go

package main
import (
"context"
"encoding/json"
"net/http"
"time"
"github.com/Luzifer/rconfig"
gorilla "github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
"golang.org/x/oauth2"
)
var cfg = struct {
SettingsFile string `default:"settings.yml" flag:"settings-file" description:"Path to settings file"`
}{}
func main() {
rconfig.Parse(&cfg)
settingsUpdater()
loadUser()
go checkUserToken()
log.Infof("User: %+v", user)
mux := gorilla.NewRouter()
mux.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
mux.HandleFunc("/login", handleTwitchLogin)
mux.HandleFunc("/callback", handleTwitchCallback)
mux.HandleFunc("/data", func(w http.ResponseWriter, r *http.Request) {
if user == nil {
http.NotFound(w, r)
return
}
w.Header().Set("Access-Control-Allow-Headers", "*")
if err := json.NewEncoder(w).Encode(user.getWebUser()); err != nil {
log.WithError(err).Error("Unable to encode user data")
http.Error(w, "Unable to encode user data", http.StatusInternalServerError)
return
}
})
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hi!"))
})
go func() {
if user != nil {
handleSaves()
}
interval := 20 * time.Second
if settings.UpdateInterval > 10*time.Second {
interval = settings.UpdateInterval
}
log.Infof("Update interval: %s", interval)
c := time.Tick(interval)
for range c {
if user == nil {
continue
}
handleSaves()
}
}()
log.Info("Starting webserver...")
log.Fatal(http.ListenAndServe(":"+settings.WebserverPort, mux))
}
func handleSaves() {
if user == nil {
return
}
getUser(user)
if user.TwitchUser != nil {
user.TwitchUser.SaveFiles()
}
getChannel(user)
if user.TwitchChannel != nil {
user.TwitchChannel.SaveFiles()
}
maxFollower := -1
if settings.MaxFollowers > 0 {
maxFollower = settings.MaxFollowers
}
log.Infof("Fetch max follower: %d", maxFollower)
getFollows(user, maxFollower)
if user.TwitchFollowers != nil {
user.TwitchFollowers.SaveFiles()
}
maxSubs := -1
if settings.MaxSubs > 0 {
maxSubs = settings.MaxSubs
}
log.Infof("Fetch max subs: %d", maxSubs)
getSubs(user, maxSubs)
if user.TwitchSubscriptions != nil {
user.TwitchSubscriptions.SaveFiles()
}
getStreams(user)
if user.TwitchStream != nil {
user.TwitchStream.SaveFiles()
}
}
func handleTwitchLogin(w http.ResponseWriter, r *http.Request) {
url := twitchOauthConfig.AuthCodeURL(settings.VerificationToken, oauth2.AccessTypeOffline)
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}
func handleTwitchCallback(w http.ResponseWriter, r *http.Request) {
twitchAuthToToken(r.FormValue("state"), r.FormValue("code"), w, r)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}
func twitchAuthToToken(state string, code string, w http.ResponseWriter, r *http.Request) {
if state != settings.VerificationToken {
log.Fatal("invalid oauth state")
}
timeoutCtx, cancel := context.WithTimeout(oauth2.NoContext, 5*time.Second)
defer cancel()
token, err := twitchOauthConfig.Exchange(timeoutCtx, code, oauth2.AccessTypeOffline)
if err != nil {
log.WithError(err).Error("code exchange failed")
return
}
u, err := createUser(token)
if err != nil {
log.WithError(err).Error("Unable to get user")
return
}
u.Token = token
user = u
log.Infof("User: %+v, User: %+v", user, user.TwitchUser)
saveUser()
}