🐣
Googleカレンダーの翌週の休暇予定をSlackに通知する
背景・概要
有休をその当日に通知させるGASを作った後に、毎週金曜日に翌週の有休を通知させるGASも欲しくなりました。
急な有休までは把握できませんが、あらかじめ休日の予定を知っていると、予定が立てやすくなります。
Slack通知サンプル
■来週の有休をお知らせします
2023/05/09 (火):
【カレンダー1】【全休】全休:山田
2023/05/11 (木):
【カレンダー2】【午前休】午前休:鈴木
2023/05/10 (水):
【カレンダー2】【全休】全休:田中
【カレンダー3】【午後休】午後休:鈴木
GAS
- トリガーを毎日特定の時間に動くように設定してください。土日祝はスキップする設定になっています。
- 金曜日に通知されますが、金曜日が祝日の場合は木曜日に通知されます。
- カレンダーIDとSlackのWebhook URLを定数に設定してください。
- 複数のGoogleカレンダーを設定できます。
function postNextWeekHolidaySchedule() {
const today = new Date();
const dayOfWeek = today.getDay();
// 金曜日であれば通知を行う
if (dayOfWeek === 5 && isBusinessDay()) {
sendNextWeekHolidayNotifications();
}
// 木曜日であれば、明日(金曜日)が祝日かどうかをチェックし、祝日であれば通知を行う
else if (dayOfWeek === 4) {
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);
if (!isBusinessDay(tomorrow)) {
sendNextWeekHolidayNotifications();
}
}
}
function sendNextWeekHolidayNotifications() {
const calendarIds = [
"calendarId1を入れる",
"calendarId2を入れる",
"calendarId3を入れる"
]; // Add more calendar IDs here.
const slackWebhookUrl = "slackWebhookUrlを入れる";
let holidaysByDate = {};
for (const calendarId of calendarIds) {
const calendar = CalendarApp.getCalendarById(calendarId);
const today = new Date();
const startDate = new Date(today);
startDate.setDate(today.getDate() + 2); // Start from next Monday
const endDate = new Date(startDate);
endDate.setDate(startDate.getDate() + 6); // End on next Sunday
const events = calendar.getEvents(startDate, endDate);
for (let i = 0; i < events.length; i++) {
const title = events[i].getTitle();
const eventDate = events[i].getStartTime();
const dateString = Utilities.formatDate(
eventDate,
Session.getScriptTimeZone(),
"yyyy/MM/dd"
);
if (!holidaysByDate[dateString]) {
holidaysByDate[dateString] = {
dayOfWeek: getDayOfWeekString(eventDate.getDay()),
holidays: [],
};
}
holidaysByDate[dateString].holidays.push({
calendarName: calendar.getName(),
title: title,
});
}
}
const slackPayload = {
text: "■来週の休日をお知らせします\n",
link_names: 1,
};
for (const date in holidaysByDate) {
slackPayload.text += `\n${date} (${holidaysByDate[date].dayOfWeek}):\n`;
for (const holiday of holidaysByDate[date].holidays) {
if (holiday.title.includes("全休")) {
slackPayload.text += `【${holiday.calendarName}】【全休】${holiday.title}\n`;
} else if (holiday.title.includes("午前休")) {
slackPayload.text += `【${holiday.calendarName}】【午前休】${holiday.title}\n`;
} else if (holiday.title.includes("午後休")) {
slackPayload.text += `【${holiday.calendarName}】【午後休】${holiday.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 = 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 getDayOfWeekString(dayOfWeek) {
const days = [
"日",
"月",
"火",
"水",
"木",
"金",
"土",
];
return days[dayOfWeek];
}
Discussion