Files
iddaai-be/src/modules/spor-toto/services/toto-fetcher.service.ts
T
2026-04-16 17:21:48 +03:00

125 lines
3.2 KiB
TypeScript

import { Injectable, Logger } from "@nestjs/common";
import axios from "axios";
/**
* Spor Toto API response types
* Source: https://sportotov2.iddaa.com/SporToto
*/
export interface SporTotoApiEvent {
eventNo: number;
eventName: string; // "Blackpool-Burton Albion"
competitionName: string; // "İN1"
eventDate: string; // "2026-03-28T18:00:00"
result: string | null;
winner: string | null;
}
export interface SporTotoApiDividend {
winnerCount15?: number;
dividend15?: number;
winnerCount14?: number;
dividend14?: number;
winnerCount13?: number;
dividend13?: number;
winnerCount12?: number;
dividend12?: number;
}
export interface SporTotoApiResponse {
isSuccess: boolean;
data: {
payinBeginDate: string;
payinEndDate: string;
gameCycleNo: number;
dividends: SporTotoApiDividend | null;
events: SporTotoApiEvent[];
programName: string;
nextDrawExpectedWins: number | null;
} | null;
message: string;
error: string | null;
info: string | null;
dateTime: string | null;
}
@Injectable()
export class TotoFetcherService {
private readonly logger = new Logger(TotoFetcherService.name);
private readonly apiUrl = "https://sportotov2.iddaa.com/SporToto";
/**
* Fetch current bulletin from Spor Toto API
*/
async fetchCurrentBulletin(): Promise<SporTotoApiResponse | null> {
try {
this.logger.log("Fetching current Spor Toto bulletin...");
const response = await axios.get<SporTotoApiResponse>(this.apiUrl, {
timeout: 10000,
headers: {
Accept: "application/json",
"User-Agent": "SuggestBet/1.0",
},
});
if (!response.data?.isSuccess || !response.data?.data) {
this.logger.warn(
"Spor Toto API returned unsuccessful response",
response.data?.message,
);
return null;
}
this.logger.log(
`Fetched bulletin: Cycle ${response.data.data.gameCycleNo}${response.data.data.programName} (${response.data.data.events.length} events)`,
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
this.logger.error(
`Spor Toto API error: ${error.message}`,
error.response?.status,
);
} else {
this.logger.error("Spor Toto fetch failed", error);
}
return null;
}
}
/**
* Parse "Blackpool-Burton Albion" → { home: "Blackpool", away: "Burton Albion" }
*/
parseEventName(eventName: string): {
homeTeam: string;
awayTeam: string;
} {
const parts = eventName.split("-");
if (parts.length >= 2) {
return {
homeTeam: parts[0].trim(),
awayTeam: parts.slice(1).join("-").trim(),
};
}
return { homeTeam: eventName, awayTeam: "" };
}
/**
* Map API result/winner to TotoMatchResult enum value
* API returns: "1" (HOME), "0" (DRAW), "2" (AWAY)
*/
mapResultToEnum(winner: string | null): "HOME" | "DRAW" | "AWAY" | null {
if (!winner) return null;
switch (winner) {
case "1":
return "HOME";
case "0":
case "X":
return "DRAW";
case "2":
return "AWAY";
default:
return null;
}
}
}