fix: event and odd fetching for all sports
This commit is contained in:
parent
bab1c6bb4c
commit
c0680537db
|
|
@ -14,6 +14,13 @@ var SupportedLeagues = []int64{
|
||||||
10047168, // US MLS
|
10047168, // US MLS
|
||||||
10044469, // Ethiopian Premier League
|
10044469, // Ethiopian Premier League
|
||||||
10050282, //UEFA Nations League
|
10050282, //UEFA Nations League
|
||||||
|
10044685, //FIFA Club World Cup
|
||||||
|
10082328, //Kings League World Cup
|
||||||
|
10081269, //CONCACAF Champions Cup
|
||||||
|
10040162, //Asia - World Cup Qualifying
|
||||||
|
10067624, //South America - World Cup Qualifying
|
||||||
|
10067913, // Europe - World Cup Qualifying
|
||||||
|
10067624, // South America - World Cup Qualifying
|
||||||
|
|
||||||
10043156, //England FA Cup
|
10043156, //England FA Cup
|
||||||
10042103, //France Cup
|
10042103, //France Cup
|
||||||
|
|
@ -22,6 +29,21 @@ var SupportedLeagues = []int64{
|
||||||
10041187, //Kenya Super League
|
10041187, //Kenya Super League
|
||||||
10041315, //Italian Serie A
|
10041315, //Italian Serie A
|
||||||
10041391, //Netherlands Eredivisie
|
10041391, //Netherlands Eredivisie
|
||||||
|
10036538, //Spain Segunda
|
||||||
|
10041058, //Denmark Superligaen
|
||||||
|
10077480, //Women’s International
|
||||||
|
10046936, // USA NPSL
|
||||||
|
10085159, //Baller League UK
|
||||||
|
10040601, //Argentina Cup
|
||||||
|
10037440, //Brazil Serie A
|
||||||
|
10043205, //Copa Sudamericana
|
||||||
|
|
||||||
|
10037327, //Austria Landesliga
|
||||||
|
10082020, //USA USL League One Cup
|
||||||
|
10037075, //International Match
|
||||||
|
10046648, //Kenya Cup
|
||||||
|
10040485, //Kenya Super League
|
||||||
|
10041369, //Norway Eliteserien
|
||||||
|
|
||||||
// Basketball
|
// Basketball
|
||||||
173998768, //NBA
|
173998768, //NBA
|
||||||
|
|
@ -30,10 +52,15 @@ var SupportedLeagues = []int64{
|
||||||
10037165, //German Bundesliga
|
10037165, //German Bundesliga
|
||||||
10036608, //Italian Lega 1
|
10036608, //Italian Lega 1
|
||||||
10040795, //EuroLeague
|
10040795, //EuroLeague
|
||||||
|
10084178, //Kenya Premier League
|
||||||
|
10043548, //International Women
|
||||||
|
|
||||||
// Ice Hockey
|
// Ice Hockey
|
||||||
10037477, //NHL
|
10037477, //NHL
|
||||||
10037447, //AHL
|
10037447, //AHL
|
||||||
|
10074238, // AIHL
|
||||||
10069385, //IIHF World Championship
|
10069385, //IIHF World Championship
|
||||||
|
|
||||||
|
// Cricket
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,3 +49,76 @@ type IceHockeyOddsResponse struct {
|
||||||
FirstPeriod OddsSection `json:"1st_period"`
|
FirstPeriod OddsSection `json:"1st_period"`
|
||||||
Others []OddsSection `json:"others"`
|
Others []OddsSection `json:"others"`
|
||||||
}
|
}
|
||||||
|
type CricketOddsResponse struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
FI string `json:"FI"`
|
||||||
|
First_Over OddsSection `json:"1st_over"`
|
||||||
|
First_Innings OddsSection `json:"innings_1"`
|
||||||
|
Main OddsSection `json:"main"`
|
||||||
|
Match OddsSection `json:"match"`
|
||||||
|
Others []OddsSection `json:"others"`
|
||||||
|
Player OddsSection `json:"player"`
|
||||||
|
Team OddsSection `json:"team"`
|
||||||
|
}
|
||||||
|
type VolleyballOddsResponse struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
FI string `json:"FI"`
|
||||||
|
Main OddsSection `json:"main"`
|
||||||
|
Others []OddsSection `json:"others"`
|
||||||
|
}
|
||||||
|
type DartsOddsResponse struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
FI string `json:"FI"`
|
||||||
|
OneEightys OddsSection `json:"180s"`
|
||||||
|
Extra OddsSection `json:"extra"`
|
||||||
|
Leg OddsSection `json:"leg"`
|
||||||
|
Main OddsSection `json:"main"`
|
||||||
|
Others []OddsSection `json:"others"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FutsalOddsResponse struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
FI string `json:"FI"`
|
||||||
|
Main OddsSection `json:"main"`
|
||||||
|
Score OddsSection `json:"score"`
|
||||||
|
Others []OddsSection `json:"others"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AmericanFootballOddsResponse struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
FI string `json:"FI"`
|
||||||
|
HalfProps OddsSection `json:"half_props"`
|
||||||
|
Main OddsSection `json:"main"`
|
||||||
|
QuarterProps OddsSection `json:"quarter_props"`
|
||||||
|
Others []OddsSection `json:"others"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RugbyLeagueOddsResponse struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
FI string `json:"FI"`
|
||||||
|
TenMinute OddsSection `json:"10minute"`
|
||||||
|
Half OddsSection `json:"half"`
|
||||||
|
Main OddsSection `json:"main"`
|
||||||
|
Main2 OddsSection `json:"main_2"`
|
||||||
|
Others []OddsSection `json:"others"`
|
||||||
|
Player OddsSection `json:"player"`
|
||||||
|
Score OddsSection `json:"score"`
|
||||||
|
Team OddsSection `json:"team"`
|
||||||
|
}
|
||||||
|
type RugbyUnionOddsResponse struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
FI string `json:"FI"`
|
||||||
|
Half OddsSection `json:"half"`
|
||||||
|
Main OddsSection `json:"main"`
|
||||||
|
Main2 OddsSection `json:"main_2"`
|
||||||
|
Others []OddsSection `json:"others"`
|
||||||
|
Player OddsSection `json:"player"`
|
||||||
|
Score OddsSection `json:"score"`
|
||||||
|
Team OddsSection `json:"team"`
|
||||||
|
}
|
||||||
|
type BaseballOddsResponse struct {
|
||||||
|
EventID string `json:"event_id"`
|
||||||
|
FI string `json:"FI"`
|
||||||
|
Main OddsSection `json:"main"`
|
||||||
|
MainProps OddsSection `json:"main_props"`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -290,3 +290,168 @@ type FutsalResultResponse struct {
|
||||||
ConfirmedAt string `json:"confirmed_at"`
|
ConfirmedAt string `json:"confirmed_at"`
|
||||||
Bet365ID string `json:"bet365_id"`
|
Bet365ID string `json:"bet365_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NFLResultResponse represents the structure for NFL game results
|
||||||
|
type NFLResultResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
SportID string `json:"sport_id"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
TimeStatus string `json:"time_status"`
|
||||||
|
League struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"league"`
|
||||||
|
Home struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ImageID string `json:"image_id"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"home"`
|
||||||
|
Away struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ImageID string `json:"image_id"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"away"`
|
||||||
|
SS string `json:"ss"`
|
||||||
|
Scores struct {
|
||||||
|
FirstQuarter Score `json:"1"`
|
||||||
|
SecondQuarter Score `json:"2"`
|
||||||
|
ThirdQuarter Score `json:"3"`
|
||||||
|
FourthQuarter Score `json:"4"`
|
||||||
|
Overtime Score `json:"5"`
|
||||||
|
TotalScore Score `json:"7"`
|
||||||
|
} `json:"scores"`
|
||||||
|
Stats struct {
|
||||||
|
FirstDowns []string `json:"first_downs"`
|
||||||
|
TotalYards []string `json:"total_yards"`
|
||||||
|
PassingYards []string `json:"passing_yards"`
|
||||||
|
RushingYards []string `json:"rushing_yards"`
|
||||||
|
Turnovers []string `json:"turnovers"`
|
||||||
|
TimeOfPossession []string `json:"time_of_possession"`
|
||||||
|
ThirdDownEfficiency []string `json:"third_down_efficiency"`
|
||||||
|
FourthDownEfficiency []string `json:"fourth_down_efficiency"`
|
||||||
|
} `json:"stats"`
|
||||||
|
Extra struct {
|
||||||
|
HomePos string `json:"home_pos"`
|
||||||
|
AwayPos string `json:"away_pos"`
|
||||||
|
StadiumData map[string]string `json:"stadium_data"`
|
||||||
|
Round string `json:"round"`
|
||||||
|
} `json:"extra"`
|
||||||
|
Events []map[string]string `json:"events"`
|
||||||
|
HasLineup int `json:"has_lineup"`
|
||||||
|
ConfirmedAt string `json:"confirmed_at"`
|
||||||
|
Bet365ID string `json:"bet365_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RugbyResultResponse represents the structure for Rugby game results
|
||||||
|
type RugbyResultResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
SportID string `json:"sport_id"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
TimeStatus string `json:"time_status"`
|
||||||
|
League struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"league"`
|
||||||
|
Home struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ImageID string `json:"image_id"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"home"`
|
||||||
|
Away struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ImageID string `json:"image_id"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"away"`
|
||||||
|
SS string `json:"ss"`
|
||||||
|
Scores struct {
|
||||||
|
FirstHalf Score `json:"1"`
|
||||||
|
SecondHalf Score `json:"2"`
|
||||||
|
TotalScore Score `json:"7"`
|
||||||
|
} `json:"scores"`
|
||||||
|
Stats struct {
|
||||||
|
Tries []string `json:"tries"`
|
||||||
|
Conversions []string `json:"conversions"`
|
||||||
|
Penalties []string `json:"penalties"`
|
||||||
|
DropGoals []string `json:"drop_goals"`
|
||||||
|
Possession []string `json:"possession"`
|
||||||
|
Territory []string `json:"territory"`
|
||||||
|
Lineouts []string `json:"lineouts"`
|
||||||
|
Scrums []string `json:"scrums"`
|
||||||
|
PenaltiesConceded []string `json:"penalties_conceded"`
|
||||||
|
} `json:"stats"`
|
||||||
|
Extra struct {
|
||||||
|
HomePos string `json:"home_pos"`
|
||||||
|
AwayPos string `json:"away_pos"`
|
||||||
|
StadiumData map[string]string `json:"stadium_data"`
|
||||||
|
Round string `json:"round"`
|
||||||
|
} `json:"extra"`
|
||||||
|
Events []map[string]string `json:"events"`
|
||||||
|
HasLineup int `json:"has_lineup"`
|
||||||
|
ConfirmedAt string `json:"confirmed_at"`
|
||||||
|
Bet365ID string `json:"bet365_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// BaseballResultResponse represents the structure for Baseball game results
|
||||||
|
type BaseballResultResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
SportID string `json:"sport_id"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
TimeStatus string `json:"time_status"`
|
||||||
|
League struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"league"`
|
||||||
|
Home struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ImageID string `json:"image_id"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"home"`
|
||||||
|
Away struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ImageID string `json:"image_id"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"away"`
|
||||||
|
SS string `json:"ss"`
|
||||||
|
Scores struct {
|
||||||
|
FirstInning Score `json:"1"`
|
||||||
|
SecondInning Score `json:"2"`
|
||||||
|
ThirdInning Score `json:"3"`
|
||||||
|
FourthInning Score `json:"4"`
|
||||||
|
FifthInning Score `json:"5"`
|
||||||
|
SixthInning Score `json:"6"`
|
||||||
|
SeventhInning Score `json:"7"`
|
||||||
|
EighthInning Score `json:"8"`
|
||||||
|
NinthInning Score `json:"9"`
|
||||||
|
ExtraInnings Score `json:"10"`
|
||||||
|
TotalScore Score `json:"11"`
|
||||||
|
} `json:"scores"`
|
||||||
|
Stats struct {
|
||||||
|
Hits []string `json:"hits"`
|
||||||
|
Errors []string `json:"errors"`
|
||||||
|
LeftOnBase []string `json:"left_on_base"`
|
||||||
|
Strikeouts []string `json:"strikeouts"`
|
||||||
|
Walks []string `json:"walks"`
|
||||||
|
HomeRuns []string `json:"home_runs"`
|
||||||
|
TotalBases []string `json:"total_bases"`
|
||||||
|
BattingAverage []string `json:"batting_average"`
|
||||||
|
} `json:"stats"`
|
||||||
|
Extra struct {
|
||||||
|
HomePos string `json:"home_pos"`
|
||||||
|
AwayPos string `json:"away_pos"`
|
||||||
|
StadiumData map[string]string `json:"stadium_data"`
|
||||||
|
Round string `json:"round"`
|
||||||
|
} `json:"extra"`
|
||||||
|
Events []map[string]string `json:"events"`
|
||||||
|
HasLineup int `json:"has_lineup"`
|
||||||
|
ConfirmedAt string `json:"confirmed_at"`
|
||||||
|
Bet365ID string `json:"bet365_id"`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -171,32 +171,28 @@ type AmericanFootballMarket int64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Main
|
// Main
|
||||||
AMERICAN_FOOTBALL_MONEY_LINE AmericanFootballMarket = 170001
|
AMERICAN_FOOTBALL_GAME_LINES AmericanFootballMarket = 1441
|
||||||
AMERICAN_FOOTBALL_SPREAD AmericanFootballMarket = 170002
|
|
||||||
AMERICAN_FOOTBALL_TOTAL_POINTS AmericanFootballMarket = 170003
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type RugbyMarket int64
|
type RugbyLeagueMarket int64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Main
|
// Main
|
||||||
RUGBY_MONEY_LINE RugbyMarket = 180001
|
RUGBY_L_GAME_BETTING_2_WAY RugbyLeagueMarket = 190006
|
||||||
RUGBY_SPREAD RugbyMarket = 180002
|
)
|
||||||
RUGBY_TOTAL_POINTS RugbyMarket = 180003
|
|
||||||
RUGBY_HANDICAP RugbyMarket = 180004
|
type RugbyUnionMarket int64
|
||||||
RUGBY_FIRST_HALF RugbyMarket = 180005
|
|
||||||
RUGBY_SECOND_HALF RugbyMarket = 180006
|
const (
|
||||||
|
// Main
|
||||||
|
RUGBY_U_GAME_BETTING_2_WAY RugbyLeagueMarket = 80007
|
||||||
)
|
)
|
||||||
|
|
||||||
type BaseballMarket int64
|
type BaseballMarket int64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Main
|
// Main
|
||||||
BASEBALL_MONEY_LINE BaseballMarket = 190001
|
BASEBALL_GAME_LINES BaseballMarket = 1096
|
||||||
BASEBALL_SPREAD BaseballMarket = 190002
|
|
||||||
BASEBALL_TOTAL_RUNS BaseballMarket = 190003
|
|
||||||
BASEBALL_FIRST_INNING BaseballMarket = 190004
|
|
||||||
BASEBALL_FIRST_5_INNINGS BaseballMarket = 190005
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Move this into the database so that it can be modified dynamically
|
// TODO: Move this into the database so that it can be modified dynamically
|
||||||
|
|
@ -229,7 +225,7 @@ var SupportedMarkets = map[int64]bool{
|
||||||
int64(BASKETBALL_RESULT_AND_BOTH_TEAMS_TO_SCORE_X_POINTS): true,
|
int64(BASKETBALL_RESULT_AND_BOTH_TEAMS_TO_SCORE_X_POINTS): true,
|
||||||
int64(BASKETBALL_DOUBLE_RESULT): true,
|
int64(BASKETBALL_DOUBLE_RESULT): true,
|
||||||
int64(BASKETBALL_MATCH_RESULT_AND_TOTAL): true,
|
int64(BASKETBALL_MATCH_RESULT_AND_TOTAL): true,
|
||||||
int64(BASKETBALL_MATCH_HANDICAP_AND_TOTAL): false,
|
int64(BASKETBALL_MATCH_HANDICAP_AND_TOTAL): true,
|
||||||
int64(BASKETBALL_GAME_TOTAL_ODD_EVEN): true,
|
int64(BASKETBALL_GAME_TOTAL_ODD_EVEN): true,
|
||||||
int64(BASKETBALL_TEAM_TOTALS): true,
|
int64(BASKETBALL_TEAM_TOTALS): true,
|
||||||
int64(BASKETBALL_TEAM_TOTAL_ODD_EVEN): true,
|
int64(BASKETBALL_TEAM_TOTAL_ODD_EVEN): true,
|
||||||
|
|
@ -250,7 +246,7 @@ var SupportedMarkets = map[int64]bool{
|
||||||
int64(BASKETBALL_FIRST_HALF_TEAM_TO_SCORE_X_POINTS): false,
|
int64(BASKETBALL_FIRST_HALF_TEAM_TO_SCORE_X_POINTS): false,
|
||||||
|
|
||||||
int64(BASKETBALL_FIRST_QUARTER): true,
|
int64(BASKETBALL_FIRST_QUARTER): true,
|
||||||
int64(BASKETBALL_FIRST_QUARTER_HANDICAP_AND_TOTAL): false,
|
int64(BASKETBALL_FIRST_QUARTER_HANDICAP_AND_TOTAL): true,
|
||||||
int64(BASKETBALL_FIRST_QUARTER_DOUBLE_CHANCE): true,
|
int64(BASKETBALL_FIRST_QUARTER_DOUBLE_CHANCE): true,
|
||||||
int64(BASKETBALL_FIRST_QUARTER_TEAM_TOTALS): true,
|
int64(BASKETBALL_FIRST_QUARTER_TEAM_TOTALS): true,
|
||||||
int64(BASKETBALL_FIRST_QUARTER_WINNING_MARGIN): false,
|
int64(BASKETBALL_FIRST_QUARTER_WINNING_MARGIN): false,
|
||||||
|
|
@ -259,7 +255,7 @@ var SupportedMarkets = map[int64]bool{
|
||||||
int64(BASKETBALL_TEAM_WITH_HIGHEST_SCORING_QUARTER): true,
|
int64(BASKETBALL_TEAM_WITH_HIGHEST_SCORING_QUARTER): true,
|
||||||
int64(BASKETBALL_QUARTER_CORRECT_SCORE): false,
|
int64(BASKETBALL_QUARTER_CORRECT_SCORE): false,
|
||||||
int64(BASKETBALL_FIRST_QUARTER_3_WAY_LINES): false,
|
int64(BASKETBALL_FIRST_QUARTER_3_WAY_LINES): false,
|
||||||
int64(BASKETBALL_FIRST_QUARTER_RESULT_AND_TOTAL): false,
|
int64(BASKETBALL_FIRST_QUARTER_RESULT_AND_TOTAL): true,
|
||||||
int64(BASKETBALL_FIRST_QUARTER_RACE_TO_POINTS): false,
|
int64(BASKETBALL_FIRST_QUARTER_RACE_TO_POINTS): false,
|
||||||
int64(BASKETBALL_FIRST_QUARTER_BOTH_TEAMS_TO_SCORE_X_POINTS): false,
|
int64(BASKETBALL_FIRST_QUARTER_BOTH_TEAMS_TO_SCORE_X_POINTS): false,
|
||||||
int64(BASKETBALL_FIRST_QUARTER_TEAM_TO_SCORE_X_POINTS): false,
|
int64(BASKETBALL_FIRST_QUARTER_TEAM_TO_SCORE_X_POINTS): false,
|
||||||
|
|
@ -325,22 +321,14 @@ var SupportedMarkets = map[int64]bool{
|
||||||
int64(FUTSAL_RACE_TO_GOALS): false,
|
int64(FUTSAL_RACE_TO_GOALS): false,
|
||||||
|
|
||||||
// American Football Markets
|
// American Football Markets
|
||||||
int64(AMERICAN_FOOTBALL_MONEY_LINE): true,
|
int64(AMERICAN_FOOTBALL_GAME_LINES): true,
|
||||||
int64(AMERICAN_FOOTBALL_SPREAD): true,
|
|
||||||
int64(AMERICAN_FOOTBALL_TOTAL_POINTS): true,
|
|
||||||
|
|
||||||
// Rugby Markets
|
// Rugby League Markets
|
||||||
int64(RUGBY_MONEY_LINE): true,
|
int64(RUGBY_L_GAME_BETTING_2_WAY): true,
|
||||||
int64(RUGBY_SPREAD): true,
|
|
||||||
int64(RUGBY_TOTAL_POINTS): true,
|
// Ruby Union Markets
|
||||||
int64(RUGBY_HANDICAP): true,
|
int64(RUGBY_U_GAME_BETTING_2_WAY): true,
|
||||||
int64(RUGBY_FIRST_HALF): true,
|
|
||||||
int64(RUGBY_SECOND_HALF): true,
|
|
||||||
|
|
||||||
// Baseball Markets
|
// Baseball Markets
|
||||||
int64(BASEBALL_MONEY_LINE): true,
|
int64(BASEBALL_GAME_LINES): true,
|
||||||
int64(BASEBALL_SPREAD): true,
|
|
||||||
int64(BASEBALL_TOTAL_RUNS): true,
|
|
||||||
int64(BASEBALL_FIRST_INNING): true,
|
|
||||||
int64(BASEBALL_FIRST_5_INNINGS): true,
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,290 +1,125 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
import (
|
// import (
|
||||||
"encoding/json"
|
// "encoding/json"
|
||||||
"strconv"
|
// "strconv"
|
||||||
"strings"
|
// "strings"
|
||||||
)
|
// )
|
||||||
|
|
||||||
// NFLResultResponse represents the structure for NFL game results
|
// // ParseNFLResult parses NFL result from raw JSON data
|
||||||
type NFLResultResponse struct {
|
// func ParseNFLResult(data json.RawMessage) (*NFLResultResponse, error) {
|
||||||
ID string `json:"id"`
|
// var result NFLResultResponse
|
||||||
SportID string `json:"sport_id"`
|
// if err := json.Unmarshal(data, &result); err != nil {
|
||||||
Time string `json:"time"`
|
// return nil, err
|
||||||
TimeStatus string `json:"time_status"`
|
// }
|
||||||
League struct {
|
// return &result, nil
|
||||||
ID string `json:"id"`
|
// }
|
||||||
Name string `json:"name"`
|
|
||||||
CC string `json:"cc"`
|
|
||||||
} `json:"league"`
|
|
||||||
Home struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
ImageID string `json:"image_id"`
|
|
||||||
CC string `json:"cc"`
|
|
||||||
} `json:"home"`
|
|
||||||
Away struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
ImageID string `json:"image_id"`
|
|
||||||
CC string `json:"cc"`
|
|
||||||
} `json:"away"`
|
|
||||||
SS string `json:"ss"`
|
|
||||||
Scores struct {
|
|
||||||
FirstQuarter Score `json:"1"`
|
|
||||||
SecondQuarter Score `json:"2"`
|
|
||||||
ThirdQuarter Score `json:"3"`
|
|
||||||
FourthQuarter Score `json:"4"`
|
|
||||||
Overtime Score `json:"5"`
|
|
||||||
TotalScore Score `json:"7"`
|
|
||||||
} `json:"scores"`
|
|
||||||
Stats struct {
|
|
||||||
FirstDowns []string `json:"first_downs"`
|
|
||||||
TotalYards []string `json:"total_yards"`
|
|
||||||
PassingYards []string `json:"passing_yards"`
|
|
||||||
RushingYards []string `json:"rushing_yards"`
|
|
||||||
Turnovers []string `json:"turnovers"`
|
|
||||||
TimeOfPossession []string `json:"time_of_possession"`
|
|
||||||
ThirdDownEfficiency []string `json:"third_down_efficiency"`
|
|
||||||
FourthDownEfficiency []string `json:"fourth_down_efficiency"`
|
|
||||||
} `json:"stats"`
|
|
||||||
Extra struct {
|
|
||||||
HomePos string `json:"home_pos"`
|
|
||||||
AwayPos string `json:"away_pos"`
|
|
||||||
StadiumData map[string]string `json:"stadium_data"`
|
|
||||||
Round string `json:"round"`
|
|
||||||
} `json:"extra"`
|
|
||||||
Events []map[string]string `json:"events"`
|
|
||||||
HasLineup int `json:"has_lineup"`
|
|
||||||
ConfirmedAt string `json:"confirmed_at"`
|
|
||||||
Bet365ID string `json:"bet365_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// RugbyResultResponse represents the structure for Rugby game results
|
// // ParseRugbyResult parses Rugby result from raw JSON data
|
||||||
type RugbyResultResponse struct {
|
// func ParseRugbyResult(data json.RawMessage) (*RugbyResultResponse, error) {
|
||||||
ID string `json:"id"`
|
// var result RugbyResultResponse
|
||||||
SportID string `json:"sport_id"`
|
// if err := json.Unmarshal(data, &result); err != nil {
|
||||||
Time string `json:"time"`
|
// return nil, err
|
||||||
TimeStatus string `json:"time_status"`
|
// }
|
||||||
League struct {
|
// return &result, nil
|
||||||
ID string `json:"id"`
|
// }
|
||||||
Name string `json:"name"`
|
|
||||||
CC string `json:"cc"`
|
|
||||||
} `json:"league"`
|
|
||||||
Home struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
ImageID string `json:"image_id"`
|
|
||||||
CC string `json:"cc"`
|
|
||||||
} `json:"home"`
|
|
||||||
Away struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
ImageID string `json:"image_id"`
|
|
||||||
CC string `json:"cc"`
|
|
||||||
} `json:"away"`
|
|
||||||
SS string `json:"ss"`
|
|
||||||
Scores struct {
|
|
||||||
FirstHalf Score `json:"1"`
|
|
||||||
SecondHalf Score `json:"2"`
|
|
||||||
TotalScore Score `json:"7"`
|
|
||||||
} `json:"scores"`
|
|
||||||
Stats struct {
|
|
||||||
Tries []string `json:"tries"`
|
|
||||||
Conversions []string `json:"conversions"`
|
|
||||||
Penalties []string `json:"penalties"`
|
|
||||||
DropGoals []string `json:"drop_goals"`
|
|
||||||
Possession []string `json:"possession"`
|
|
||||||
Territory []string `json:"territory"`
|
|
||||||
Lineouts []string `json:"lineouts"`
|
|
||||||
Scrums []string `json:"scrums"`
|
|
||||||
PenaltiesConceded []string `json:"penalties_conceded"`
|
|
||||||
} `json:"stats"`
|
|
||||||
Extra struct {
|
|
||||||
HomePos string `json:"home_pos"`
|
|
||||||
AwayPos string `json:"away_pos"`
|
|
||||||
StadiumData map[string]string `json:"stadium_data"`
|
|
||||||
Round string `json:"round"`
|
|
||||||
} `json:"extra"`
|
|
||||||
Events []map[string]string `json:"events"`
|
|
||||||
HasLineup int `json:"has_lineup"`
|
|
||||||
ConfirmedAt string `json:"confirmed_at"`
|
|
||||||
Bet365ID string `json:"bet365_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// BaseballResultResponse represents the structure for Baseball game results
|
// // ParseRugbyUnionResult parses Rugby Union result from raw JSON data
|
||||||
type BaseballResultResponse struct {
|
// func ParseRugbyUnionResult(data json.RawMessage) (*RugbyResultResponse, error) {
|
||||||
ID string `json:"id"`
|
// return ParseRugbyResult(data)
|
||||||
SportID string `json:"sport_id"`
|
// }
|
||||||
Time string `json:"time"`
|
|
||||||
TimeStatus string `json:"time_status"`
|
|
||||||
League struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
CC string `json:"cc"`
|
|
||||||
} `json:"league"`
|
|
||||||
Home struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
ImageID string `json:"image_id"`
|
|
||||||
CC string `json:"cc"`
|
|
||||||
} `json:"home"`
|
|
||||||
Away struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
ImageID string `json:"image_id"`
|
|
||||||
CC string `json:"cc"`
|
|
||||||
} `json:"away"`
|
|
||||||
SS string `json:"ss"`
|
|
||||||
Scores struct {
|
|
||||||
FirstInning Score `json:"1"`
|
|
||||||
SecondInning Score `json:"2"`
|
|
||||||
ThirdInning Score `json:"3"`
|
|
||||||
FourthInning Score `json:"4"`
|
|
||||||
FifthInning Score `json:"5"`
|
|
||||||
SixthInning Score `json:"6"`
|
|
||||||
SeventhInning Score `json:"7"`
|
|
||||||
EighthInning Score `json:"8"`
|
|
||||||
NinthInning Score `json:"9"`
|
|
||||||
ExtraInnings Score `json:"10"`
|
|
||||||
TotalScore Score `json:"11"`
|
|
||||||
} `json:"scores"`
|
|
||||||
Stats struct {
|
|
||||||
Hits []string `json:"hits"`
|
|
||||||
Errors []string `json:"errors"`
|
|
||||||
LeftOnBase []string `json:"left_on_base"`
|
|
||||||
Strikeouts []string `json:"strikeouts"`
|
|
||||||
Walks []string `json:"walks"`
|
|
||||||
HomeRuns []string `json:"home_runs"`
|
|
||||||
TotalBases []string `json:"total_bases"`
|
|
||||||
BattingAverage []string `json:"batting_average"`
|
|
||||||
} `json:"stats"`
|
|
||||||
Extra struct {
|
|
||||||
HomePos string `json:"home_pos"`
|
|
||||||
AwayPos string `json:"away_pos"`
|
|
||||||
StadiumData map[string]string `json:"stadium_data"`
|
|
||||||
Round string `json:"round"`
|
|
||||||
} `json:"extra"`
|
|
||||||
Events []map[string]string `json:"events"`
|
|
||||||
HasLineup int `json:"has_lineup"`
|
|
||||||
ConfirmedAt string `json:"confirmed_at"`
|
|
||||||
Bet365ID string `json:"bet365_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseNFLResult parses NFL result from raw JSON data
|
// // ParseRugbyLeagueResult parses Rugby League result from raw JSON data
|
||||||
func ParseNFLResult(data json.RawMessage) (*NFLResultResponse, error) {
|
// func ParseRugbyLeagueResult(data json.RawMessage) (*RugbyResultResponse, error) {
|
||||||
var result NFLResultResponse
|
// return ParseRugbyResult(data)
|
||||||
if err := json.Unmarshal(data, &result); err != nil {
|
// }
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseRugbyResult parses Rugby result from raw JSON data
|
// // ParseBaseballResult parses Baseball result from raw JSON data
|
||||||
func ParseRugbyResult(data json.RawMessage) (*RugbyResultResponse, error) {
|
// func ParseBaseballResult(data json.RawMessage) (*BaseballResultResponse, error) {
|
||||||
var result RugbyResultResponse
|
// var result BaseballResultResponse
|
||||||
if err := json.Unmarshal(data, &result); err != nil {
|
// if err := json.Unmarshal(data, &result); err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
return &result, nil
|
// return &result, nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
// ParseRugbyUnionResult parses Rugby Union result from raw JSON data
|
// // GetNFLWinner determines the winner of an NFL game
|
||||||
func ParseRugbyUnionResult(data json.RawMessage) (*RugbyResultResponse, error) {
|
// func GetNFLWinner(result *NFLResultResponse) (string, error) {
|
||||||
return ParseRugbyResult(data)
|
// homeScore, err := strconv.Atoi(result.Scores.TotalScore.Home)
|
||||||
}
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
// awayScore, err := strconv.Atoi(result.Scores.TotalScore.Away)
|
||||||
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
|
||||||
// ParseRugbyLeagueResult parses Rugby League result from raw JSON data
|
// if homeScore > awayScore {
|
||||||
func ParseRugbyLeagueResult(data json.RawMessage) (*RugbyResultResponse, error) {
|
// return result.Home.Name, nil
|
||||||
return ParseRugbyResult(data)
|
// } else if awayScore > homeScore {
|
||||||
}
|
// return result.Away.Name, nil
|
||||||
|
// }
|
||||||
|
// return "Draw", nil
|
||||||
|
// }
|
||||||
|
|
||||||
// ParseBaseballResult parses Baseball result from raw JSON data
|
// // GetRugbyWinner determines the winner of a Rugby game
|
||||||
func ParseBaseballResult(data json.RawMessage) (*BaseballResultResponse, error) {
|
// func GetRugbyWinner(result *RugbyResultResponse) (string, error) {
|
||||||
var result BaseballResultResponse
|
// homeScore, err := strconv.Atoi(result.Scores.TotalScore.Home)
|
||||||
if err := json.Unmarshal(data, &result); err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return "", err
|
||||||
}
|
// }
|
||||||
return &result, nil
|
// awayScore, err := strconv.Atoi(result.Scores.TotalScore.Away)
|
||||||
}
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
|
||||||
// GetNFLWinner determines the winner of an NFL game
|
// if homeScore > awayScore {
|
||||||
func GetNFLWinner(result *NFLResultResponse) (string, error) {
|
// return result.Home.Name, nil
|
||||||
homeScore, err := strconv.Atoi(result.Scores.TotalScore.Home)
|
// } else if awayScore > homeScore {
|
||||||
if err != nil {
|
// return result.Away.Name, nil
|
||||||
return "", err
|
// }
|
||||||
}
|
// return "Draw", nil
|
||||||
awayScore, err := strconv.Atoi(result.Scores.TotalScore.Away)
|
// }
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if homeScore > awayScore {
|
// // GetBaseballWinner determines the winner of a Baseball game
|
||||||
return result.Home.Name, nil
|
// func GetBaseballWinner(result *BaseballResultResponse) (string, error) {
|
||||||
} else if awayScore > homeScore {
|
// homeScore, err := strconv.Atoi(result.Scores.TotalScore.Home)
|
||||||
return result.Away.Name, nil
|
// if err != nil {
|
||||||
}
|
// return "", err
|
||||||
return "Draw", nil
|
// }
|
||||||
}
|
// awayScore, err := strconv.Atoi(result.Scores.TotalScore.Away)
|
||||||
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
|
||||||
// GetRugbyWinner determines the winner of a Rugby game
|
// if homeScore > awayScore {
|
||||||
func GetRugbyWinner(result *RugbyResultResponse) (string, error) {
|
// return result.Home.Name, nil
|
||||||
homeScore, err := strconv.Atoi(result.Scores.TotalScore.Home)
|
// } else if awayScore > homeScore {
|
||||||
if err != nil {
|
// return result.Away.Name, nil
|
||||||
return "", err
|
// }
|
||||||
}
|
// return "Draw", nil
|
||||||
awayScore, err := strconv.Atoi(result.Scores.TotalScore.Away)
|
// }
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if homeScore > awayScore {
|
// // FormatNFLScore formats the NFL score in a readable format
|
||||||
return result.Home.Name, nil
|
// func FormatNFLScore(result *NFLResultResponse) string {
|
||||||
} else if awayScore > homeScore {
|
// return strings.Join([]string{
|
||||||
return result.Away.Name, nil
|
// result.Home.Name + " " + result.Scores.TotalScore.Home,
|
||||||
}
|
// result.Away.Name + " " + result.Scores.TotalScore.Away,
|
||||||
return "Draw", nil
|
// }, " - ")
|
||||||
}
|
// }
|
||||||
|
|
||||||
// GetBaseballWinner determines the winner of a Baseball game
|
// // FormatRugbyScore formats the Rugby score in a readable format
|
||||||
func GetBaseballWinner(result *BaseballResultResponse) (string, error) {
|
// func FormatRugbyScore(result *RugbyResultResponse) string {
|
||||||
homeScore, err := strconv.Atoi(result.Scores.TotalScore.Home)
|
// return strings.Join([]string{
|
||||||
if err != nil {
|
// result.Home.Name + " " + result.Scores.TotalScore.Home,
|
||||||
return "", err
|
// result.Away.Name + " " + result.Scores.TotalScore.Away,
|
||||||
}
|
// }, " - ")
|
||||||
awayScore, err := strconv.Atoi(result.Scores.TotalScore.Away)
|
// }
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if homeScore > awayScore {
|
// // FormatBaseballScore formats the Baseball score in a readable format
|
||||||
return result.Home.Name, nil
|
// func FormatBaseballScore(result *BaseballResultResponse) string {
|
||||||
} else if awayScore > homeScore {
|
// return strings.Join([]string{
|
||||||
return result.Away.Name, nil
|
// result.Home.Name + " " + result.Scores.TotalScore.Home,
|
||||||
}
|
// result.Away.Name + " " + result.Scores.TotalScore.Away,
|
||||||
return "Draw", nil
|
// }, " - ")
|
||||||
}
|
// }
|
||||||
|
|
||||||
// FormatNFLScore formats the NFL score in a readable format
|
|
||||||
func FormatNFLScore(result *NFLResultResponse) string {
|
|
||||||
return strings.Join([]string{
|
|
||||||
result.Home.Name + " " + result.Scores.TotalScore.Home,
|
|
||||||
result.Away.Name + " " + result.Scores.TotalScore.Away,
|
|
||||||
}, " - ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// FormatRugbyScore formats the Rugby score in a readable format
|
|
||||||
func FormatRugbyScore(result *RugbyResultResponse) string {
|
|
||||||
return strings.Join([]string{
|
|
||||||
result.Home.Name + " " + result.Scores.TotalScore.Home,
|
|
||||||
result.Away.Name + " " + result.Scores.TotalScore.Away,
|
|
||||||
}, " - ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// FormatBaseballScore formats the Baseball score in a readable format
|
|
||||||
func FormatBaseballScore(result *BaseballResultResponse) string {
|
|
||||||
return strings.Join([]string{
|
|
||||||
result.Home.Name + " " + result.Scores.TotalScore.Home,
|
|
||||||
result.Away.Name + " " + result.Scores.TotalScore.Away,
|
|
||||||
}, " - ")
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"slices"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -189,8 +188,8 @@ func (s *service) FetchUpcomingEvents(ctx context.Context) error {
|
||||||
source string
|
source string
|
||||||
}{
|
}{
|
||||||
{"https://api.b365api.com/v1/bet365/upcoming?sport_id=%d&token=%s&page=%d", "bet365"},
|
{"https://api.b365api.com/v1/bet365/upcoming?sport_id=%d&token=%s&page=%d", "bet365"},
|
||||||
{"https://api.b365api.com/v1/betfair/sb/upcoming?sport_id=%d&token=%s&page=%d", "betfair"},
|
// {"https://api.b365api.com/v1/betfair/sb/upcoming?sport_id=%d&token=%s&page=%d", "betfair"},
|
||||||
{"https://api.b365api.com/v1/1xbet/upcoming?sport_id=%d&token=%s&page=%d", "1xbet"},
|
// {"https://api.b365api.com/v1/1xbet/upcoming?sport_id=%d&token=%s&page=%d", "1xbet"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, url := range urls {
|
for _, url := range urls {
|
||||||
|
|
@ -207,16 +206,23 @@ func (s *service) FetchUpcomingEvents(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, url, source string) {
|
func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, url, source string) {
|
||||||
sportIDs := []int{1, 18, 17}
|
sportIDs := []int{1, 18, 17, 3, 83, 15, 12, 19, 8, 16, 91}
|
||||||
|
// TODO: Add the league skipping again when we have dynamic leagues
|
||||||
|
// b, err := os.OpenFile("logs/skipped_leagues.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Printf("❌ Failed to open leagues file %v", err)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
for _, sportID := range sportIDs {
|
||||||
var totalPages int = 1
|
var totalPages int = 1
|
||||||
var page int = 0
|
var page int = 0
|
||||||
var limit int = 100
|
var limit int = 100
|
||||||
var count int = 0
|
var count int = 0
|
||||||
for _, sportID := range sportIDs {
|
log.Printf("Sport ID %d", sportID)
|
||||||
for page <= totalPages {
|
for page <= totalPages {
|
||||||
page = page + 1
|
page = page + 1
|
||||||
url := fmt.Sprintf("https://api.b365api.com/v1/bet365/upcoming?sport_id=%d&token=%s&page=%d", sportID, s.token, page)
|
url := fmt.Sprintf("https://api.b365api.com/v1/bet365/upcoming?sport_id=%d&token=%s&page=%d", sportID, s.token, page)
|
||||||
log.Printf("📡 Fetching data for event data page %d", page)
|
log.Printf("📡 Fetching data for sport %d at page %d", sportID, page)
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("❌ Failed to fetch event data for page %d: %v", page, err)
|
log.Printf("❌ Failed to fetch event data for page %d: %v", page, err)
|
||||||
|
|
@ -240,17 +246,21 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, url, sour
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
|
|
||||||
leagueID, err := strconv.ParseInt(ev.League.ID, 10, 64)
|
// leagueID, err := strconv.ParseInt(ev.League.ID, 10, 64)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Printf("❌ Invalid league id, leagueID %v", ev.League.ID)
|
// log.Printf("❌ Invalid league id, leagueID %v", ev.League.ID)
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
|
||||||
if !slices.Contains(domain.SupportedLeagues, leagueID) {
|
// if !slices.Contains(domain.SupportedLeagues, leagueID) {
|
||||||
// fmt.Printf("⚠️ Skipping league %s (%d) as it is not supported\n", ev.League.Name, leagueID)
|
// // fmt.Printf("⚠️ Skipping league %s (%d) as it is not supported\n", ev.League.Name, leagueID)
|
||||||
skippedLeague = append(skippedLeague, ev.League.Name)
|
// _, err = fmt.Fprintf(b, "Skipped league %s (%d) in sport %d\n", ev.League.Name, leagueID, sportID)
|
||||||
continue
|
// if err != nil {
|
||||||
}
|
// fmt.Printf(" Error while logging skipped league")
|
||||||
|
// }
|
||||||
|
// skippedLeague = append(skippedLeague, ev.League.Name)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
event := domain.UpcomingEvent{
|
event := domain.UpcomingEvent{
|
||||||
ID: ev.ID,
|
ID: ev.ID,
|
||||||
|
|
@ -282,7 +292,7 @@ func (s *service) fetchUpcomingEventsFromProvider(ctx context.Context, url, sour
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("⚠️ Skipped leagues %v", len(skippedLeague))
|
log.Printf("⚠️ Skipped leagues %v", len(skippedLeague))
|
||||||
// log.Printf("⚠️ Total pages %v", data.Pager.Total)
|
log.Printf("⚠️ Total pages %v", data.Pager.Total/data.Pager.PerPage)
|
||||||
totalPages = data.Pager.Total / data.Pager.PerPage
|
totalPages = data.Pager.Total / data.Pager.PerPage
|
||||||
|
|
||||||
if count >= limit {
|
if count >= limit {
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,46 @@ func (s *ServiceImpl) FetchNonLiveOdds(ctx context.Context) error {
|
||||||
s.logger.Error("Error while inserting ice hockey odd")
|
s.logger.Error("Error while inserting ice hockey odd")
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
case domain.CRICKET:
|
||||||
|
if err := s.parseCricket(ctx, oddsData.Results[0]); err != nil {
|
||||||
|
s.logger.Error("Error while inserting cricket odd")
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
case domain.VOLLEYBALL:
|
||||||
|
if err := s.parseVolleyball(ctx, oddsData.Results[0]); err != nil {
|
||||||
|
s.logger.Error("Error while inserting volleyball odd")
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
case domain.DARTS:
|
||||||
|
if err := s.parseDarts(ctx, oddsData.Results[0]); err != nil {
|
||||||
|
s.logger.Error("Error while inserting darts odd")
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
case domain.FUTSAL:
|
||||||
|
if err := s.parseFutsal(ctx, oddsData.Results[0]); err != nil {
|
||||||
|
s.logger.Error("Error while inserting futsal odd")
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
case domain.AMERICAN_FOOTBALL:
|
||||||
|
if err := s.parseAmericanFootball(ctx, oddsData.Results[0]); err != nil {
|
||||||
|
s.logger.Error("Error while inserting american football odd")
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
case domain.RUGBY_LEAGUE:
|
||||||
|
if err := s.parseRugbyLeague(ctx, oddsData.Results[0]); err != nil {
|
||||||
|
s.logger.Error("Error while inserting rugby league odd")
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
case domain.RUGBY_UNION:
|
||||||
|
if err := s.parseRugbyUnion(ctx, oddsData.Results[0]); err != nil {
|
||||||
|
s.logger.Error("Error while inserting rugby union odd")
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
case domain.BASEBALL:
|
||||||
|
if err := s.parseBaseball(ctx, oddsData.Results[0]); err != nil {
|
||||||
|
s.logger.Error("Error while inserting baseball odd")
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// result := oddsData.Results[0]
|
// result := oddsData.Results[0]
|
||||||
|
|
@ -223,6 +263,332 @@ func (s *ServiceImpl) parseIceHockey(ctx context.Context, res json.RawMessage) e
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) parseCricket(ctx context.Context, res json.RawMessage) error {
|
||||||
|
var cricketRes domain.CricketOddsResponse
|
||||||
|
if err := json.Unmarshal(res, &cricketRes); err != nil {
|
||||||
|
s.logger.Error("Failed to unmarshal ice hockey result", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if cricketRes.EventID == "" && cricketRes.FI == "" {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
return fmt.Errorf("Skipping result with no valid Event ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
sections := map[string]domain.OddsSection{
|
||||||
|
"1st_over": cricketRes.Main,
|
||||||
|
"innings_1": cricketRes.First_Innings,
|
||||||
|
"main": cricketRes.Main,
|
||||||
|
"match": cricketRes.Match,
|
||||||
|
"player": cricketRes.Player,
|
||||||
|
"team": cricketRes.Team,
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
for oddCategory, section := range sections {
|
||||||
|
if err := s.storeSection(ctx, cricketRes.EventID, cricketRes.FI, oddCategory, section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, section := range cricketRes.Others {
|
||||||
|
if err := s.storeSection(ctx, cricketRes.EventID, cricketRes.FI, "others", section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) parseVolleyball(ctx context.Context, res json.RawMessage) error {
|
||||||
|
var volleyballRes domain.VolleyballOddsResponse
|
||||||
|
if err := json.Unmarshal(res, &volleyballRes); err != nil {
|
||||||
|
s.logger.Error("Failed to unmarshal ice hockey result", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if volleyballRes.EventID == "" && volleyballRes.FI == "" {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
return fmt.Errorf("Skipping result with no valid Event ID")
|
||||||
|
}
|
||||||
|
sections := map[string]domain.OddsSection{
|
||||||
|
"main": volleyballRes.Main,
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
for oddCategory, section := range sections {
|
||||||
|
if err := s.storeSection(ctx, volleyballRes.EventID, volleyballRes.FI, oddCategory, section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, section := range volleyballRes.Others {
|
||||||
|
if err := s.storeSection(ctx, volleyballRes.EventID, volleyballRes.FI, "others", section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) parseDarts(ctx context.Context, res json.RawMessage) error {
|
||||||
|
var dartsRes domain.DartsOddsResponse
|
||||||
|
if err := json.Unmarshal(res, &dartsRes); err != nil {
|
||||||
|
s.logger.Error("Failed to unmarshal ice hockey result", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if dartsRes.EventID == "" && dartsRes.FI == "" {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
return fmt.Errorf("Skipping result with no valid Event ID")
|
||||||
|
}
|
||||||
|
sections := map[string]domain.OddsSection{
|
||||||
|
"180s": dartsRes.OneEightys,
|
||||||
|
"extra": dartsRes.Extra,
|
||||||
|
"leg": dartsRes.Leg,
|
||||||
|
"main": dartsRes.Main,
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
for oddCategory, section := range sections {
|
||||||
|
if err := s.storeSection(ctx, dartsRes.EventID, dartsRes.FI, oddCategory, section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, section := range dartsRes.Others {
|
||||||
|
if err := s.storeSection(ctx, dartsRes.EventID, dartsRes.FI, "others", section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) parseFutsal(ctx context.Context, res json.RawMessage) error {
|
||||||
|
var futsalRes domain.FutsalOddsResponse
|
||||||
|
if err := json.Unmarshal(res, &futsalRes); err != nil {
|
||||||
|
s.logger.Error("Failed to unmarshal ice hockey result", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if futsalRes.EventID == "" && futsalRes.FI == "" {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
return fmt.Errorf("Skipping result with no valid Event ID")
|
||||||
|
}
|
||||||
|
sections := map[string]domain.OddsSection{
|
||||||
|
"main": futsalRes.Main,
|
||||||
|
"score": futsalRes.Score,
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
for oddCategory, section := range sections {
|
||||||
|
if err := s.storeSection(ctx, futsalRes.EventID, futsalRes.FI, oddCategory, section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, section := range futsalRes.Others {
|
||||||
|
if err := s.storeSection(ctx, futsalRes.EventID, futsalRes.FI, "others", section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) parseAmericanFootball(ctx context.Context, res json.RawMessage) error {
|
||||||
|
var americanFootballRes domain.AmericanFootballOddsResponse
|
||||||
|
if err := json.Unmarshal(res, &americanFootballRes); err != nil {
|
||||||
|
s.logger.Error("Failed to unmarshal ice hockey result", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if americanFootballRes.EventID == "" && americanFootballRes.FI == "" {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
return fmt.Errorf("Skipping result with no valid Event ID")
|
||||||
|
}
|
||||||
|
sections := map[string]domain.OddsSection{
|
||||||
|
"half_props": americanFootballRes.HalfProps,
|
||||||
|
"main": americanFootballRes.Main,
|
||||||
|
"quarter_props": americanFootballRes.QuarterProps,
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
for oddCategory, section := range sections {
|
||||||
|
if err := s.storeSection(ctx, americanFootballRes.EventID, americanFootballRes.FI, oddCategory, section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, section := range americanFootballRes.Others {
|
||||||
|
if err := s.storeSection(ctx, americanFootballRes.EventID, americanFootballRes.FI, "others", section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) parseRugbyLeague(ctx context.Context, res json.RawMessage) error {
|
||||||
|
var rugbyLeagueRes domain.RugbyLeagueOddsResponse
|
||||||
|
if err := json.Unmarshal(res, &rugbyLeagueRes); err != nil {
|
||||||
|
s.logger.Error("Failed to unmarshal ice hockey result", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rugbyLeagueRes.EventID == "" && rugbyLeagueRes.FI == "" {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
return fmt.Errorf("Skipping result with no valid Event ID")
|
||||||
|
}
|
||||||
|
sections := map[string]domain.OddsSection{
|
||||||
|
"10minute": rugbyLeagueRes.TenMinute,
|
||||||
|
"main": rugbyLeagueRes.Main,
|
||||||
|
"main_2": rugbyLeagueRes.Main2,
|
||||||
|
"player": rugbyLeagueRes.Player,
|
||||||
|
"Score": rugbyLeagueRes.Score,
|
||||||
|
"Team": rugbyLeagueRes.Team,
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
for oddCategory, section := range sections {
|
||||||
|
if err := s.storeSection(ctx, rugbyLeagueRes.EventID, rugbyLeagueRes.FI, oddCategory, section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, section := range rugbyLeagueRes.Others {
|
||||||
|
if err := s.storeSection(ctx, rugbyLeagueRes.EventID, rugbyLeagueRes.FI, "others", section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) parseRugbyUnion(ctx context.Context, res json.RawMessage) error {
|
||||||
|
var rugbyUnionRes domain.RugbyUnionOddsResponse
|
||||||
|
if err := json.Unmarshal(res, &rugbyUnionRes); err != nil {
|
||||||
|
s.logger.Error("Failed to unmarshal ice hockey result", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rugbyUnionRes.EventID == "" && rugbyUnionRes.FI == "" {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
return fmt.Errorf("Skipping result with no valid Event ID")
|
||||||
|
}
|
||||||
|
sections := map[string]domain.OddsSection{
|
||||||
|
"main": rugbyUnionRes.Main,
|
||||||
|
"main_2": rugbyUnionRes.Main2,
|
||||||
|
"player": rugbyUnionRes.Player,
|
||||||
|
"Score": rugbyUnionRes.Score,
|
||||||
|
"Team": rugbyUnionRes.Team,
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
for oddCategory, section := range sections {
|
||||||
|
if err := s.storeSection(ctx, rugbyUnionRes.EventID, rugbyUnionRes.FI, oddCategory, section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, section := range rugbyUnionRes.Others {
|
||||||
|
if err := s.storeSection(ctx, rugbyUnionRes.EventID, rugbyUnionRes.FI, "others", section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceImpl) parseBaseball(ctx context.Context, res json.RawMessage) error {
|
||||||
|
var baseballRes domain.BaseballOddsResponse
|
||||||
|
if err := json.Unmarshal(res, &baseballRes); err != nil {
|
||||||
|
s.logger.Error("Failed to unmarshal ice hockey result", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if baseballRes.EventID == "" && baseballRes.FI == "" {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
return fmt.Errorf("Skipping result with no valid Event ID")
|
||||||
|
}
|
||||||
|
sections := map[string]domain.OddsSection{
|
||||||
|
"main": baseballRes.Main,
|
||||||
|
"mani_props": baseballRes.MainProps,
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
for oddCategory, section := range sections {
|
||||||
|
if err := s.storeSection(ctx, baseballRes.EventID, baseballRes.FI, oddCategory, section); err != nil {
|
||||||
|
s.logger.Error("Skipping result with no valid Event ID")
|
||||||
|
errs = append(errs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName string, section domain.OddsSection) error {
|
func (s *ServiceImpl) storeSection(ctx context.Context, eventID, fi, sectionName string, section domain.OddsSection) error {
|
||||||
if len(section.Sp) == 0 {
|
if len(section.Sp) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -429,7 +429,7 @@ func evaluateGameLines(outcome domain.BetOutcome, score struct{ Home, Away int }
|
||||||
case "Money Line":
|
case "Money Line":
|
||||||
return evaluateMoneyLine(outcome, score)
|
return evaluateMoneyLine(outcome, score)
|
||||||
|
|
||||||
case "Spread", "Line":
|
case "Spread", "Line", "Run Line":
|
||||||
// Since Spread betting is essentially the same thing
|
// Since Spread betting is essentially the same thing
|
||||||
return evaluateAsianHandicap(outcome, score)
|
return evaluateAsianHandicap(outcome, score)
|
||||||
case "Total":
|
case "Total":
|
||||||
|
|
@ -985,36 +985,6 @@ func evaluateTiedAfterRegulation(outcome domain.BetOutcome, scores []struct{ Hom
|
||||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName)
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func evaluateRugbyOutcome(outcome domain.BetOutcome, result *domain.RugbyResultResponse) (domain.OutcomeStatus, error) {
|
|
||||||
finalScore := parseSS(result.SS)
|
|
||||||
|
|
||||||
switch outcome.MarketName {
|
|
||||||
case "Money Line":
|
|
||||||
return evaluateRugbyMoneyLine(outcome, finalScore)
|
|
||||||
case "Spread":
|
|
||||||
return evaluateRugbySpread(outcome, finalScore)
|
|
||||||
case "Total Points":
|
|
||||||
return evaluateRugbyTotalPoints(outcome, finalScore)
|
|
||||||
default:
|
|
||||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported rugby market: %s", outcome.MarketName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func evaluateBaseballOutcome(outcome domain.BetOutcome, result *domain.BaseballResultResponse) (domain.OutcomeStatus, error) {
|
|
||||||
finalScore := parseSS(result.SS)
|
|
||||||
|
|
||||||
switch outcome.MarketName {
|
|
||||||
case "Money Line":
|
|
||||||
return evaluateBaseballMoneyLine(outcome, finalScore)
|
|
||||||
case "Spread":
|
|
||||||
return evaluateBaseballSpread(outcome, finalScore)
|
|
||||||
case "Total Runs":
|
|
||||||
return evaluateBaseballTotalRuns(outcome, finalScore)
|
|
||||||
default:
|
|
||||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported baseball market: %s", outcome.MarketName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func evaluateVolleyballGamelines(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
func evaluateVolleyballGamelines(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
||||||
switch outcome.OddName {
|
switch outcome.OddName {
|
||||||
case "Total":
|
case "Total":
|
||||||
|
|
@ -1023,3 +993,16 @@ func evaluateVolleyballGamelines(outcome domain.BetOutcome, score struct{ Home,
|
||||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd name: %s", outcome.OddName)
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd name: %s", outcome.OddName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func evaluateGameBettingTwoWay(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
||||||
|
switch outcome.OddName {
|
||||||
|
case "Handicap":
|
||||||
|
return evaluateAsianHandicap(outcome, score)
|
||||||
|
case "Total":
|
||||||
|
return evaluateTotalOverUnder(outcome, score)
|
||||||
|
case "To Win":
|
||||||
|
return evaluateFullTimeResult(outcome, score)
|
||||||
|
default:
|
||||||
|
return domain.OUTCOME_STATUS_ERROR, fmt.Errorf("invalid odd name: %s", outcome.OddName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,71 +161,6 @@ func (s *Service) FetchAndProcessResults(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (s *Service) FetchAndStoreResult(ctx context.Context, eventID string) error {
|
|
||||||
// url := fmt.Sprintf("https://api.b365api.com/v1/bet365/result?token=%s&event_id=%s", s.config.Bet365Token, eventID)
|
|
||||||
|
|
||||||
// res, err := s.client.Get(url)
|
|
||||||
// if err != nil {
|
|
||||||
// s.logger.Error("Failed to fetch result", "event_id", eventID, "error", err)
|
|
||||||
// return fmt.Errorf("failed to fetch result: %w", err)
|
|
||||||
// }
|
|
||||||
// defer res.Body.Close()
|
|
||||||
|
|
||||||
// if res.StatusCode != http.StatusOK {
|
|
||||||
// s.logger.Error("Unexpected status code", "event_id", eventID, "status_code", res.StatusCode)
|
|
||||||
// return fmt.Errorf("unexpected status code: %d", res.StatusCode)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var apiResp domain.BaseResultResponse
|
|
||||||
// if err := json.NewDecoder(res.Body).Decode(&apiResp); err != nil {
|
|
||||||
// s.logger.Error("Failed to decode result", "event_id", eventID, "error", err)
|
|
||||||
// return fmt.Errorf("failed to decode result: %w", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if apiResp.Success != 1 || len(apiResp.Results) == 0 {
|
|
||||||
// s.logger.Error("Invalid API response", "event_id", eventID)
|
|
||||||
// return fmt.Errorf("no result returned from API")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// r := apiResp.Results[0]
|
|
||||||
// if r.TimeStatus != "3" {
|
|
||||||
// s.logger.Warn("Match not yet completed", "event_id", eventID)
|
|
||||||
// return fmt.Errorf("match not yet completed")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// eventIDInt, err := strconv.ParseInt(eventID, 10, 64)
|
|
||||||
// if err != nil {
|
|
||||||
// s.logger.Error("Failed to parse event_id", "event_id", eventID, "error", err)
|
|
||||||
// return fmt.Errorf("failed to parse event_id: %w", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// halfScore := ""
|
|
||||||
// if r.Scores.FirstHalf.Home != "" {
|
|
||||||
// halfScore = fmt.Sprintf("%s-%s", r.Scores.FirstHalf.Home, r.Scores.FirstHalf.Away)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// result := domain.Result{
|
|
||||||
// EventID: eventIDInt,
|
|
||||||
// Status: domain.OUTCOME_STATUS_PENDING,
|
|
||||||
// Score: r.SS,
|
|
||||||
// FullTimeScore: r.SS,
|
|
||||||
// HalfTimeScore: halfScore,
|
|
||||||
// SS: r.SS,
|
|
||||||
// Scores: make(map[string]domain.Score),
|
|
||||||
// }
|
|
||||||
// for k, v := range map[string]domain.Score{
|
|
||||||
// "1": r.Scores.FirstHalf,
|
|
||||||
// "2": r.Scores.SecondHalf,
|
|
||||||
// } {
|
|
||||||
// result.Scores[k] = domain.Score{
|
|
||||||
// Home: v.Home,
|
|
||||||
// Away: v.Away,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return s.repo.InsertResult(ctx, result)
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (s *Service) fetchResult(ctx context.Context, eventID, oddID, marketID, sportID int64, outcome domain.BetOutcome) (domain.CreateResult, error) {
|
func (s *Service) fetchResult(ctx context.Context, eventID, oddID, marketID, sportID int64, outcome domain.BetOutcome) (domain.CreateResult, error) {
|
||||||
// url := fmt.Sprintf("https://api.b365api.com/v1/bet365/result?token=%s&event_id=%d", s.config.Bet365Token, eventID)
|
// url := fmt.Sprintf("https://api.b365api.com/v1/bet365/result?token=%s&event_id=%d", s.config.Bet365Token, eventID)
|
||||||
url := fmt.Sprintf("https://api.b365api.com/v1/event/view?token=%s&event_id=%d", s.config.Bet365Token, eventID)
|
url := fmt.Sprintf("https://api.b365api.com/v1/event/view?token=%s&event_id=%d", s.config.Bet365Token, eventID)
|
||||||
|
|
@ -598,21 +533,7 @@ func (s *Service) parseNFL(resultRes json.RawMessage, eventID, oddID, marketID i
|
||||||
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
||||||
}
|
}
|
||||||
|
|
||||||
finalScore := parseSS(nflResp.SS)
|
status, err := s.evaluateNFLOutcome(outcome, nflResp)
|
||||||
|
|
||||||
var status domain.OutcomeStatus
|
|
||||||
var err error
|
|
||||||
|
|
||||||
switch outcome.MarketName {
|
|
||||||
case "Money Line":
|
|
||||||
status, err = evaluateNFLMoneyLine(outcome, finalScore)
|
|
||||||
case "Spread":
|
|
||||||
status, err = evaluateNFLSpread(outcome, finalScore)
|
|
||||||
case "Total Points":
|
|
||||||
status, err = evaluateNFLTotalPoints(outcome, finalScore)
|
|
||||||
default:
|
|
||||||
return domain.CreateResult{}, fmt.Errorf("unsupported market: %s", outcome.MarketName)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
||||||
|
|
@ -639,7 +560,7 @@ func (s *Service) parseRugbyUnion(resultRes json.RawMessage, eventID, oddID, mar
|
||||||
s.logger.Warn("Match not yet completed", "event_id", eventID)
|
s.logger.Warn("Match not yet completed", "event_id", eventID)
|
||||||
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
||||||
}
|
}
|
||||||
status, err := evaluateRugbyOutcome(outcome, &rugbyResp)
|
status, err := s.evaluateRugbyOutcome(outcome, rugbyResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
||||||
return domain.CreateResult{}, err
|
return domain.CreateResult{}, err
|
||||||
|
|
@ -664,7 +585,7 @@ func (s *Service) parseRugbyLeague(resultRes json.RawMessage, eventID, oddID, ma
|
||||||
s.logger.Warn("Match not yet completed", "event_id", eventID)
|
s.logger.Warn("Match not yet completed", "event_id", eventID)
|
||||||
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
||||||
}
|
}
|
||||||
status, err := evaluateRugbyOutcome(outcome, &rugbyResp)
|
status, err := s.evaluateRugbyOutcome(outcome, rugbyResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
||||||
return domain.CreateResult{}, err
|
return domain.CreateResult{}, err
|
||||||
|
|
@ -689,7 +610,7 @@ func (s *Service) parseBaseball(resultRes json.RawMessage, eventID, oddID, marke
|
||||||
s.logger.Warn("Match not yet completed", "event_id", eventID)
|
s.logger.Warn("Match not yet completed", "event_id", eventID)
|
||||||
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
||||||
}
|
}
|
||||||
status, err := evaluateBaseballOutcome(outcome, &baseballResp)
|
status, err := s.evaluateBaseballOutcome(outcome, baseballResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
||||||
return domain.CreateResult{}, err
|
return domain.CreateResult{}, err
|
||||||
|
|
@ -986,21 +907,51 @@ func (s *Service) evaluateFutsalOutcome(outcome domain.BetOutcome, res domain.Fu
|
||||||
return domain.OUTCOME_STATUS_PENDING, nil
|
return domain.OUTCOME_STATUS_PENDING, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) evaluateNFLOutcome(outcome domain.BetOutcome, finalScore struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
func (s *Service) evaluateNFLOutcome(outcome domain.BetOutcome, res domain.NFLResultResponse) (domain.OutcomeStatus, error) {
|
||||||
if !domain.SupportedMarkets[outcome.MarketID] {
|
if !domain.SupportedMarkets[outcome.MarketID] {
|
||||||
s.logger.Warn("Unsupported market type", "market_name", outcome.MarketName)
|
s.logger.Warn("Unsupported market type", "market_name", outcome.MarketName)
|
||||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported market type: %s", outcome.MarketName)
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported market type: %s", outcome.MarketName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finalScore := parseSS(res.SS)
|
||||||
|
|
||||||
switch outcome.MarketID {
|
switch outcome.MarketID {
|
||||||
case int64(domain.AMERICAN_FOOTBALL_MONEY_LINE):
|
case int64(domain.AMERICAN_FOOTBALL_GAME_LINES):
|
||||||
return evaluateNFLMoneyLine(outcome, finalScore)
|
return evaluateGameLines(outcome, finalScore)
|
||||||
case int64(domain.AMERICAN_FOOTBALL_SPREAD):
|
|
||||||
return evaluateNFLSpread(outcome, finalScore)
|
|
||||||
case int64(domain.AMERICAN_FOOTBALL_TOTAL_POINTS):
|
|
||||||
return evaluateNFLTotalPoints(outcome, finalScore)
|
|
||||||
default:
|
default:
|
||||||
s.logger.Warn("Market type not implemented", "market_name", outcome.MarketName)
|
s.logger.Warn("Market type not implemented", "market_name", outcome.MarketName)
|
||||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("market type not implemented: %s", outcome.MarketName)
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("market type not implemented: %s", outcome.MarketName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) evaluateRugbyOutcome(outcome domain.BetOutcome, result domain.RugbyResultResponse) (domain.OutcomeStatus, error) {
|
||||||
|
if !domain.SupportedMarkets[outcome.MarketID] {
|
||||||
|
s.logger.Warn("Unsupported market type", "market_name", outcome.MarketName)
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported market type: %s", outcome.MarketName)
|
||||||
|
}
|
||||||
|
|
||||||
|
finalScore := parseSS(result.SS)
|
||||||
|
|
||||||
|
switch outcome.MarketID {
|
||||||
|
case int64(domain.RUGBY_L_GAME_BETTING_2_WAY):
|
||||||
|
return evaluateGameBettingTwoWay(outcome, finalScore)
|
||||||
|
default:
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported rugby market: %s", outcome.MarketName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) evaluateBaseballOutcome(outcome domain.BetOutcome, res domain.BaseballResultResponse) (domain.OutcomeStatus, error) {
|
||||||
|
if !domain.SupportedMarkets[outcome.MarketID] {
|
||||||
|
s.logger.Warn("Unsupported market type", "market_name", outcome.MarketName)
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported market type: %s", outcome.MarketName)
|
||||||
|
}
|
||||||
|
|
||||||
|
finalScore := parseSS(res.SS)
|
||||||
|
|
||||||
|
switch outcome.MarketID {
|
||||||
|
case int64(domain.BASEBALL_GAME_LINES):
|
||||||
|
return evaluateGameLines(outcome, finalScore)
|
||||||
|
default:
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported baseball market: %s", outcome.MarketName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,189 +1,189 @@
|
||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
// import (
|
||||||
"encoding/json"
|
// "encoding/json"
|
||||||
"fmt"
|
// "fmt"
|
||||||
"time"
|
// "time"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
)
|
// )
|
||||||
|
|
||||||
// ResultCheckerService handles the checking of game results
|
// // ResultCheckerService handles the checking of game results
|
||||||
type ResultCheckerService struct {
|
// type ResultCheckerService struct {
|
||||||
// Add any dependencies here (e.g., repositories, external APIs)
|
// // Add any dependencies here (e.g., repositories, external APIs)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// NewResultCheckerService creates a new instance of ResultCheckerService
|
// // NewResultCheckerService creates a new instance of ResultCheckerService
|
||||||
func NewResultCheckerService() *ResultCheckerService {
|
// func NewResultCheckerService() *ResultCheckerService {
|
||||||
return &ResultCheckerService{}
|
// return &ResultCheckerService{}
|
||||||
}
|
// }
|
||||||
|
|
||||||
// CheckNFLResult checks the result of an NFL game
|
// // CheckNFLResult checks the result of an NFL game
|
||||||
func (s *ResultCheckerService) CheckNFLResult(data json.RawMessage) (*domain.Result, error) {
|
// func (s *ResultCheckerService) CheckNFLResult(data json.RawMessage) (*domain.Result, error) {
|
||||||
nflResult, err := domain.ParseNFLResult(data)
|
// nflResult, err := domain.ParseNFLResult(data)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse NFL result: %w", err)
|
// return nil, fmt.Errorf("failed to parse NFL result: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
winner, err := domain.GetNFLWinner(nflResult)
|
// winner, err := domain.GetNFLWinner(nflResult)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to determine NFL winner: %w", err)
|
// return nil, fmt.Errorf("failed to determine NFL winner: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
score := domain.FormatNFLScore(nflResult)
|
// score := domain.FormatNFLScore(nflResult)
|
||||||
|
|
||||||
return &domain.Result{
|
// return &domain.Result{
|
||||||
Status: determineOutcomeStatus(winner, nflResult.Home.Name, nflResult.Away.Name),
|
// Status: determineOutcomeStatus(winner, nflResult.Home.Name, nflResult.Away.Name),
|
||||||
Score: score,
|
// Score: score,
|
||||||
FullTimeScore: score,
|
// FullTimeScore: score,
|
||||||
SS: nflResult.SS,
|
// SS: nflResult.SS,
|
||||||
Scores: map[string]domain.Score{
|
// Scores: map[string]domain.Score{
|
||||||
"1": nflResult.Scores.FirstQuarter,
|
// "1": nflResult.Scores.FirstQuarter,
|
||||||
"2": nflResult.Scores.SecondQuarter,
|
// "2": nflResult.Scores.SecondQuarter,
|
||||||
"3": nflResult.Scores.ThirdQuarter,
|
// "3": nflResult.Scores.ThirdQuarter,
|
||||||
"4": nflResult.Scores.FourthQuarter,
|
// "4": nflResult.Scores.FourthQuarter,
|
||||||
"5": nflResult.Scores.Overtime,
|
// "5": nflResult.Scores.Overtime,
|
||||||
"7": nflResult.Scores.TotalScore,
|
// "7": nflResult.Scores.TotalScore,
|
||||||
},
|
// },
|
||||||
CreatedAt: time.Now(),
|
// CreatedAt: time.Now(),
|
||||||
UpdatedAt: time.Now(),
|
// UpdatedAt: time.Now(),
|
||||||
}, nil
|
// }, nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
// determineOutcomeStatus determines the outcome status based on the winner and teams
|
// // determineOutcomeStatus determines the outcome status based on the winner and teams
|
||||||
func determineOutcomeStatus(winner, homeTeam, awayTeam string) domain.OutcomeStatus {
|
// func determineOutcomeStatus(winner, homeTeam, awayTeam string) domain.OutcomeStatus {
|
||||||
if winner == "Draw" {
|
// if winner == "Draw" {
|
||||||
return domain.OUTCOME_STATUS_VOID
|
// return domain.OUTCOME_STATUS_VOID
|
||||||
}
|
// }
|
||||||
if winner == homeTeam {
|
// if winner == homeTeam {
|
||||||
return domain.OUTCOME_STATUS_WIN
|
// return domain.OUTCOME_STATUS_WIN
|
||||||
}
|
// }
|
||||||
if winner == awayTeam {
|
// if winner == awayTeam {
|
||||||
return domain.OUTCOME_STATUS_LOSS
|
// return domain.OUTCOME_STATUS_LOSS
|
||||||
}
|
// }
|
||||||
return domain.OUTCOME_STATUS_PENDING
|
// return domain.OUTCOME_STATUS_PENDING
|
||||||
}
|
// }
|
||||||
|
|
||||||
// CheckRugbyResult checks the result of a Rugby game
|
// // CheckRugbyResult checks the result of a Rugby game
|
||||||
func (s *ResultCheckerService) CheckRugbyResult(data json.RawMessage) (*domain.Result, error) {
|
// func (s *ResultCheckerService) CheckRugbyResult(data json.RawMessage) (*domain.Result, error) {
|
||||||
rugbyResult, err := domain.ParseRugbyResult(data)
|
// rugbyResult, err := domain.ParseRugbyResult(data)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse Rugby result: %w", err)
|
// return nil, fmt.Errorf("failed to parse Rugby result: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
winner, err := domain.GetRugbyWinner(rugbyResult)
|
// winner, err := domain.GetRugbyWinner(rugbyResult)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to determine Rugby winner: %w", err)
|
// return nil, fmt.Errorf("failed to determine Rugby winner: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
score := domain.FormatRugbyScore(rugbyResult)
|
// score := domain.FormatRugbyScore(rugbyResult)
|
||||||
|
|
||||||
return &domain.Result{
|
// return &domain.Result{
|
||||||
Status: determineOutcomeStatus(winner, rugbyResult.Home.Name, rugbyResult.Away.Name),
|
// Status: determineOutcomeStatus(winner, rugbyResult.Home.Name, rugbyResult.Away.Name),
|
||||||
Score: score,
|
// Score: score,
|
||||||
FullTimeScore: score,
|
// FullTimeScore: score,
|
||||||
SS: rugbyResult.SS,
|
// SS: rugbyResult.SS,
|
||||||
Scores: map[string]domain.Score{
|
// Scores: map[string]domain.Score{
|
||||||
"1": rugbyResult.Scores.FirstHalf,
|
// "1": rugbyResult.Scores.FirstHalf,
|
||||||
"2": rugbyResult.Scores.SecondHalf,
|
// "2": rugbyResult.Scores.SecondHalf,
|
||||||
"7": rugbyResult.Scores.TotalScore,
|
// "7": rugbyResult.Scores.TotalScore,
|
||||||
},
|
// },
|
||||||
CreatedAt: time.Now(),
|
// CreatedAt: time.Now(),
|
||||||
UpdatedAt: time.Now(),
|
// UpdatedAt: time.Now(),
|
||||||
}, nil
|
// }, nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
// CheckBaseballResult checks the result of a Baseball game
|
// // CheckBaseballResult checks the result of a Baseball game
|
||||||
func (s *ResultCheckerService) CheckBaseballResult(data json.RawMessage) (*domain.Result, error) {
|
// func (s *ResultCheckerService) CheckBaseballResult(data json.RawMessage) (*domain.Result, error) {
|
||||||
baseballResult, err := domain.ParseBaseballResult(data)
|
// baseballResult, err := domain.ParseBaseballResult(data)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse Baseball result: %w", err)
|
// return nil, fmt.Errorf("failed to parse Baseball result: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
winner, err := domain.GetBaseballWinner(baseballResult)
|
// winner, err := domain.GetBaseballWinner(baseballResult)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to determine Baseball winner: %w", err)
|
// return nil, fmt.Errorf("failed to determine Baseball winner: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
score := domain.FormatBaseballScore(baseballResult)
|
// score := domain.FormatBaseballScore(baseballResult)
|
||||||
|
|
||||||
return &domain.Result{
|
// return &domain.Result{
|
||||||
Status: determineOutcomeStatus(winner, baseballResult.Home.Name, baseballResult.Away.Name),
|
// Status: determineOutcomeStatus(winner, baseballResult.Home.Name, baseballResult.Away.Name),
|
||||||
Score: score,
|
// Score: score,
|
||||||
FullTimeScore: score,
|
// FullTimeScore: score,
|
||||||
SS: baseballResult.SS,
|
// SS: baseballResult.SS,
|
||||||
Scores: map[string]domain.Score{
|
// Scores: map[string]domain.Score{
|
||||||
"1": baseballResult.Scores.FirstInning,
|
// "1": baseballResult.Scores.FirstInning,
|
||||||
"2": baseballResult.Scores.SecondInning,
|
// "2": baseballResult.Scores.SecondInning,
|
||||||
"3": baseballResult.Scores.ThirdInning,
|
// "3": baseballResult.Scores.ThirdInning,
|
||||||
"4": baseballResult.Scores.FourthInning,
|
// "4": baseballResult.Scores.FourthInning,
|
||||||
"5": baseballResult.Scores.FifthInning,
|
// "5": baseballResult.Scores.FifthInning,
|
||||||
"6": baseballResult.Scores.SixthInning,
|
// "6": baseballResult.Scores.SixthInning,
|
||||||
"7": baseballResult.Scores.SeventhInning,
|
// "7": baseballResult.Scores.SeventhInning,
|
||||||
"8": baseballResult.Scores.EighthInning,
|
// "8": baseballResult.Scores.EighthInning,
|
||||||
"9": baseballResult.Scores.NinthInning,
|
// "9": baseballResult.Scores.NinthInning,
|
||||||
"10": baseballResult.Scores.ExtraInnings,
|
// "10": baseballResult.Scores.ExtraInnings,
|
||||||
"T": baseballResult.Scores.TotalScore,
|
// "T": baseballResult.Scores.TotalScore,
|
||||||
},
|
// },
|
||||||
CreatedAt: time.Now(),
|
// CreatedAt: time.Now(),
|
||||||
UpdatedAt: time.Now(),
|
// UpdatedAt: time.Now(),
|
||||||
}, nil
|
// }, nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
// CheckRugbyUnionResult checks the result of a Rugby Union game
|
// // CheckRugbyUnionResult checks the result of a Rugby Union game
|
||||||
func (s *ResultCheckerService) CheckRugbyUnionResult(data json.RawMessage) (*domain.Result, error) {
|
// func (s *ResultCheckerService) CheckRugbyUnionResult(data json.RawMessage) (*domain.Result, error) {
|
||||||
rugbyResult, err := domain.ParseRugbyUnionResult(data)
|
// rugbyResult, err := domain.ParseRugbyUnionResult(data)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse Rugby Union result: %w", err)
|
// return nil, fmt.Errorf("failed to parse Rugby Union result: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
winner, err := domain.GetRugbyWinner(rugbyResult)
|
// winner, err := domain.GetRugbyWinner(rugbyResult)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to determine Rugby Union winner: %w", err)
|
// return nil, fmt.Errorf("failed to determine Rugby Union winner: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
score := domain.FormatRugbyScore(rugbyResult)
|
// score := domain.FormatRugbyScore(rugbyResult)
|
||||||
|
|
||||||
return &domain.Result{
|
// return &domain.Result{
|
||||||
Status: determineOutcomeStatus(winner, rugbyResult.Home.Name, rugbyResult.Away.Name),
|
// Status: determineOutcomeStatus(winner, rugbyResult.Home.Name, rugbyResult.Away.Name),
|
||||||
Score: score,
|
// Score: score,
|
||||||
FullTimeScore: score,
|
// FullTimeScore: score,
|
||||||
SS: rugbyResult.SS,
|
// SS: rugbyResult.SS,
|
||||||
Scores: map[string]domain.Score{
|
// Scores: map[string]domain.Score{
|
||||||
"1": rugbyResult.Scores.FirstHalf,
|
// "1": rugbyResult.Scores.FirstHalf,
|
||||||
"2": rugbyResult.Scores.SecondHalf,
|
// "2": rugbyResult.Scores.SecondHalf,
|
||||||
"7": rugbyResult.Scores.TotalScore,
|
// "7": rugbyResult.Scores.TotalScore,
|
||||||
},
|
// },
|
||||||
CreatedAt: time.Now(),
|
// CreatedAt: time.Now(),
|
||||||
UpdatedAt: time.Now(),
|
// UpdatedAt: time.Now(),
|
||||||
}, nil
|
// }, nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
// CheckRugbyLeagueResult checks the result of a Rugby League game
|
// // CheckRugbyLeagueResult checks the result of a Rugby League game
|
||||||
func (s *ResultCheckerService) CheckRugbyLeagueResult(data json.RawMessage) (*domain.Result, error) {
|
// func (s *ResultCheckerService) CheckRugbyLeagueResult(data json.RawMessage) (*domain.Result, error) {
|
||||||
rugbyResult, err := domain.ParseRugbyLeagueResult(data)
|
// rugbyResult, err := domain.ParseRugbyLeagueResult(data)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse Rugby League result: %w", err)
|
// return nil, fmt.Errorf("failed to parse Rugby League result: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
winner, err := domain.GetRugbyWinner(rugbyResult)
|
// winner, err := domain.GetRugbyWinner(rugbyResult)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to determine Rugby League winner: %w", err)
|
// return nil, fmt.Errorf("failed to determine Rugby League winner: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
score := domain.FormatRugbyScore(rugbyResult)
|
// score := domain.FormatRugbyScore(rugbyResult)
|
||||||
|
|
||||||
return &domain.Result{
|
// return &domain.Result{
|
||||||
Status: determineOutcomeStatus(winner, rugbyResult.Home.Name, rugbyResult.Away.Name),
|
// Status: determineOutcomeStatus(winner, rugbyResult.Home.Name, rugbyResult.Away.Name),
|
||||||
Score: score,
|
// Score: score,
|
||||||
FullTimeScore: score,
|
// FullTimeScore: score,
|
||||||
SS: rugbyResult.SS,
|
// SS: rugbyResult.SS,
|
||||||
Scores: map[string]domain.Score{
|
// Scores: map[string]domain.Score{
|
||||||
"1": rugbyResult.Scores.FirstHalf,
|
// "1": rugbyResult.Scores.FirstHalf,
|
||||||
"2": rugbyResult.Scores.SecondHalf,
|
// "2": rugbyResult.Scores.SecondHalf,
|
||||||
"7": rugbyResult.Scores.TotalScore,
|
// "7": rugbyResult.Scores.TotalScore,
|
||||||
},
|
// },
|
||||||
CreatedAt: time.Now(),
|
// CreatedAt: time.Now(),
|
||||||
UpdatedAt: time.Now(),
|
// UpdatedAt: time.Now(),
|
||||||
}, nil
|
// }, nil
|
||||||
}
|
// }
|
||||||
|
|
|
||||||
|
|
@ -21,22 +21,22 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
|
||||||
spec string
|
spec string
|
||||||
task func()
|
task func()
|
||||||
}{
|
}{
|
||||||
// {
|
{
|
||||||
// spec: "0 0 * * * *", // Every 1 hour
|
spec: "0 0 * * * *", // Every 1 hour
|
||||||
// task: func() {
|
task: func() {
|
||||||
// if err := eventService.FetchUpcomingEvents(context.Background()); err != nil {
|
if err := eventService.FetchUpcomingEvents(context.Background()); err != nil {
|
||||||
// log.Printf("FetchUpcomingEvents error: %v", err)
|
log.Printf("FetchUpcomingEvents error: %v", err)
|
||||||
// }
|
}
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// spec: "0 */15 * * * *", // Every 15 minutes
|
spec: "0 */15 * * * *", // Every 15 minutes
|
||||||
// task: func() {
|
task: func() {
|
||||||
// if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
|
if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
|
||||||
// log.Printf("FetchNonLiveOdds error: %v", err)
|
log.Printf("FetchNonLiveOdds error: %v", err)
|
||||||
// }
|
}
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
spec: "0 */15 * * * *", // Every 15 Minutes
|
spec: "0 */15 * * * *", // Every 15 Minutes
|
||||||
task: func() {
|
task: func() {
|
||||||
|
|
@ -52,7 +52,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, job := range schedule {
|
for _, job := range schedule {
|
||||||
// job.task()
|
job.task()
|
||||||
if _, err := c.AddFunc(job.spec, job.task); err != nil {
|
if _, err := c.AddFunc(job.spec, job.task); err != nil {
|
||||||
log.Fatalf("Failed to schedule cron job: %v", err)
|
log.Fatalf("Failed to schedule cron job: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ func (h *Handler) GetRawOddsByMarketID(c *fiber.Ctx) error {
|
||||||
|
|
||||||
rawOdds, err := h.prematchSvc.GetRawOddsByMarketID(c.Context(), marketID, upcomingID)
|
rawOdds, err := h.prematchSvc.GetRawOddsByMarketID(c.Context(), marketID, upcomingID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.logger.Error("failed to fetch raw odds", "error", err)
|
// h.logger.Error("failed to fetch raw odds", "error", err)
|
||||||
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve raw odds", err, nil)
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve raw odds", err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
3
makefile
3
makefile
|
|
@ -54,11 +54,10 @@ db-up:
|
||||||
|
|
||||||
.PHONY: db-down
|
.PHONY: db-down
|
||||||
db-down:
|
db-down:
|
||||||
@docker volume rm fortunebet-backend_postgres_data
|
|
||||||
@docker compose down
|
@docker compose down
|
||||||
|
@docker volume rm fortunebet-backend_postgres_data
|
||||||
postgres:
|
postgres:
|
||||||
@docker exec -it fortunebet-backend-postgres-1 psql -U root -d gh
|
@docker exec -it fortunebet-backend-postgres-1 psql -U root -d gh
|
||||||
|
|
||||||
.PHONY: sqlc-gen
|
.PHONY: sqlc-gen
|
||||||
sqlc-gen:
|
sqlc-gen:
|
||||||
@sqlc generate
|
@sqlc generate
|
||||||
Loading…
Reference in New Issue
Block a user