🐣

Googleカレンダーの翌週の予定をslackに通知する

2023/05/10に公開

背景・概要

毎週金曜日に、翌週の平日の予定をslackで通知させるGASです。
自分はカレンダーで日々のタスクを管理しているのですが、予定を大雑把に確認する目的で利用しています。

Slack通知のサンプル

※※※来週の予定※※※
■ 2023/05/08(月)
カレンダー1
【10:30-11:30】予定が入る
■ 2023/05/09(火)
カレンダー1
【10:30-11:30】予定が入る
カレンダー2
【09:30-15:00】予定が入る
【12:30-13:30】予定が入る
■ 2023/05/10(水)
カレンダー3
【00:00-00:00】予定が入る
【13:30-14:30】予定が入る
【13:30-14:30】予定が入る
【15:00-15:45】予定が入る
■ 2023/05/12(金)
カレンダー2
【12:30-13:30】予定が入る

GAS

  • トリガーを毎日特定の時間に動くように設定してください。土日祝はスキップする設定になっています。
  • カレンダーIDとSlackのWebhook URLを定数に設定してください。
function sendNextWeekHolidayNotifications() {
  const calendarIds = [
    "calendarId1を入れる",
    "calendarId2を入れる",
    "calendarId3を入れる"
  ]; // Add more calendar IDs here.
  const slackWebhookUrl = "slackWebhookUrlを入れる";


  const slackPayload = {
    "text": "※※※来週の予定※※※\n",
    "link_names": 1
  };

  const today = new Date();
  const nextWeekDates = getNextWeekBusinessDates(today);

  for (const date of nextWeekDates) {
    const dateStr = Utilities.formatDate(date, "JST", "yyyy/MM/dd");
    const dayOfWeek = ["(日)", "(月)", "(火)", "(水)", "(木)", "(金)", "(土)"][date.getDay()];
    const eventsByDate = [];

    for (const calendarId of calendarIds) {
      const calendar = CalendarApp.getCalendarById(calendarId);
      const calendarName = calendar.getName();
      const events = calendar.getEventsForDay(date);

      if (events.length > 0) {
        eventsByDate.push({calendarName, events});
      }
    }

    if (eventsByDate.length > 0) {
      slackPayload.text += `\n*■ ${dateStr}${dayOfWeek}*\n`;

      for (const eventInfo of eventsByDate) {
        slackPayload.text += `*${eventInfo.calendarName}*\n`;
        for (const event of eventInfo.events) {
          const title = event.getTitle();
          const start = event.getStartTime();
          const end = event.getEndTime();
          const startStr = Utilities.formatDate(start, "JST", "HH:mm");
          const endStr = Utilities.formatDate(end, "JST", "HH:mm");
          slackPayload.text += `【${startStr}-${endStr}】${title}\n`;
        }
      }
    }
  }

  if (slackPayload.text === "来週の予定\n") {
    return;
  }

  const options = {
    "method": "post",
    "contentType": "application/json",
    "payload": JSON.stringify(slackPayload)
  };
  UrlFetchApp.fetch(slackWebhookUrl, options);
}


function isBusinessDay(date) {
  if (!date) {
    date = new Date();
  }
  const dayOfWeek = date.getDay();

  // 土日は営業日ではない
  if (dayOfWeek === 0 || dayOfWeek === 6) {
    return false;
  }

  // 祝日は営業日ではない
  const calendar = CalendarApp.getCalendarById("ja.japanese#holiday@group.v.calendar.google.com");
  const holidays = calendar.getEventsForDay(date);
  if (holidays.length > 0) {
    return false;
  }

  // 営業日の場合はtrueを返す
  return true;
}


function checkWhenToSendNotification() {
  const today = new Date();
  const dayOfWeek = today.getDay();

  // 金曜日であれば通知を行う
  if (dayOfWeek === 5 && isBusinessDay(today)) {
    sendNextWeekHolidayNotifications();
  }
  // 木曜日であれば、明日(金曜日)が祝日かどうかをチェックし、祝日であれば通知を行う
  else if (dayOfWeek === 4) {
    const tomorrow = new Date(today);
    tomorrow.setDate(today.getDate() + 1);
    if (!isBusinessDay(tomorrow)) {
      sendNextWeekHolidayNotifications();
    }
  }
}

// 実行時に通知をチェックする条件を検証する関数を呼び出します
checkWhenToSendNotification();

function getNextWeekBusinessDates(today) {
  const nextWeekBusinessDates = [];
  const daysToAdd = 7 - today.getDay() + 1; // Add 1 to start from next Monday

  for (let i = 0; i < 5; i++) {
    const nextWeekDate = new Date(today);
    nextWeekDate.setDate(today.getDate() + daysToAdd + i);
    nextWeekBusinessDates.push(nextWeekDate);
  }

  return nextWeekBusinessDates;
}




GitHubで編集を提案

Discussion