// Just a program to display information about twitch. // Token can be found at https://dev.twitch.tv/console // Also can be obtained at the console I beleive, but twitch-cli token also // gives a valid token. package main import ( "auth" "context" "fmt" "os" "github.com/charmbracelet/log" "github.com/nicklaw5/helix/v2" ) var authCtx, authCancel = context.WithCancel(context.Background()) var helixOptions helix.Options var defaultUserID string func init() { config, err := read_config() if err != nil { fmt.Printf("Error with config: %v\n", err) fmt.Println("Use the init subcommand to initialize a config file.") } else { helixOptions.ClientID = config.ClientID helixOptions.ClientSecret = config.ClientSecret defaultUserID = config.UserID } maybeSet := func(out *string, env string) { val, isSet := os.LookupEnv(env) if isSet { *out = val } } // Override any argument if a corresponding environment variable is set. maybeSet(&helixOptions.ClientID, "TWITCH_CLIENT_ID") // maybeSet(&helixOptions.AppAccessToken, "TWITCH_APP_TOKEN") maybeSet(&helixOptions.ClientSecret, "TWITCH_CLIENT_SECRET") } func printHelp() { fmt.Println("Print help about commands here.") } // Note: // Currently everything is intended to just have all the scopes possible for // us to need to be requested.. func main() { ctx := context.Background() runAuth := func() *helix.Client { client, err := helix.NewClient(&helixOptions) if err != nil { panic(err) } // Ask for all scopes up front. Not handling scope renegotiation at the // moment. a, err := auth.New(&ctx, client, []string{"user:read:follows"}) if err != nil { log.Info("Need to reauth") } if !a.HaveAuth { ch, err := a.StartAuth("", []string{"user:read:follows"}) if err != nil { panic(err) } <-ch } return client } if len(os.Args) < 2 { printHelp() panic("Insufficient arguments.") } switch os.Args[1] { case "category": { client := runAuth() categories(client, os.Args[2:]) } case "search": { client := runAuth() search(client, os.Args[2:]) } case "live": { // TODO: FlagSet client := runAuth() // Always assume config has ID for now. err := getFollowedLive(client, defaultUserID) if err != nil { panic("Couldn't get followed streams.") } } case "games": { // TODO: FlagSet // XXX: Handle a list of game search terms maybe. client := runAuth() if err := printGames(client, []string{os.Args[2]}); err != nil { panic("Couldn't list games") } } case "init": { newConfig, err := setupAuth() if err != nil { panic("Something went wrong with init.") } helixOptions.ClientID = newConfig.ClientID helixOptions.ClientSecret = newConfig.ClientSecret client := runAuth() users, err := getUsersByName(client, []string{newConfig.UserName}) if err != nil { log.Fatalf("Couldn't look up user '%v': %v\n", newConfig.UserName, err) } newConfig.UserID = users[0].ID // Hopefully the config is safe to write. write_config(newConfig) } case "user": { // TODO: FlagSet client := runAuth() users, err := getUsersByName(client, []string{os.Args[2]}) if err != nil { panic("Something went wrong with user fetch.") } for _, user := range users { fmt.Printf("%+v\n", user) } } default: printHelp() } }