Complete rewrite to support new API.
This commit is contained in:
@ -1,9 +1,13 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
var (
|
var BotToken = ""
|
||||||
BotToken = "REDACTED"
|
|
||||||
CFBDAPIKey = "ay2L+7JSttYQP9e10qxpAkluht7NHcyEnSqbBUsqWrwVjBcl02QH2XjOaVDnPRBy"
|
var CustomTeamNames = map[string]string{
|
||||||
)
|
"UGA": "Georgia",
|
||||||
|
"Booger Eaters": "Auburn",
|
||||||
|
"Rape Enablers": "LSU",
|
||||||
|
"Checkerboard Clowns": "Tennessee",
|
||||||
|
}
|
||||||
|
|
||||||
func LoadConfig() {
|
func LoadConfig() {
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,41 @@
|
|||||||
package bot
|
package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"discord-cfb-bot/config"
|
||||||
"strings"
|
"discord-cfb-bot/internal/clients"
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
"discord-cfb-bot/internal/clients/cfb" // Adjust this import path as needed
|
"fmt"
|
||||||
"github.com/bwmarrin/discordgo"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MessageCreate handles incoming messages and triggers the appropriate response
|
var Bot *discordgo.Session
|
||||||
func MessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|
||||||
// Ignore messages from the bot itself
|
|
||||||
if m.Author.ID == s.State.User.ID {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Command for fetching college football scores
|
func Start() error {
|
||||||
if strings.HasPrefix(m.Content, "!cfb") {
|
var err error
|
||||||
// Extract any arguments (e.g., week number) if needed
|
Bot, err = discordgo.New("Bot " + config.BotToken)
|
||||||
weekNumber := 10 // Replace this with dynamic parsing if necessary
|
|
||||||
|
|
||||||
games, err := cfb.FetchScoreboard(weekNumber)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Error fetching games: %s", err))
|
return fmt.Errorf("error creating a Discord session: %w", err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(games) == 0 {
|
fmt.Println("Discord session created successfully")
|
||||||
s.ChannelMessageSend(m.ChannelID, "No games found for this week.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send formatted game summaries
|
Bot.AddHandler(commandHandler)
|
||||||
for _, game := range games {
|
err = Bot.Open()
|
||||||
gameSummary := cfb.FormatGameOutput(game)
|
if err != nil {
|
||||||
s.ChannelMessageSend(m.ChannelID, gameSummary)
|
return fmt.Errorf("Error opening connection: %w", err)
|
||||||
}
|
}
|
||||||
}
|
fmt.Println("Bot is now running.")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func commandHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||||
|
if m.Author.Bot {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(m.Content, "!cfb ") {
|
||||||
|
teamName := strings.TrimSpace(strings.TrimPrefix(m.Content, "!cfb "))
|
||||||
|
response := cfb.GetGameInfo(teamName)
|
||||||
|
s.ChannelMessageSend(m.ChannelID, response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,81 +1,98 @@
|
|||||||
package cfb
|
ipackage cfb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"strings"
|
||||||
"time"
|
|
||||||
|
"discord-cfb-bot/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Game represents the structure of a single game
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
AwayTeam string `json:"away_team"`
|
Game struct {
|
||||||
AwayScore string `json:"away_score"`
|
GameID string `json:"gameID"`
|
||||||
HomeTeam string `json:"home_team"`
|
StartDate string `json:"startDate"`
|
||||||
HomeScore string `json:"home_score"`
|
StartTime string `json:"startTime"`
|
||||||
GameState string `json:"game_state"`
|
GameState string `json:"gameState"`
|
||||||
CurrentPeriod string `json:"current_period"`
|
CurrentPeriod string `json:"currentPeriod"`
|
||||||
StartTime string `json:"start_time"`
|
ContestClock string `json:"contestClock"`
|
||||||
ContestClock string `json:"contest_clock"`
|
Home Team `json:"home"`
|
||||||
StartTimeEpoch int64 `json:"start_time_epoch"`
|
Away Team `json:"away"`
|
||||||
|
FinalMessage string `json:"finalMessage"`
|
||||||
|
} `json:"game"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchScoreboard retrieves and parses the scoreboard data from the specified API URL
|
type Team struct {
|
||||||
func FetchScoreboard(weekNumber int) ([]Game, error) {
|
Score string `json:"score"`
|
||||||
apiKey := os.Getenv("CFBD_API_KEY")
|
Names struct {
|
||||||
if apiKey == "" {
|
Short string `json:"short"`
|
||||||
return nil, errors.New("missing API key")
|
Full string `json:"full"`
|
||||||
|
} `json:"names"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetGameInfo(teamName string) string {
|
||||||
|
// Make the teamName input lowercase
|
||||||
|
teamNameLower := strings.ToLower(teamName)
|
||||||
|
|
||||||
|
// Check if the lowercase teamName matches a custom abbreviation
|
||||||
|
for key, value := range config.CustomTeamNames {
|
||||||
|
if strings.ToLower(key) == teamNameLower {
|
||||||
|
teamNameLower = strings.ToLower(value)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("https://ncaa.ewnix.net/scoreboard/football/fbs/2024/%d/all-conf", weekNumber)
|
apiURL := "https://ncaa.ewnix.net/scoreboard/football/fbs/2024/all-conf"
|
||||||
req, _ := http.NewRequest("GET", url, nil)
|
resp, err := http.Get(apiURL)
|
||||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey))
|
|
||||||
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return fmt.Sprintf("Failed to reach the scoreboard API: %v", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("failed to fetch scoreboard, status code: %d", resp.StatusCode)
|
return fmt.Sprintf("Failed to reach the scoreboard API. Status code: %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
var data struct {
|
|
||||||
Games []struct {
|
var apiResponse struct {
|
||||||
Game Game `json:"game"`
|
Games []Game `json:"games"`
|
||||||
} `json:"games"`
|
}
|
||||||
|
if err := json.Unmarshal(body, &apiResponse); err != nil {
|
||||||
|
return "Error parsing the API response."
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(body, &data); err != nil {
|
var results []string
|
||||||
return nil, fmt.Errorf("error parsing scoreboard: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
games := make([]Game, len(data.Games))
|
for _, game := range apiResponse.Games {
|
||||||
for i, g := range data.Games {
|
// Filter games by team name (either home or away)
|
||||||
// Adjust start time by subtracting 5 hours for upcoming games
|
if strings.ToLower(game.Game.Home.Names.Short) == teamNameLower ||
|
||||||
if g.Game.GameState == "upcoming" {
|
strings.ToLower(game.Game.Away.Names.Short) == teamNameLower {
|
||||||
epochTime := time.Unix(g.Game.StartTimeEpoch, 0).Add(-5 * time.Hour)
|
|
||||||
g.Game.StartTime = epochTime.Format("03:04PM ET")
|
var gameInfo string
|
||||||
|
if game.Game.GameState == "in_progress" {
|
||||||
|
gameInfo = fmt.Sprintf("%s: **%s** %s: **%s** | Quarter: %s | Time Remaining: %s",
|
||||||
|
game.Game.Away.Names.Short, game.Game.Away.Score,
|
||||||
|
game.Game.Home.Names.Short, game.Game.Home.Score,
|
||||||
|
game.Game.CurrentPeriod, game.Game.ContestClock)
|
||||||
|
} else if game.Game.GameState == "scheduled" {
|
||||||
|
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)
|
||||||
|
} else if game.Game.GameState == "final" {
|
||||||
|
gameInfo = fmt.Sprintf("Final: %s: %s %s: %s",
|
||||||
|
game.Game.Away.Names.Short, game.Game.Away.Score,
|
||||||
|
game.Game.Home.Names.Short, game.Game.Home.Score)
|
||||||
|
}
|
||||||
|
|
||||||
|
results = append(results, gameInfo)
|
||||||
}
|
}
|
||||||
games[i] = g.Game
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return games, nil
|
if len(results) > 0 {
|
||||||
}
|
return strings.Join(results, "\n")
|
||||||
|
|
||||||
// FormatGameOutput formats the game data into a string
|
|
||||||
func FormatGameOutput(game Game) string {
|
|
||||||
if game.GameState == "live" {
|
|
||||||
return fmt.Sprintf("%s: *%s* %s: *%s* Quarter: %s Time Remaining: %s",
|
|
||||||
game.AwayTeam, game.AwayScore, game.HomeTeam, game.HomeScore, game.CurrentPeriod, game.ContestClock)
|
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s: %s %s: %s Final",
|
|
||||||
game.AwayTeam, game.AwayScore, game.HomeTeam, game.HomeScore)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return "No game found for the specified team."
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user