cricket support
This commit is contained in:
parent
252bf04b1e
commit
7e1a126ead
|
|
@ -175,6 +175,41 @@ type IceHockeyResultResponse struct {
|
||||||
Bet365ID string `json:"bet365_id"`
|
Bet365ID string `json:"bet365_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CricketResultResponse 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"`
|
||||||
|
Extra struct {
|
||||||
|
HomePos string `json:"home_pos"`
|
||||||
|
AwayPos string `json:"away_pos"`
|
||||||
|
NumberOfPeriods string `json:"numberofperiods"`
|
||||||
|
PeriodLength string `json:"periodlength"`
|
||||||
|
StadiumData map[string]string `json:"stadium_data"`
|
||||||
|
} `json:"extra"`
|
||||||
|
HasLineup int `json:"has_lineup"`
|
||||||
|
ConfirmedAt string `json:"confirmed_at"`
|
||||||
|
Bet365ID string `json:"bet365_id"`
|
||||||
|
}
|
||||||
|
|
||||||
type Score struct {
|
type Score struct {
|
||||||
Home string `json:"home"`
|
Home string `json:"home"`
|
||||||
Away string `json:"away"`
|
Away string `json:"away"`
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,29 @@ const (
|
||||||
ICE_HOCKEY_ALTERNATIVE_TOTAL_TWO_WAY IceHockeyMarket = 170240
|
ICE_HOCKEY_ALTERNATIVE_TOTAL_TWO_WAY IceHockeyMarket = 170240
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CricketMarket int64
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Main
|
||||||
|
CRICKET_TO_WIN_THE_MATCH CricketMarket = 1246
|
||||||
|
CRICKET_TEAM_TOP_BATTER CricketMarket = 1241
|
||||||
|
CRICKET_TEAM_TOP_BOWLE CricketMarket = 1242
|
||||||
|
CRICKET_PLAYER_OF_THE_MATCH CricketMarket = 346
|
||||||
|
CRICKET_FIRST_WICKET_METHOD CricketMarket = 30205
|
||||||
|
|
||||||
|
// First Over
|
||||||
|
CRICKET_FIRST_OVER_TOTAL_RUNS CricketMarket = 300336
|
||||||
|
CRICKET_FIRST_OVER_TOTAL_RUNS_Odd_Even CricketMarket = 300118
|
||||||
|
|
||||||
|
// Inninigs 1
|
||||||
|
CRICKET_FIRST_INNINIGS_SCORE CricketMarket = 300338
|
||||||
|
CRICKET_INNINGS_OF_MATCH_BOWLED_OUT CricketMarket = 300108
|
||||||
|
|
||||||
|
// Match
|
||||||
|
CRICKET_TOP_MATCH_BATTER CricketMarket = 30245
|
||||||
|
CRICKET_TOP_MATCH_BOWLER CricketMarket = 30246
|
||||||
|
)
|
||||||
|
|
||||||
// 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
|
||||||
|
|
||||||
var SupportedMarkets = map[int64]bool{
|
var SupportedMarkets = map[int64]bool{
|
||||||
|
|
@ -164,4 +187,18 @@ var SupportedMarkets = map[int64]bool{
|
||||||
|
|
||||||
int64(ICE_HOCKEY_ALTERNATIVE_PUCK_LINE_TWO_WAY): false,
|
int64(ICE_HOCKEY_ALTERNATIVE_PUCK_LINE_TWO_WAY): false,
|
||||||
int64(ICE_HOCKEY_ALTERNATIVE_TOTAL_TWO_WAY): false,
|
int64(ICE_HOCKEY_ALTERNATIVE_TOTAL_TWO_WAY): false,
|
||||||
|
|
||||||
|
// Cricket Markets
|
||||||
|
int64(CRICKET_TO_WIN_THE_MATCH): true,
|
||||||
|
int64(CRICKET_FIRST_OVER_TOTAL_RUNS_Odd_Even): true,
|
||||||
|
int64(CRICKET_FIRST_INNINIGS_SCORE): true,
|
||||||
|
|
||||||
|
int64(CRICKET_INNINGS_OF_MATCH_BOWLED_OUT): false,
|
||||||
|
int64(CRICKET_FIRST_OVER_TOTAL_RUNS): false,
|
||||||
|
int64(CRICKET_TEAM_TOP_BATTER): false,
|
||||||
|
int64(CRICKET_TEAM_TOP_BOWLE): false,
|
||||||
|
int64(CRICKET_PLAYER_OF_THE_MATCH): false,
|
||||||
|
int64(CRICKET_FIRST_WICKET_METHOD): false,
|
||||||
|
int64(CRICKET_TOP_MATCH_BATTER): false,
|
||||||
|
int64(CRICKET_TOP_MATCH_BOWLER): false,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -709,3 +709,46 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cricket evalations
|
||||||
|
func evaluateInningScore(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
||||||
|
var inningsScore int
|
||||||
|
if outcome.OddName == "1" {
|
||||||
|
inningsScore = score.Home
|
||||||
|
} else if outcome.OddName == "2" {
|
||||||
|
inningsScore = score.Away
|
||||||
|
} else {
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd header: %s", outcome.OddHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Fields(outcome.OddHeader)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd format: %s", outcome.OddHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
evalType := parts[0]
|
||||||
|
|
||||||
|
threshold, err := strconv.ParseFloat(parts[1], 64)
|
||||||
|
if err != nil {
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid threshold value: %s", parts[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
switch evalType {
|
||||||
|
case "Over":
|
||||||
|
if float64(inningsScore) > threshold {
|
||||||
|
return domain.OUTCOME_STATUS_WIN, nil
|
||||||
|
}
|
||||||
|
return domain.OUTCOME_STATUS_LOSS, nil
|
||||||
|
case "Under":
|
||||||
|
if float64(inningsScore) < threshold {
|
||||||
|
return domain.OUTCOME_STATUS_WIN, nil
|
||||||
|
}
|
||||||
|
return domain.OUTCOME_STATUS_LOSS, nil
|
||||||
|
case "Exactly":
|
||||||
|
if float64(inningsScore) == threshold {
|
||||||
|
return domain.OUTCOME_STATUS_WIN, nil
|
||||||
|
}
|
||||||
|
return domain.OUTCOME_STATUS_LOSS, nil
|
||||||
|
default:
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid comparison operator: %s", evalType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,8 @@ func (s *Service) FetchAndProcessResults(ctx context.Context) error {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
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)
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to create request", "event_id", eventID, "error", err)
|
s.logger.Error("Failed to create request", "event_id", eventID, "error", err)
|
||||||
|
|
@ -219,6 +220,12 @@ func (s *Service) fetchResult(ctx context.Context, eventID, oddID, marketID, spo
|
||||||
s.logger.Error("Failed to parse ice hockey", "event id", eventID, "market_id", marketID, "error", err)
|
s.logger.Error("Failed to parse ice hockey", "event id", eventID, "market_id", marketID, "error", err)
|
||||||
return domain.CreateResult{}, err
|
return domain.CreateResult{}, err
|
||||||
}
|
}
|
||||||
|
case domain.CRICKET:
|
||||||
|
result, err = s.parseCricket(resultResp.Results[0], eventID, oddID, marketID, outcome)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error("Failed to parse cricket", "event id", eventID, "market_id", marketID, "error", err)
|
||||||
|
return domain.CreateResult{}, err
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
s.logger.Error("Unsupported sport", "sport", sportID)
|
s.logger.Error("Unsupported sport", "sport", sportID)
|
||||||
return domain.CreateResult{}, fmt.Errorf("unsupported sport: %v", sportID)
|
return domain.CreateResult{}, fmt.Errorf("unsupported sport: %v", sportID)
|
||||||
|
|
@ -263,6 +270,10 @@ func (s *Service) parseFootball(resultRes json.RawMessage, eventID, oddID, marke
|
||||||
|
|
||||||
func (s *Service) parseBasketball(response json.RawMessage, eventID, oddID, marketID int64, outcome domain.BetOutcome) (domain.CreateResult, error) {
|
func (s *Service) parseBasketball(response json.RawMessage, eventID, oddID, marketID int64, outcome domain.BetOutcome) (domain.CreateResult, error) {
|
||||||
var basketBallRes domain.BasketballResultResponse
|
var basketBallRes domain.BasketballResultResponse
|
||||||
|
|
||||||
|
// TODO: here !!
|
||||||
|
fmt.Println(string(response))
|
||||||
|
|
||||||
if err := json.Unmarshal(response, &basketBallRes); err != nil {
|
if err := json.Unmarshal(response, &basketBallRes); err != nil {
|
||||||
s.logger.Error("Failed to unmarshal football result", "event_id", eventID, "error", err)
|
s.logger.Error("Failed to unmarshal football result", "event_id", eventID, "error", err)
|
||||||
return domain.CreateResult{}, err
|
return domain.CreateResult{}, err
|
||||||
|
|
@ -317,6 +328,33 @@ func (s *Service) parseIceHockey(response json.RawMessage, eventID, oddID, marke
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) parseCricket(response json.RawMessage, eventID, oddID, marketID int64, outcome domain.BetOutcome) (domain.CreateResult, error) {
|
||||||
|
var cricketRes domain.CricketResultResponse
|
||||||
|
|
||||||
|
if err := json.Unmarshal(response, &cricketRes); err != nil {
|
||||||
|
s.logger.Error("Failed to unmarshal football result", "event_id", eventID, "error", err)
|
||||||
|
return domain.CreateResult{}, err
|
||||||
|
}
|
||||||
|
if cricketRes.TimeStatus != "3" {
|
||||||
|
s.logger.Warn("Match not yet completed", "event_id", eventID)
|
||||||
|
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
||||||
|
}
|
||||||
|
|
||||||
|
status, err := s.evaluateCricketOutcome(outcome, cricketRes)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
||||||
|
return domain.CreateResult{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.CreateResult{
|
||||||
|
BetOutcomeID: 0,
|
||||||
|
EventID: eventID,
|
||||||
|
OddID: oddID,
|
||||||
|
MarketID: marketID,
|
||||||
|
Status: status,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseScore(home string, away string) struct{ Home, Away int } {
|
func parseScore(home string, away string) struct{ Home, Away int } {
|
||||||
homeVal, _ := strconv.Atoi(strings.TrimSpace(home))
|
homeVal, _ := strconv.Atoi(strings.TrimSpace(home))
|
||||||
awaVal, _ := strconv.Atoi(strings.TrimSpace(away))
|
awaVal, _ := strconv.Atoi(strings.TrimSpace(away))
|
||||||
|
|
@ -487,3 +525,23 @@ func (s *Service) evaluateIceHockeyOutcome(outcome domain.BetOutcome, res domain
|
||||||
|
|
||||||
return domain.OUTCOME_STATUS_PENDING, nil
|
return domain.OUTCOME_STATUS_PENDING, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) evaluateCricketOutcome(outcome domain.BetOutcome, res domain.CricketResultResponse) (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)
|
||||||
|
}
|
||||||
|
|
||||||
|
score := parseSS(res.SS)
|
||||||
|
|
||||||
|
switch outcome.MarketID {
|
||||||
|
case int64(domain.CRICKET_TO_WIN_THE_MATCH):
|
||||||
|
return evaluateFullTimeResult(outcome, score)
|
||||||
|
case int64(domain.CRICKET_FIRST_OVER_TOTAL_RUNS_Odd_Even):
|
||||||
|
return evaluateGoalsOddEven(outcome, score)
|
||||||
|
case int64(domain.CRICKET_FIRST_INNINIGS_SCORE):
|
||||||
|
return evaluateInningScore(outcome, score)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
5
makefile
5
makefile
|
|
@ -27,6 +27,11 @@ migrations/up:
|
||||||
@echo 'Running up migrations...'
|
@echo 'Running up migrations...'
|
||||||
@migrate -path ./db/migrations -database $(DB_URL) up
|
@migrate -path ./db/migrations -database $(DB_URL) up
|
||||||
|
|
||||||
|
.PHONY: postgres
|
||||||
|
postgres:
|
||||||
|
@echo 'Running postgres db...'
|
||||||
|
docker compose -f compose.db.yaml exec postgres psql -U root -d gh
|
||||||
|
|
||||||
.PHONY: swagger
|
.PHONY: swagger
|
||||||
swagger:
|
swagger:
|
||||||
@swag init -g cmd/main.go
|
@swag init -g cmd/main.go
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user