yuheijotaki.com

GASでMLB試合予定を日本時間でGoogleカレンダーに登録する

  • MLB の Stats API を使用
  • GAS で予定取得し変換、Googleカレンダーに登録
    • 特定チーム(今回はエンゼルス)の予定を取得
    • 時刻は日本時間に
    • タイトルのチーム名は3文字の省略形(LAA など)に

// GoogleカレンダーIDをセット
const CALENDAR_ID = '[GOOGLE_CALENDAR_ID]';

// MLB Data APIからエンゼルスの試合情報を取得
function fetchAngelsSchedule() {
  const apiUrl = 'https://statsapi.mlb.com/api/v1/schedule?teamId=108&season=2023&sportId=1';
  const response = UrlFetchApp.fetch(apiUrl);
  const data = JSON.parse(response.getContentText());
  const games = data.dates.flatMap(date => date.games);

  return games.map(game => {
    const gameDate = new Date(game.gameDate);
    const end = new Date(gameDate.getTime() + 3 * 60 * 60 * 1000); // 試合終了時間を仮定して3時間後に設定
    const isHome = game.teams.home.team.id === 108;
    const opponent = isHome ? game.teams.away.team : game.teams.home.team;
    const opponentShortName = getShortName(opponent);
    return {
      start: gameDate,
      end: end,
      opponent: opponentShortName,
      isHome: isHome,
    };
  });
}

function getShortName(team) {
  const shortNames = {
    'Baltimore Orioles': 'BAL',
    'Boston Red Sox': 'BOS',
    'New York Yankees': 'NYY',
    'Tampa Bay Rays': 'TBR',
    'Toronto Blue Jays': 'TOR',
    'Chicago White Sox': 'CWS',
    'Cleveland Guardians': 'CLE',
    'Detroit Tigers': 'DET',
    'Kansas City Royals': 'KC',
    'Minnesota Twins': 'MIN',
    'Los Angeles Angels': 'LAA',
    'Oakland Athletics': 'OAK',
    'Seattle Mariners': 'SEA',
    'Texas Rangers': 'TEX',
    'Houston Astros': 'HOU',
    'Atlanta Braves': 'ATL',
    'Miami Marlins': 'MIA',
    'New York Mets': 'NYM',
    'Philadelphia Phillies': 'PHI',
    'Washington Nationals': 'WSH',
    'Chicago Cubs': 'CHC',
    'Cincinnati Reds': 'CIN',
    'Milwaukee Brewers': 'MIL',
    'Pittsburgh Pirates': 'PIT',
    'St. Louis Cardinals': 'STL',
    'Arizona Diamondbacks': 'ARI',
    'Colorado Rockies': 'COL',
    'Los Angeles Dodgers': 'LAD',
    'San Diego Padres': 'SDP',
    'San Francisco Giants': 'SFG',
  };

  return shortNames[team.name] || team.name;
}

// 日時を日本時間に変換
function convertToJST(date) {
  const jstDate = new Date(date.toLocaleString('en-US', { timeZone: 'Asia/Tokyo' }));
  return jstDate;
}

// Googleカレンダーに試合予定を登録
function addAngelsScheduleToCalendar() {
  const calendar = CalendarApp.getCalendarById(CALENDAR_ID);
  const games = fetchAngelsSchedule();

  const seasonStart = new Date(2023, 2, 31); // 2023年3月31日
  const seasonEnd = new Date(2023, 9, 31); // 2023年10月31日

  games.forEach(game => {
    const startJST = convertToJST(game.start);
    const endJST = convertToJST(game.end);

    if (startJST >= seasonStart && startJST <= seasonEnd) {
      const title = game.isHome ? `LAA vs ${game.opponent}` : `${game.opponent} vs LAA`;

      // 予定がすでにあるかチェック
      const rangeStart = new Date(startJST.getTime() - 24 * 60 * 60 * 1000);
      const rangeEnd = new Date(startJST.getTime() + 24 * 60 * 60 * 1000);
      const events = calendar.getEvents(rangeStart, rangeEnd, { search: title });

      const isEventExist = events.some(event => {
        const eventStart = event.getStartTime();
        return eventStart.getYear() === startJST.getYear() &&
               eventStart.getMonth() === startJST.getMonth() &&
               eventStart.getDate() === startJST.getDate();
      });

      if (!isEventExist) {
        // 予定がなければ新たに追加
        calendar.createEvent(title, startJST, endJST);
      }
    }
  });
}