First commit
This commit is contained in:
146
cfb/cfb_client.go
Normal file
146
cfb/cfb_client.go
Normal file
@ -0,0 +1,146 @@
|
||||
package cfb
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"matrix-scores-bot/config"
|
||||
)
|
||||
|
||||
// Game holds the nested game data structure from the API.
|
||||
type Game struct {
|
||||
Game struct {
|
||||
GameID string `json:"gameID"`
|
||||
StartDate string `json:"startDate"`
|
||||
StartTime string `json:"startTime"`
|
||||
StartTimeEpoch string `json:"startTimeEpoch"`
|
||||
GameState string `json:"gameState"`
|
||||
CurrentPeriod string `json:"currentPeriod"`
|
||||
ContestClock string `json:"contestClock"`
|
||||
Home Team `json:"home"`
|
||||
Away Team `json:"away"`
|
||||
FinalMessage string `json:"finalMessage"`
|
||||
} `json:"game"`
|
||||
}
|
||||
|
||||
// Team holds the team's score and names.
|
||||
type Team struct {
|
||||
Score string `json:"score"`
|
||||
Names struct {
|
||||
Short string `json:"short"`
|
||||
Full string `json:"full"`
|
||||
} `json:"names"`
|
||||
}
|
||||
|
||||
// GetGameInfo fetches and returns information for a specific team or week.
|
||||
func GetGameInfo(input string) string {
|
||||
teamName := strings.TrimSpace(strings.ToLower(input))
|
||||
week := ""
|
||||
|
||||
// Replace custom team name if configured
|
||||
if custom, ok := config.CustomTeamNames[teamName]; ok {
|
||||
log.Printf("Custom team name detected: %s -> %s", teamName, custom)
|
||||
teamName = custom
|
||||
}
|
||||
|
||||
// Detect week if last two chars are digits
|
||||
if len(teamName) >= 2 {
|
||||
last2 := teamName[len(teamName)-2:]
|
||||
if unicode.IsDigit(rune(last2[0])) && unicode.IsDigit(rune(last2[1])) {
|
||||
week = last2
|
||||
teamName = strings.TrimSpace(teamName[:len(teamName)-2])
|
||||
log.Printf("Week detected: %s", week)
|
||||
}
|
||||
}
|
||||
|
||||
// Build URL
|
||||
url := fmt.Sprintf("https://ncaa.ewnix.net/scoreboard/football/fbs/2024/%s/all-conf", week)
|
||||
if week == "" {
|
||||
url = "https://ncaa.ewnix.net/scoreboard/football/fbs/2024/current/all-conf"
|
||||
}
|
||||
log.Printf("Fetching CFB data from API: %s", url)
|
||||
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("Failed to reach the scoreboard API: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Sprintf("API error: status code %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("Error reading API response: %v", err)
|
||||
}
|
||||
|
||||
var apiResponse struct {
|
||||
Games []Game `json:"games"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &apiResponse); err != nil {
|
||||
return "Error parsing the API response."
|
||||
}
|
||||
|
||||
results := []string{}
|
||||
teamKey := strings.ToLower(teamName)
|
||||
|
||||
for _, g := range apiResponse.Games {
|
||||
h := strings.ToLower(g.Game.Home.Names.Short)
|
||||
a := strings.ToLower(g.Game.Away.Names.Short)
|
||||
|
||||
if h == teamKey || a == teamKey {
|
||||
var info string
|
||||
s := g.Game
|
||||
if s.GameState == "live" {
|
||||
period := s.CurrentPeriod
|
||||
if period == "" {
|
||||
period = "HALFTIME"
|
||||
}
|
||||
info = fmt.Sprintf("%s: <strong>%s</strong> %s: <strong>%s</strong> | Quarter: %s | Time Remaining: %s",
|
||||
s.Away.Names.Short, s.Away.Score,
|
||||
s.Home.Names.Short, s.Home.Score,
|
||||
period, s.ContestClock)
|
||||
} else if s.GameState == "pre" {
|
||||
timeCT, err := convertEpochToCentralTime(s.StartTimeEpoch)
|
||||
if err != nil {
|
||||
timeCT = s.StartTime
|
||||
}
|
||||
info = fmt.Sprintf("Upcoming: %s @ %s on %s at %s CT",
|
||||
s.Away.Names.Short, s.Home.Names.Short, s.StartDate, timeCT)
|
||||
} else if s.GameState == "final" {
|
||||
info = fmt.Sprintf("Final: %s: <strong>%s</strong> %s: <strong>%s</strong>",
|
||||
s.Away.Names.Short, s.Away.Score,
|
||||
s.Home.Names.Short, s.Home.Score)
|
||||
}
|
||||
results = append(results, info)
|
||||
}
|
||||
}
|
||||
|
||||
if len(results) > 0 {
|
||||
return strings.Join(results, "\n")
|
||||
}
|
||||
|
||||
return "No game found for the specified team."
|
||||
}
|
||||
|
||||
func convertEpochToCentralTime(epochStr string) (string, error) {
|
||||
epoch, err := strconv.ParseInt(epochStr, 10, 64)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error parsing epoch: %w", err)
|
||||
}
|
||||
|
||||
t := time.Unix(epoch, 0).UTC()
|
||||
loc, err := time.LoadLocation("America/Chicago")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error loading location: %w", err)
|
||||
}
|
||||
return t.In(loc).Format("03:04 PM"), nil
|
||||
}
|
Reference in New Issue
Block a user