22}
23
24export interface YahooAPIConfig {
25 access_token: string;
26 refresh_token: string;
99 }
100
101 // Initialize Yahoo Fantasy API client
102 const yahooAPI = new YahooFantasyAPIClient(tokenData, this.tokenStorage, userId);
103
104 // Get user's leagues
105 const leagues = await yahooAPI.getUserLeagues(userId);
106 console.log(`🏟️ Found ${leagues.length} leagues for user ${userId}`);
107
111
112 // Get user's team in this league
113 const teamKey = await yahooAPI.getTeamKey(userId, league.league_id);
114 if (!teamKey) {
115 throw new Error(`Could not find team key for league ${league.league_id}`);
117
118 // Schedule pitchers for today
119 const scheduleResult = await this.schedulePitchersForTeam(yahooAPI, teamKey, date);
120
121 results.leagues_processed.push({
139 }
140
141 private async schedulePitchersForTeam(yahooAPI: YahooFantasyAPIClient, teamKey: string, date: Date) {
142 // Get today's probable pitchers from MLB API
143 const probablePitchers = await this.getTodaysProbablePitchers(date);
144 console.log(`🎯 Found ${probablePitchers.length} probable pitchers for ${date.toDateString()}`);
145
146 // Get current team roster
147 const roster = await yahooAPI.getTeamRoster(teamKey);
148 console.log(`👥 Team roster has ${roster.length} players`);
149
166 for (const change of optimization.changes) {
167 try {
168 await yahooAPI.setPlayerPosition(teamKey, change.playerId, change.newPosition);
169 results.pitchers_scheduled.push(change.playerId);
170 results.changes_made.push(change);
186 ): Promise<Array<{ name: string; team: string; game_time?: string }>> {
187 try {
188 // Call MLB Stats API for probable pitchers
189 const dateStr = date.toISOString().split("T")[0];
190 const response = await fetch(
191 `https://statsapi.mlb.com/api/v1/schedule?sportId=1&date=${dateStr}&hydrate=probablePitcher`,
192 );
193
194 if (!response.ok) {
195 throw new Error(`MLB API error: ${response.status}`);
196 }
197
440}
441
442// Simplified Yahoo Fantasy API client for Val.town
443class YahooFantasyAPIClient {
444 private config: YahooAPIConfig;
445 private baseUrl = "https://fantasysports.yahooapis.com/fantasy/v2";
446 private tokenStorage: LouTokenStorage;
447 private userId: string;
448
449 constructor(config: YahooAPIConfig, tokenStorage: LouTokenStorage, userId: string) {
450 this.config = config;
451 this.tokenStorage = tokenStorage;
465 private async refreshAccessToken(): Promise<void> {
466 try {
467 const response = await fetch("https://api.login.yahoo.com/oauth2/get_token", {
468 method: "POST",
469 headers: {
551
552 if (!retryResponse.ok) {
553 throw new Error(`Yahoo API error after refresh: ${retryResponse.status} ${retryResponse.statusText}`);
554 }
555
558
559 if (!response.ok) {
560 throw new Error(`Yahoo API error: ${response.status} ${response.statusText}`);
561 }
562
744 await this.ensureValidToken();
745
746 // Yahoo Fantasy API requires XML for roster changes
747 const dateStr = new Date().toISOString().split("T")[0];
748
776 if (!response.ok) {
777 const responseText = await response.text();
778 console.error(`❌ Yahoo API error response: ${responseText}`);
779 throw new Error(`Failed to set player position: ${response.status} ${response.statusText}`);
780 }
796
797 // Store results in Val.town's blob storage for history
798 await fetch("https://api.val.town/v1/blob/scheduler_results", {
799 method: "POST",
800 headers: {