【ジャニオタ用】公式からgoogleカレンダーに予定を自動登録するスクリプト作った

2026年1月15日 | からふみ | ファイル: tech, ジャニーズ.

オタクになって以来ずっとKing & Prince情報さんのgoogleカレンダーを頼りに生きてきた。なんですけど、多分KP情報さんって手動で入れてくださっているっぽいんですよね…!オタクの時間には限りがあり、善意の手動はいつか限界も来るし…

ってことでGeminiにアドバイスしてもらいながら(そしてコードはほとんど書いてもらった)、公式サイトを深夜に毎日1回チェックしてカレンダーに登録するGASを作り、カレンダーを公開しました。

なんか狭くて草、なんでだよ

iPhoneで登録(購読)するやり方

  1. https://calendar.google.com をブラウザに貼り付けて、iPhoneに追加済みのアカウントでログインしておく。
  2. 下記のURLをクリック。「カレンダーを追加しますか?」って聞かれたら「はい」を押す。聞かれなければ右下の「+」を押してみてください
https://calendar.google.com/calendar/embed?src=renren123calendar%40gmail.com&ctz=Asia%2FTokyo
  1. カレンダーの同期設定 https://calendar.google.com/calendar/u/0/syncselect をクリックして、追加した↑れんれんカレンダーにチェックを入れ右下の「保存」を押す
  2. iPhoneのカレンダーアプリを開いて右下にあるカレンダーマークを押す
  3. れんれんカレンダーがチェックされていることを確認

手順3から5の参考画像

注意事項

  • 開始時刻は公式から取ってますが、枠は1時間固定にしているので、実際の長さとは異なる場合があります。ごめん
  • コンサートの予定はすげー取得が面倒だったので反映されてません、ごめん
  • 事務所のサイトしょっちゅう色々変わるので仕様が変わってたら自動更新が失敗するかも、ごめん
  • 漏れとか誤りがあったらごめん、自己責任で信じてください

以上です!楽しくれんれんを応援しような!

別グループでやりたい人向けの開発編

↓のコードをそのまま使うと「永瀬廉」と「King&Prince」の予定を登録することになってるんだけど、ちょっと各自のグループのURLを見てほしい。

https://starto.jp/s/p/media/list?tag=41&list[]=41&artist=41&dy=202601

キンプリに振られてるIDは「41」なことがわかりますね。そのほかに見てみるとSixTONESは「42」Travis Japanは「60」ってワケ。あとはわかるな?!

手順 ※サポートはしません

  1. googleアカウントを用意する(専用がいい)
  2. https://script.google.com/home から新しいプロジェクトを作成
  3. コードを貼り、自軍および自担に書き換える
  4. うまく実行できたらトリガを設定する。あまりにアクセスしすぎると勘付かれそうなので、深夜に一日一回とかがいいと思います。

コード

function syncKP_Schedule_3Months() {
  const calendarName = 'アーティスト予定';
  // 判定用キーワード(全角・半角対応)
  const targetRegex = /永瀬廉|King\s*[&&]\s*Prince/i;
  const calendar = CalendarApp.getCalendarsByName(calendarName)[0] || CalendarApp.getDefaultCalendar();

  // 今月(0)から2ヶ月先(2)までループ
  for (let i = 0; i <= 2; i++) {
    const targetDate = new Date();
    targetDate.setMonth(targetDate.getMonth() + i);
    const yearMonth = Utilities.formatDate(targetDate, 'JST', 'yyyyMM');
    
    Logger.log(`--- ${yearMonth} のデータをチェック中 ---`);
    
    const url = `https://starto.jp/s/p/api/list/media?dy=${yearMonth}&list[]=41&list[]=41&rw=3000`;
    const response = UrlFetchApp.fetch(url);
    const json = JSON.parse(response.getContentText());
    const items = json.items;

  if (!items || items.length === 0) {
    Logger.log(`${yearMonth} のデータはありませんでした。`);
    continue;
  }

  let count = 0;

  items.forEach(item => {
    const title = item.name;
    const category = item.catename; // TV, RADIO, CONCERT, MOVIE, MAGAZINE 等
    const artistsInfo = item.tags_display || "";
    
    // 【判定ロジックの修正】
    // 1. 出演者情報に「永瀬廉」か「King & Prince」が含まれる
    // 2. もしくは、カテゴリーが CONCERT か MOVIE である(このページにある時点で本人達のものとみなす)
    const isTarget = targetRegex.test(artistsInfo) || 
                     category === "CONCERT" || 
                     category === "MOVIE" || 
                     category === "STAGE";

    if (isTarget) {
      const dateStr = item.date_base;
      const timeStr = item.time;
      const eventTitle = `[${category}] ${title}`;
      const description = `詳細: ${item.comment2}\nURL: https://starto.jp${item.link}`;
      
      let startTime, endTime, isAllDay;
      const timeMatch = timeStr ? timeStr.match(/(\d{1,2}):(\d{2})/) : null;

      if (timeMatch) {
        const hours = parseInt(timeMatch[1]);
        const minutes = parseInt(timeMatch[2]);
        startTime = new Date(dateStr);
        startTime.setHours(hours, minutes, 0);
        endTime = new Date(startTime.getTime() + (60 * 60 * 1000));
        isAllDay = false;
      } else {
        startTime = new Date(dateStr);
        isAllDay = true;
      }

      // 重複チェック
      const checkDate = new Date(dateStr);
      const eventsOnDay = calendar.getEventsForDay(checkDate);
      const isAlreadyRegistered = eventsOnDay.some(event => {
        if (event.getTitle() === eventTitle) {
          if (isAllDay) return event.isAllDayEvent();
          return event.getStartTime().getTime() === startTime.getTime();
        }
        return false;
      });

      if (!isAlreadyRegistered) {
        if (isAllDay) {
          calendar.createAllDayEvent(eventTitle, startTime, {description: description});
          Logger.log('登録: ' + eventTitle);
        } else {
          calendar.createEvent(eventTitle, startTime, endTime, {description: description});
          Logger.log('登録: ' + eventTitle + ` (${timeStr})`);
        }
        count++;
      }
    }
  });
  Logger.log(`${yearMonth} の新規登録数: ${count}件`);
  }
  Logger.log('3ヶ月分の処理が完了しました。');
}

キンプリのオタクらしくGeminiで楽しい推し活ができたネ!


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください