Discord_image

どんなもの?

Googleカレンダーの説明欄にメモしてあるとき,Discordへタイトルとメモ内容の通知をしてくれる.

なぜ作ったの?

説明欄にメモをしてもそれを通知する術がない. せっかく大切なことをメモをしても忘れてしまうことが多々あった.

しくみ

以下のようなフローチャートになっている. 黄色の線で囲ったとこが説明あり→通知のシステムに関わる箇所である. GoogleカレンダーAPIフローチャート 図1: GoogleカレンダーAPIとDiscord通知の関係図(黄色の枠が今回の内容)

Apps scriptに書いてあるコード

Apps scriptには以下のto_discord_scriptが書かれている.ここが説明あり→通知するといったシステムの根幹である.

トリガーを使って一定時間ごとにそれぞれの関数が走っている.

関数の説明

  • sendDiscordReminders:30分後の説明ありの予定を走査している.トリガーで毎分実行している.
  • sendAllDayEventReminders:翌日の説明ありの予定を走査している.トリガーで毎日17時~18時のどこかでランダムに実行している.

トリガーの設定

  • sendDiscordReminders → 毎分トリガー
  • sendAllDayEventReminders → 毎日17:00〜18:00の間で実行

Apps Scriptのメニューから「トリガー」を開き,対応する関数に上記のスケジュールを設定すればOK.

コメントアウトを書いて軽く説明する.

// Discord Webhook URLここは自分でとってくる!
const webhookUrl = "https://discordapp.com/api/...";

function sendDiscordReminders() {
  // メインのGoogleカレンダーを取得
  var calendar = CalendarApp.getDefaultCalendar();

  // 現在時刻〜30分後までをチェック
  var now = new Date();
  var later = new Date(now.getTime() + 30 * 60 * 1000);
  var events = calendar.getEvents(now, later);

  // 対象のイベントごとに通知
  events.forEach(function(event) {

    // 終日イベントはスキップ
    if (event.isAllDayEvent()) return;

    var start = event.getStartTime();
    var diffMinutes = Math.floor((start.getTime() - now.getTime()) / 1000 / 60);
    var description = event.getDescription();

    // 説明がないイベントはスキップ
    if (!description || description.trim() === "") return;

    // ちょうど30分前のときだけ通知
    if (diffMinutes >= 29 && diffMinutes <= 30) {
      var embed = {
        title: "⏰ 30分後に説明ありの予定があります!",
        color: 3447003, //青🟦
        fields: [
          {
            name: "📌 タイトル",
            value: event.getTitle()
          },
          //時刻は30分後って分かってるからいらんと思ってコメントアウトにしてある
          /*
          {
            name: "🕒 開始時刻",
            value: start.toLocaleString()
          },
          */
          {
            name: "📝 説明",
            value: description
          }
        ]
      };

      var payload = { embeds: [embed] };

      UrlFetchApp.fetch(webhookUrl, {
        method: "post",
        contentType: "application/json",
        payload: JSON.stringify(payload),
        muteHttpExceptions: true
      });
    }
  });
}


function sendAllDayEventReminders() {
  var calendar = CalendarApp.getDefaultCalendar();
  // 現在の日時を取得
  var now = new Date();

  // 明日の日付を取得(時刻部分は0:00)
  var tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);

  // 明日の終日イベントを取得
  var events = calendar.getEventsForDay(tomorrow);

  events.forEach(function(event) {
    // 終日イベントのみ対象
    if (!event.isAllDayEvent()) return;

    var description = event.getDescription();

    // 説明がないイベントはスキップ
    if (!description || description.trim() === "") return;

    // 通知メッセージの内容
    var embed = {
      title: "🌙 明日は説明ありの終日イベントがあります!",
      color: 15844367, //黄色🟡
      fields: [
        {
          name: "📌 タイトル",
          value: event.getTitle()
        },
        {
          name: "📝 説明",
          value: description
        }
      ]
    };

    var payload = { embeds: [embed] };

    // Discordに送信
    UrlFetchApp.fetch(webhookUrl, {
      method: "post",
      contentType: "application/json",
      payload: JSON.stringify(payload),
      muteHttpExceptions: true
    });
  });
}

おしまい

Discord webhook URLをちゃんと取って,トリガーをちゃんと設定したら上手く動くはず. カレンダーの「説明欄」を活かすことで,ちょっとしたメモを逃さない快適なワークフローになる. 自動化はしあわせ