🌲

GoogleカレンダーとTimeTreeを自動連携するやり方(半自動)

に公開

🎯 目的

  • 普段使っている Googleカレンダーの予定を TimeTreeでも見える化 したい
  • 手作業のコピーや二重入力を避けて、 できるだけ工数を減らしたい
  • 背景として、家族がTimeTreeを利用しているが自分はGoogleカレンダー一択なため、いちいちTimeTreeに予定を作成して共有するのがめんどくさかった


📝 課題と解決策

課題1:GoogleカレンダーからTimeTreeへ直接連携できない

解決策

  • 「Googleカレンダー → iPhone標準カレンダー → TimeTree」のルートを構築
  • iPhone標準カレンダーはGoogleカレンダーを取り込める
  • TimeTreeはiPhoneカレンダーをインポートできる
    👉 直接は無理でも、間に「別カレンダー」を挟むことで実現


課題2:過去の予定までコピーされてしまう

解決策

  • GASで「今日以降の予定だけコピー」するように修正


課題3:毎月コピーすると同じ予定が重複する

解決策

  • GASに「既存チェック」を追加
  • タイトル+日時が同じ予定があればスキップ


課題4:プライベート予定まで詳細がコピーされる

解決策

  • GASで「プライベート(private)の予定は『予定あり』に変換」


課題5:コピー内容が確認できない

解決策

  • GASで「コピーした予定の日時+タイトルをログに出力」


課題6:予定を二重に入力する必要がある

解決策

  • GASで「普段使うカレンダー → 共有用カレンダー」に自動コピー
  • 普段はいつも通りメインカレンダーに予定を入れるだけでOK


✅ 解決策まとめ(やり方)

① Google Apps Script (GAS) プロジェクトを作成

  • Google Apps Script を開く
  • 新しいプロジェクトを作成
  • 名前を「GoogleCalendar_Copy」などに変更


② Calendar API を有効化

  • GASエディタ左メニュー → 「サービス(積み木マーク)」
  • 「高度なGoogleサービス」をクリック
  • Calendar API を「オン」にする
  • さらに「Google Cloud Consoleを開く」を押して、そこでも Calendar API を有効化

👉 これで Calendar.Events.listCalendar.Events.insert が使えるようになる


③ コピー用カレンダーを作成

  • Googleカレンダーを開く
  • 左の「+」→「新しいカレンダーを作成」
  • 名前を「TimeTree同期用」などにする
  • カレンダー設定 → 「カレンダー統合」→ カレンダーIDをコピー


④ コードを貼り付ける

function copyFutureEventsWithCalendarAPI() {
  var sourceCalendarId = "primary"; // 元カレンダー(メインなら "primary")
  var targetCalendarId = "your-target-calendar@group.calendar.google.com"; // コピー先カレンダーID
  
  var today = new Date();
  var end = new Date();
  end.setFullYear(end.getFullYear() + 1);

  // 元カレンダーからイベント取得
  var events = Calendar.Events.list(sourceCalendarId, {
    timeMin: today.toISOString(),
    timeMax: end.toISOString(),
    singleEvents: true,
    orderBy: "startTime"
  });

  var copied = [];
  var skipped = [];

  for (var i = 0; i < events.items.length; i++) {
    var ev = events.items[i];
    var start = new Date(ev.start.dateTime || ev.start.date); // 終日対応
    var endTime = new Date(ev.end.dateTime || ev.end.date);
    var title = ev.summary || "(無題)";

    // プライベートならタイトルを「予定あり」に変換
    var copiedTitle = (ev.visibility === "private") ? "予定あり" : title;

    // コピー先に同じ予定があるか確認
    var existing = Calendar.Events.list(targetCalendarId, {
      timeMin: start.toISOString(),
      timeMax: endTime.toISOString(),
      q: copiedTitle
    });

    if (existing.items && existing.items.length > 0) {
      skipped.push(start.toLocaleString() + " - " + copiedTitle);
      continue;
    }

    // コピー先に作成(privateの場合は場所・説明を入れない)
    if (ev.visibility === "private") {
      Calendar.Events.insert({
        summary: "予定あり",
        start: { dateTime: start.toISOString() },
        end: { dateTime: endTime.toISOString() }
      }, targetCalendarId);
    } else {
      Calendar.Events.insert({
        summary: copiedTitle,
        start: { dateTime: start.toISOString() },
        end: { dateTime: endTime.toISOString() },
        location: ev.location,
        description: ev.description
      }, targetCalendarId);
    }

    copied.push(start.toLocaleString() + " - " + copiedTitle);
  }

  // ログ出力
  Logger.log("=== コピーした予定 ===");
  copied.forEach(function(e) { Logger.log(e); });

  Logger.log("=== スキップした予定 ===");
  skipped.forEach(function(e) { Logger.log(e); });

  Logger.log("コピー完了!新規コピー: " + copied.length + "件, スキップ: " + skipped.length + "件");
}


⑤ 実行テスト

  • ▶ ボタンを押して copyFutureEventsWithCalendarAPI を実行
  • 初回は「権限の承認」が必要 → 許可
  • 「表示 → ログ」で「コピーした予定」と「スキップした予定」が出れば成功


⑥ 自動化(トリガー設定)

  • GASエディタ左の「時計アイコン」 → 「トリガー」
  • 「トリガーを追加」
    • 関数:copyFutureEventsWithCalendarAPI
    • イベントのソース:時間主導型
    • 時間ベース:月ベース、毎月1日など
  • 保存

👉 毎月自動で「今日以降1年分」をコピー


⑦ TimeTreeで表示

  • iPhoneの標準カレンダーに「コピー先カレンダー」を追加
    • 設定 → カレンダー → アカウント → Googleアカウント → 同期するカレンダーにチェック
  • TimeTreeアプリで「iPhoneカレンダーからインポート」を設定

👉 これで自動的にTimeTreeに予定が反映される


🔄 最終的な運用フロー

  1. 普段は Googleカレンダー(メイン) に予定を入力するだけ
  2. GASが毎月1日に自動実行 → 「今日以降1年分」を別カレンダーにコピー
    • 重複チェックあり
    • プライベート予定は「予定あり」に変換
    • コピー内容はログで確認可能
  3. iPhone標準カレンダーにその「別カレンダー」を読み込む
  4. TimeTreeでiPhoneカレンダーを定期的にインポート → TimeTreeにも反映


📝 まとめ

今回GPTを使って試行錯誤しながらやってみました。
非エンジニアですが、GPTを使えば30分くらいでそれっぽく動く仕組みを作ることができました。

エンジニアの方なら、完全に自動化まで持っていけるんですかね…。
自分ももっと精進します💪

Discussion