Holy shit this was hard

This commit is contained in:
2024-11-10 21:18:37 -05:00
parent 9eee8c7f9c
commit cd33fd2584
3 changed files with 119 additions and 66 deletions

View File

@ -1,48 +1,76 @@
package bot package bot
import ( import (
"discord-cfb-bot/config" "discord-cfb-bot/config"
cfbClient "discord-cfb-bot/internal/clients/cfb" cfbClient "discord-cfb-bot/internal/clients/cfb"
cbbClient "discord-cfb-bot/internal/clients/cbb" cbbClient "discord-cfb-bot/internal/clients/cbb"
"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, "!cfb ") {
teamName := strings.TrimSpace(strings.TrimPrefix(m.Content, "!cfb "))
response := cfbClient.GetGameInfo(teamName)
s.ChannelMessageSend(m.ChannelID, response)
}
if strings.HasPrefix(m.Content, "!cbb ") {
content := strings.TrimSpace(strings.TrimPrefix(m.Content, "!cbb "))
parts := strings.SplitN(content, " ", 2)
teamName := parts[0]
date := ""
if len(parts) > 1 {
if isDateFormat(parts[1]) {
date = parts[1]
} else {
teamName = content // Reset team name to include all parts if no valid date
}
} }
if strings.HasPrefix(m.Content, "!cfb ") { // Check if the team name is a custom name defined in config
teamName := strings.TrimSpace(strings.TrimPrefix(m.Content, "!cfb ")) if customTeam, exists := config.CustomTeamNames[strings.ToLower(teamName)]; exists {
response := cfbClient.GetGameInfo(teamName) response := cbbClient.GetGameInfo(customTeam, date) // Exact match for custom teams
s.ChannelMessageSend(m.ChannelID, response) s.ChannelMessageSend(m.ChannelID, response)
} else {
response := cbbClient.GetGameInfo(teamName, date) // General match for all teams
s.ChannelMessageSend(m.ChannelID, response)
} }
}
if strings.HasPrefix(m.Content, "!cbb ") {
teamName := strings.TrimSpace(strings.TrimPrefix(m.Content, "!cbb "))
response := cbbClient.GetGameInfo(teamName)
s.ChannelMessageSend(m.ChannelID, response)
}
} }
// isDateFormat checks if a string is in the MM/DD format
func isDateFormat(dateStr string) bool {
parts := strings.Split(dateStr, "/")
if len(parts) != 2 {
return false
}
return len(parts[0]) <= 2 && len(parts[1]) <= 2 // Simple check for MM/DD format
}

View File

