Add actual support for live scores.
This commit is contained in:
@ -1,41 +1,41 @@
|
|||||||
package bot
|
package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"discord-cfb-bot/config"
|
"discord-cfb-bot/config"
|
||||||
"discord-cfb-bot/internal/clients"
|
"discord-cfb-bot/internal/clients"
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Bot *discordgo.Session
|
var Bot *discordgo.Session
|
||||||
|
|
||||||
func Start() error {
|
func Start() error {
|
||||||
var err error
|
var err error
|
||||||
Bot, err = discordgo.New("Bot " + config.BotToken)
|
Bot, err = discordgo.New("Bot " + config.BotToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating a Discord session: %w", err)
|
return fmt.Errorf("error creating a Discord session: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Discord session created successfully")
|
fmt.Println("Discord session created successfully")
|
||||||
|
|
||||||
Bot.AddHandler(commandHandler)
|
Bot.AddHandler(commandHandler)
|
||||||
err = Bot.Open()
|
err = Bot.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error opening connection: %w", err)
|
return fmt.Errorf("Error opening connection: %w", err)
|
||||||
}
|
}
|
||||||
fmt.Println("Bot is now running.")
|
fmt.Println("Bot is now running.")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func commandHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
|
func commandHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||||
if m.Author.Bot {
|
if m.Author.Bot {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(m.Content, "!s ") {
|
if strings.HasPrefix(m.Content, "!s ") {
|
||||||
teamName := strings.TrimSpace(strings.TrimPrefix(m.Content, "!s "))
|
teamName := strings.TrimSpace(strings.TrimPrefix(m.Content, "!s "))
|
||||||
response := clients.GetGameInfo(teamName)
|
response := clients.GetGameInfo(teamName)
|
||||||
s.ChannelMessageSend(m.ChannelID, response)
|
s.ChannelMessageSend(m.ChannelID, response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,115 +1,93 @@
|
|||||||
package cfbd_client
|
package clients
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"discord-cfb-bot/config"
|
"discord-cfb-bot/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
HomeTeam string `json:"home_team"`
|
ID int `json:"id"`
|
||||||
AwayTeam string `json:"away_team"`
|
StartDate string `json:"startDate"`
|
||||||
HomePoints *int `json:"home_points"`
|
Status string `json:"status"`
|
||||||
AwayPoints *int `json:"away_points"`
|
Period *int `json:"period"`
|
||||||
StartDateTime string `json:"start_date"`
|
Clock *string `json:"clock"`
|
||||||
|
HomeTeam Team `json:"homeTeam"`
|
||||||
|
AwayTeam Team `json:"awayTeam"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ScoreboardGame struct {
|
type Team struct {
|
||||||
HomeTeam string `json:"home_team"`
|
Name string `json:"name"`
|
||||||
AwayTeam string `json:"away_team"`
|
Points *int `json:"points"`
|
||||||
HomePoints *int `json:"home_points"`
|
|
||||||
AwayPoints *int `json:"away_points"`
|
|
||||||
StartDateTime string `json:"start_date"`
|
|
||||||
Status string `json:"status"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCurrentWeek() int {
|
|
||||||
seasonStartDate := "2024-08-28" // Replace with actual season start date
|
|
||||||
startDate, _ := time.Parse("2006-01-02", seasonStartDate)
|
|
||||||
weeks := int(time.Since(startDate).Hours() / (24 * 7))
|
|
||||||
return weeks + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func getLiveGame(teamName string) string {
|
|
||||||
url := "https://api.collegefootballdata.com/scoreboard"
|
|
||||||
currentWeek := getCurrentWeek()
|
|
||||||
params := fmt.Sprintf("?year=%d&week=%d", time.Now().Year(), currentWeek)
|
|
||||||
|
|
||||||
req, _ := http.NewRequest("GET", url+params, nil)
|
|
||||||
req.Header.Set("Authorization", "Bearer "+config.CFBDAPIKey)
|
|
||||||
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error fetching data from scoreboard API:", err)
|
|
||||||
return "Error fetching live game data."
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var games []ScoreboardGame
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&games); err != nil {
|
|
||||||
fmt.Println("Error decoding scoreboard response:", err)
|
|
||||||
return "Error parsing live game data."
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, game := range games {
|
|
||||||
if game.Status == "in_progress" && (game.HomeTeam == teamName || game.AwayTeam == teamName) {
|
|
||||||
return fmt.Sprintf("Live: %s: %d %s: %d", game.AwayTeam, *game.AwayPoints, game.HomeTeam, *game.HomePoints)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "No live games found for the team."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGameInfo(teamName string) string {
|
func GetGameInfo(teamName string) string {
|
||||||
apiUrl := "https://api.collegefootballdata.com/games"
|
apiURL := "https://apinext.collegefootballdata.com/scoreboard"
|
||||||
currentWeek := getCurrentWeek()
|
req, _ := http.NewRequest("GET", apiURL, nil)
|
||||||
queryParams := fmt.Sprintf("?year=%d&week=%d&team=%s", time.Now().Year(), currentWeek, url.QueryEscape(teamName))
|
req.Header.Set("Authorization", "Bearer "+config.CFBDAPIKey) // Use the API key from config
|
||||||
|
|
||||||
req, _ := http.NewRequest("GET", apiUrl+queryParams, nil)
|
|
||||||
req.Header.Set("Authorization", "Bearer "+config.CFBDAPIKey)
|
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error fetching data:", err)
|
return fmt.Sprintf("Failed to reach the scoreboard API: %v", err)
|
||||||
return "Error fetching game info."
|
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return fmt.Sprintf("Failed to reach the scoreboard API. Status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
|
||||||
var games []Game
|
var games []Game
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&games); err != nil {
|
if err := json.Unmarshal(body, &games); err != nil {
|
||||||
fmt.Println("Error decoding response:", err)
|
return "Error parsing the API response."
|
||||||
return "Error parsing game data."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, game := range games {
|
for _, game := range games {
|
||||||
startTime, _ := time.Parse(time.RFC3339, game.StartDateTime)
|
if strings.Contains(strings.ToLower(game.HomeTeam.Name), strings.ToLower(teamName)) ||
|
||||||
|
strings.Contains(strings.ToLower(game.AwayTeam.Name), strings.ToLower(teamName)) {
|
||||||
|
|
||||||
// Load Eastern Time location
|
startTime, _ := time.Parse(time.RFC3339, game.StartDate)
|
||||||
eastern, err := time.LoadLocation("America/New_York")
|
adjustedTime := startTime.Add(-5 * time.Hour) // Subtract 5 hours for upcoming games
|
||||||
if err != nil {
|
formattedTime := adjustedTime.Format("03:04 PM")
|
||||||
fmt.Println("Error loading Eastern timezone:", err)
|
|
||||||
return "Error fetching game time."
|
|
||||||
}
|
|
||||||
startTimeEastern := startTime.In(eastern)
|
|
||||||
|
|
||||||
if time.Now().After(startTime) && game.HomePoints != nil && game.AwayPoints != nil {
|
if game.Status == "in_progress" {
|
||||||
return fmt.Sprintf("%s: %d %s: %d", game.AwayTeam, *game.AwayPoints, game.HomeTeam, *game.HomePoints)
|
return fmt.Sprintf("%s: **%d** %s: **%d** | Quarter: %d | Time Remaining: %s",
|
||||||
} else if time.Now().Before(startTime) {
|
game.AwayTeam.Name, valueOrZero(game.AwayTeam.Points),
|
||||||
return fmt.Sprintf("%s @ %s %s Eastern", game.AwayTeam, game.HomeTeam, startTimeEastern.Format("03:04 PM"))
|
game.HomeTeam.Name, valueOrZero(game.HomeTeam.Points),
|
||||||
|
*game.Period, derefOrDefault(game.Clock, "00:00"))
|
||||||
|
} else if game.Status == "scheduled" {
|
||||||
|
return fmt.Sprintf("Upcoming: %s @ %s at %s Eastern",
|
||||||
|
game.AwayTeam.Name, game.HomeTeam.Name, formattedTime)
|
||||||
|
} else if game.Status == "completed" {
|
||||||
|
return fmt.Sprintf("Final: %s: %d %s: %d",
|
||||||
|
game.AwayTeam.Name, valueOrZero(game.AwayTeam.Points),
|
||||||
|
game.HomeTeam.Name, valueOrZero(game.HomeTeam.Points))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the getLiveGame function if no specific game is found
|
return "No game found for the specified team."
|
||||||
liveGameResult := getLiveGame(teamName)
|
|
||||||
if liveGameResult != "No live games found for the team." {
|
|
||||||
return liveGameResult
|
|
||||||
}
|
|
||||||
|
|
||||||
return "No recent, upcoming, or live games found for the team."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to safely dereference pointers
|
||||||
|
func derefOrDefault(str *string, defaultVal string) string {
|
||||||
|
if str != nil {
|
||||||
|
return *str
|
||||||
|
}
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to return a value or zero if nil
|
||||||
|
func valueOrZero(val *int) int {
|
||||||
|
if val != nil {
|
||||||
|
return *val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user