【GAS】嬉しい！毎日指定した時間ジャストにGoogleカレンダーのスケジュールが届く！

# 毎日定時に、今日のスケジュールが知りたい！
自分を含め、3名のスケジュール管理をしています。同じ場所で働いていないため、いつもそれぞれのスケジュールを、必要な時に調べていました。これを、**毎日定時にmailに届くようにしたいと考えたのが、今回のきっかけ**です。今回はアカウント保持者が1名のため、代表者のカレンダーに他２名のスケジュールを登録して使用しています。


## はじめに
この記事では、**Google Apps Script（GAS）を使用して、Googleカレンダーのスケジュールを毎日定刻に自動で送信する方法**について解説します。このスクリプトを活用することで、チームメンバーや個人の予定を確実に共有できるようになります。また、コードを書くことができない私が、Copilotの力を借りで奮闘した記録になります。
## 必要なもの
Googleアカウント
Googleカレンダー
Googleスプレッドシート
[Microsoft Copilot](https://copilot.microsoft.com/ "Microsoft Copilot Home")

## スクリプトの準備
Googleスプレッドシートを開き、「拡張機能」メニューから「Apps Script」を選択します。以下のスクリプトを貼り付けてください。

:::note alert
**サンプルコードを修正しました**
24時間毎分確認するスクリプトになっていたため、指定時間の２分前から2分間確認するよう修正しました。
※今回は8:00に送信するため、7:58～8:00の間の2分間確認するようにしました。
:::

<details><summary>サンプルコード（open属性なし）</summary>

```rb
// 毎分実行される関数
function checkAndRunDailyTask() {
  var now = new Date();
  var targetHour = 8;
  var targetMinute = 00;
  var startMinute = targetMinute - 2;
  var currentHour = now.getHours();
  var currentMinute = now.getMinutes();

  // 7:58から 8:00までの間に確認し、指定された時刻に一致した場合に関数を実行
  if ((currentHour === targetHour && currentMinute >= startMinute && currentMinute <= targetMinute) && currentMinute === targetMinute) {
    Logger.log('指定された時刻にスクリプトが実行されています');
    sendDailyCalendarEvents();
  }
}

// メール送信関数
function sendDailyCalendarEvents() {
  try {
    var calendarId = 'mailアドレス'; // 確認した主カレンダーのID
    var toEmail = 'mailアドレス'; // TOの送信先メールアドレス
    var ccEmail = 'mailアドレス'; // CCの送信先メールアドレス
    var yourName = 'あなたの名前'; // 送信者の名前

    var today = new Date();
    today.setHours(0, 0, 0, 0);
    var tomorrow = new Date(today);
    tomorrow.setDate(today.getDate() + 1);

    // 主カレンダーから今日の予定を取得
    var events = CalendarApp.getCalendarById(calendarId).getEvents(today, tomorrow);

    // 予定を名前ごとにグループ化する
    var groupedEvents = {};
    events.forEach(function(event) {
      var eventTitle = event.getTitle();
      var name = eventTitle.match(/【(.+?)】/);
      if (name) {
        name = name[1];
        if (!groupedEvents[name]) {
          groupedEvents[name] = [];
        }
        var eventDetails;
        if (eventTitle.includes("休日")) {
          eventDetails = eventTitle;
        } else {
          var startTime = Utilities.formatDate(event.getStartTime(), Session.getScriptTimeZone(), "HH:mm");
          var endTime = Utilities.formatDate(event.getEndTime(), Session.getScriptTimeZone(), "HH:mm");
          eventDetails = startTime + ' ～ ' + endTime + ' - ' + eventTitle;
        }
        groupedEvents[name].push(eventDetails);
      }
    });

    // メール本文を作成
    var message = '今日の予定\n\n';
    for (var name in groupedEvents) {
      message += '【' + name + '】の予定\n';
      groupedEvents[name].forEach(function(details) {
        message += details + '\n';
      });
      message += '\n';
    }

    // メール本文に「よろしくお願いします。」と名前を追加
    message += 'よろしくお願いします。\n' + yourName;

    // メール送信の前にログを追加
    Logger.log('メール送信: TO: ' + toEmail + ', CC: ' + ccEmail + ', Subject: ' + '本日の予定をご連絡します');
    Logger.log('メール内容: ' + message);

    // メール送信
    MailApp.sendEmail({
      to: toEmail,
      cc: ccEmail,
      subject: '本日の予定をご連絡します',
      body: message
    });

  } catch (error) {
    Logger.log('Error: ' + error.message);
    MailApp.sendEmail('mail', 'エラー発生', 'スクリプト実行中にエラーが発生しました: ' + error.message);
  }
}

// トリガー作成関数
function createMinuteTrigger() {
  try {
    // 既存のトリガーを削除
    deleteTriggers();
    // 毎分実行するトリガーを設定
    ScriptApp.newTrigger('checkAndRunDailyTask')
      .timeBased()
      .everyMinutes(1)
      .create();
  } catch (error) {
    Logger.log('Error: ' + error.message);
    MailApp.sendEmail('your_email@gmail.com', 'トリガー作成エラー', 'トリガー作成中にエラーが発生しました: ' + error.message);
  }
}

// トリガー削除関数
function deleteTriggers() {
  var allTriggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < allTriggers.length; i++) {
    ScriptApp.deleteTrigger(allTriggers[i]);
  }
}


```
</details>

## トリガーの設定
スクリプトエディタの「時計アイコン」をクリックして、毎分実行するトリガーを設定します。これにより、**毎日午前8時ちょうどにスケジュールがメールで送信**されます。

:::note alert
**希望の定時時間に必ず送られて来るために**
時間ベースでは、指定の1時間のうちいつ来るかわからないため、スクリプトに1分おきに確認し定時に送信する指示がされています。
:::


![スケジュールトリガー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727502/169bc813-4f83-60d9-bc46-f8a38ad0d342.jpeg)

## 苦労した点
この記事を書く中で、特に苦労した点についても共有します。
1名以外はアドレスを保有していないため、代表者のカレンダーに他２名のスケジュール登録の工夫、mail本文の見やすいレイアウトに気を配りました。中でも、休日入力の人には時間を表記しないこと、人でグルーピングすることで見やすいレイアウトになりました。

:::note warn
**正確な時刻指定**
Google Apps Scriptの時間ベースのトリガーでは正確な時刻指定が難しく、毎分実行する方法で対応しました。
:::

:::note info
**休日の表示**
最初は休日のスケジュールにも時間が表示されてしまいましたが、「休日」のイベントには時間が表示されないように工夫しました。この修正により、わかりやすいスケジュール表示が実現できました。
:::
![スケジュールmail本文.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727502/9f908cec-1503-2e76-d97f-6788dfcb1f34.jpeg)

:::note warn
**エラーハンドリング**
スクリプトのエラーハンドリングをしっかり行い、ログを使って問題を特定しました。エラー発生時には通知メールも送信するように設定しました。
:::

:::note info
**複数の受信者**
TO、CC、BCCの複数の受信者にメールを送信する方法に注意し、正確に設定しました。
:::

## おわりに
**書かないGAS部**に入部した私は、Copilotを頼りに今回作成しました。何度もエラーが出て聞き直すこと10回以上になった時には、「エラーばっかりじゃん！」と大人げなく怒りましたが、直後にエラー改善をしました（笑）感謝の気持ちを伝えるばかりではなく、たまには本音をぶつけることも必要なんだと気づきをいただきました。これは実生活でも必要なことですよね！

**この記事を読んだ誰かが、このスクリプトを活用することで、日々の予定管理が大幅に改善されることを願っています。**　

もし他にも改善点やアイデアがあれば、ぜひコメントで教えてください！

最後までお読みいただき、ありがとうございました！