@ -6,8 +6,8 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strings" "strings"
"time"
"discord-cfb-bot/config" "unicode"
) )
type Game struct { type Game struct {
@ -32,19 +32,27 @@ type Team struct {
} `json:"names"` } `json:"names"`
} }
func GetGameInfo(teamName string) string { func GetGameInfo(teamName, date string) string {
// Make the teamName input lowercase // If no date is provided, use today's date
teamNameLower := strings.ToLower(teamName) if date == "" {
date = time.Now().Format("2006/01/02") // Format as YYYY/MM/DD
// Check if the lowercase teamName matches a custom abbreviation } else {
for key, value := range config.CustomTeamNames { // Check if the last 5 characters are in MM/DD format for date input
if strings.ToLower(key) == teamNameLower { if len(date) == 5 && unicode.IsDigit(rune(date[0])) && unicode.IsDigit(rune(date[1])) && date[2] == '/' &&
teamNameLower = strings.ToLower(value) unicode.IsDigit(rune(date[3])) && unicode.IsDigit(rune(date[4])) {
break date = fmt.Sprintf("2024/%s", strings.ReplaceAll(date, "/", "/")) // Add the year and reformat
} else {
return "Invalid date format. Please use MM/DD."
} }
} }
apiURL := "https://ncaa.ewnix.net/scoreboard/basketball-men/d1" apiURL := fmt.Sprintf("https://ncaa.ewnix.net/scoreboard/basketball-men/d1/%s", date)
return fetchAndParseGames(apiURL, teamName)
}
func fetchAndParseGames(apiURL, teamName string) string {
teamNameLower := strings.ToLower(teamName)
resp, err := http.Get(apiURL) resp, err := http.Get(apiURL)
if err != nil { if err != nil {
return fmt.Sprintf("Failed to reach the scoreboard API: %v", err) return fmt.Sprintf("Failed to reach the scoreboard API: %v", err)
@ -67,17 +75,20 @@ func GetGameInfo(teamName string) string {
var results []string var results []string
for _, game := range apiResponse.Games { for _, game := range apiResponse.Games {
// Filter games by team name (either home or away)
if strings.ToLower(game.Game.Home.Names.Short) == teamNameLower || if strings.ToLower(game.Game.Home.Names.Short) == teamNameLower ||
strings.ToLower(game.Game.Away.Names.Short) == teamNameLower { strings.ToLower(game.Game.Away.Names.Short) == teamNameLower {
var gameInfo string var gameInfo string
if game.Game.GameState == "in_progress" { if game.Game.GameState == "live" {
gameInfo = fmt.Sprintf("%s: **%s** %s: **%s** | Half: %s | Time Remaining: %s", currentPeriod := game.Game.CurrentPeriod
if currentPeriod == "" {
currentPeriod = "HALFTIME"
}
gameInfo = fmt.Sprintf("Live: %s: **%s** %s: **%s** | Half: %s | Time Remaining: %s",
game.Game.Away.Names.Short, game.Game.Away.Score, game.Game.Away.Names.Short, game.Game.Away.Score,
game.Game.Home.Names.Short, game.Game.Home.Score, game.Game.Home.Names.Short, game.Game.Home.Score,
game.Game.CurrentPeriod, game.Game.ContestClock) currentPeriod, game.Game.ContestClock)
} else if game.Game.GameState == "scheduled" { } else if game.Game.GameState == "pre" {
gameInfo = fmt.Sprintf("Upcoming: %s @ %s on %s at %s ET", gameInfo = fmt.Sprintf("Upcoming: %s @ %s on %s at %s ET",
game.Game.Away.Names.Short, game.Game.Home.Names.Short, game.Game.StartDate, game.Game.StartTime) game.Game.Away.Names.Short, game.Game.Home.Names.Short, game.Game.StartDate, game.Game.StartTime)
} else if game.Game.GameState == "final" { } else if game.Game.GameState == "final" {
@ -96,3 +107,4 @@ func GetGameInfo(teamName string) string {
return "No game found for the specified team." return "No game found for the specified team."
} }

View File

@ -4,10 +4,10 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"strings" "strings"
"unicode"
"discord-cfb-bot/config"
) )
type Game struct { type Game struct {
@ -33,18 +33,24 @@ type Team struct {
} }
func GetGameInfo(teamName string) string { func GetGameInfo(teamName string) string {
// Make the teamName input lowercase teamName = strings.TrimSpace(teamName)
teamNameLower := strings.ToLower(teamName) week := ""
// Check if the lowercase teamName matches a custom abbreviation // Check if the last two characters of the input are integers for the week
for key, value := range config.CustomTeamNames { if len(teamName) >= 2 && unicode.IsDigit(rune(teamName[len(teamName)-1])) && unicode.IsDigit(rune(teamName[len(teamName)-2])) {
if strings.ToLower(key) == teamNameLower { week = teamName[len(teamName)-2:]
teamNameLower = strings.ToLower(value) teamName = strings.TrimSpace(teamName[:len(teamName)-2])
break log.Printf("Week detected: %s", week)
}
} }
apiURL := "https://ncaa.ewnix.net/scoreboard/football/fbs/2024/all-conf" // Build the API URL based on whether a week is provided
apiURL := "https://ncaa.ewnix.net/scoreboard/football/fbs"
if week != "" {
apiURL = fmt.Sprintf("https://ncaa.ewnix.net/scoreboard/football/fbs/2024/%s/all-conf", week)
}
log.Printf("Fetching data from API: %s", apiURL)
resp, err := http.Get(apiURL) resp, err := http.Get(apiURL)
if err != nil { if err != nil {
return fmt.Sprintf("Failed to reach the scoreboard API: %v", err) return fmt.Sprintf("Failed to reach the scoreboard API: %v", err)
@ -65,23 +71,29 @@ func GetGameInfo(teamName string) string {
} }
var results []string var results []string
teamNameLower := strings.ToLower(teamName)
for _, game := range apiResponse.Games { for _, game := range apiResponse.Games {
// Filter games by team name (either home or away) homeTeamLowerShort := strings.ToLower(game.Game.Home.Names.Short)
if strings.ToLower(game.Game.Home.Names.Short) == teamNameLower || awayTeamLowerShort := strings.ToLower(game.Game.Away.Names.Short)
strings.ToLower(game.Game.Away.Names.Short) == teamNameLower {
// Check if the team matches the short name only
if homeTeamLowerShort == teamNameLower || awayTeamLowerShort == teamNameLower {
var gameInfo string var gameInfo string
if game.Game.GameState == "in_progress" { if game.Game.GameState == "live" {
period := game.Game.CurrentPeriod
if period == "" {
period = "HALFTIME"
}
gameInfo = fmt.Sprintf("%s: **%s** %s: **%s** | Quarter: %s | Time Remaining: %s", gameInfo = fmt.Sprintf("%s: **%s** %s: **%s** | Quarter: %s | Time Remaining: %s",
game.Game.Away.Names.Short, game.Game.Away.Score, game.Game.Away.Names.Short, game.Game.Away.Score,
game.Game.Home.Names.Short, game.Game.Home.Score, game.Game.Home.Names.Short, game.Game.Home.Score,
game.Game.CurrentPeriod, game.Game.ContestClock) period, game.Game.ContestClock)
} else if game.Game.GameState == "scheduled" { } else if game.Game.GameState == "pre" {
gameInfo = fmt.Sprintf("Upcoming: %s @ %s on %s at %s ET", gameInfo = fmt.Sprintf("Upcoming: %s @ %s on %s at %s ET",
game.Game.Away.Names.Short, game.Game.Home.Names.Short, game.Game.StartDate, game.Game.StartTime) game.Game.Away.Names.Short, game.Game.Home.Names.Short, game.Game.StartDate, game.Game.StartTime)
} else if game.Game.GameState == "final" { } else if game.Game.GameState == "final" {
gameInfo = fmt.Sprintf("Final: %s: %s %s: %s", gameInfo = fmt.Sprintf("Final: %s: **%s** %s: **%s**",
game.Game.Away.Names.Short, game.Game.Away.Score, game.Game.Away.Names.Short, game.Game.Away.Score,
game.Game.Home.Names.Short, game.Game.Home.Score) game.Game.Home.Names.Short, game.Game.Home.Score)
} }
@ -96,3 +108,4 @@ func GetGameInfo(teamName string) string {
return "No game found for the specified team." return "No game found for the specified team."
} }