<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Gas on Xainome Blog</title>
    <link>https://xainome-blog.pages.dev/tags/gas/</link>
    <description>Recent content in Gas on Xainome Blog</description>
    <generator>Hugo</generator>
    <language>ja-JP</language>
    <lastBuildDate>Sun, 03 Dec 2023 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://xainome-blog.pages.dev/tags/gas/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>GASを使って勤怠管理の提出を忘れないようにしたい！</title>
      <link>https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/</link>
      <pubDate>Sun, 03 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/</guid>
      <description>&lt;p&gt;皆さんは日々の作業の中で提出物などはありますか？&lt;/p&gt;
&lt;p&gt;私は月の初めの第1営業日、月の終わりから5営業日前、最終営業日に勤怠の提出があります。忘れがちな私はよく上司から提出していないと言われ、言う側も言われる側もストレスだと思い、Slackに通知が来るようなプログラムを組むことにしました。&lt;/p&gt;
&lt;p&gt;連携で使用したアプリは以下の2つになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;GAS(Google Apps Script)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Slack&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;やることは以下の順でやっていきます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Slackに通知するためのアプリ作成&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/#apps&#34;&gt;アプリの作成&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/#notice&#34;&gt;通知の設定&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/#work&#34;&gt;ワークスペースへのインストールとURL作成&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GASにコードを書いて日時実行の設定を行う&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/#code&#34;&gt;コードの作成&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/#trigger&#34;&gt;実行トリガーの作成&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;アプリの作成&lt;/p&gt;
&lt;p&gt;1つ目ですがまずはSlackのアプリ作成から始めます。&lt;a href=&#34;https://api.slack.com/apps&#34;&gt;こちら&lt;/a&gt;からアプリ作成ができます。リンク先に飛んだ後、赤枠の「Create New App」をクリックします。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2023-12-02-153025-wpp1701501782703.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;この画面が出たら赤枠の「From scratch」をクリックします。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2023-12-02-153040-wpp1701502071691.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;この画面が出たらアプリの名前と使用するワークスペースを設定します。仕事で使ってる人はワークスペースが所属している会社名になったりすると思います。設定が完了したら「Create App」をクリックします。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2023-12-02-153104-wpp1701502109236.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;通知の設定&lt;/p&gt;
&lt;p&gt;この画面になりますので「OAuth &amp;amp; Permissions」をクリックして、通知の設定をします。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2023-12-02-153407-wpp1701502138773.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;次に、Scopesでアプリに与える権限の設定を行います。「Add an OAuth Scope」をクリックし、「incoming-webhook」を選択します。今回は特定のチャンネル(自身のみ)通知を送る設定なのでこちらを選択します。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2023-12-02-155128-wpp1701501905755.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;ワークスペースへのインストールとURL作成&lt;/p&gt;
&lt;p&gt;同じタブで下の方にスクロールするとこの画面が出ますので「install to Workspace」をクリックします。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2023-12-02-155203-wpp1701501948122.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;次に、権限が求められますので投稿先を自身のチャンネルに設定して、「許可する」をクリックします。もし、他の人にも通知をしたい場合は、そのチャンネルに設定してください。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2023-12-02-155230-wpp1701501832629.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;これで通知に必要なURLを設定することができましたので、次はコードの作成に移ります。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2023/12/gas-attendance-management/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2023-12-02-155324-wpp1701502023177.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;コードの作成&lt;/p&gt;
&lt;p&gt;2つめのGASに関しては&lt;a href=&#34;https://qiita.com/ykhirao/items/782e20ab0465533c48f6&#34;&gt;こちら&lt;/a&gt;を参考にして作り、コードのきれいさを保つため、Chat-GPTに頼みました。1つ目の設定が終わったらwebhook URLをコード内に貼り付けます。&lt;/p&gt;
&lt;p&gt;もし、会社で特定の日が休日であればそこも考慮することができます。私は年末年始辺りの日付を入れてます。&amp;ldquo;specialHolidays&amp;quot;という変数に日付を入れていただけるとできます。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// Slackに特定の日の通知を送る関数
function documentAlert() {
  const today = new Date();
  // const today = new Date(&amp;#34;2023/12/22&amp;#34;); // テスト用: 

  const monthEnd5Date = getLastDateOfMonth(today);
  const monthEnd1Date = getLastDateOfMonth(today);
  const monthStartDate = new Date(today.getFullYear(), today.getMonth(), 1);

  sendNotificationIfDue(today, monthEnd5Date, -5, today+&amp;#34;、5営業日前になりました。見込み版勤怠の提出をお願いします。&amp;#34;);
  sendNotificationIfDue(today, monthEnd1Date, -1, today+&amp;#34;、最終営業日になりました。確定版勤怠の提出をお願いします。&amp;#34;);
  sendNotificationIfDue(today, monthStartDate, 1, today+&amp;#34;、第一営業日になりました。自社勤怠と交通費精算の提出をお願いします。&amp;#34;);
}

// 営業日計算関数
function dayCount(date, offsetDays) {
  let counter = 1;

  while (counter &amp;lt;= Math.abs(offsetDays)) {
    if (!isHoliday_(date)) counter++;
    if (counter &amp;gt; Math.abs(offsetDays)) break;
    date.setDate(date.getDate() + Math.sign(offsetDays));
  }
  return date;
}

// Slackに通知を送る関数
function slackSend(message) {
  const webhookUrl = &amp;#34;ワークスペースのWebhook URL&amp;#34;;
  
  const payload = {
    &amp;#34;text&amp;#34;: message
  };

  const options = {
    &amp;#34;method&amp;#34;: &amp;#34;post&amp;#34;,
    &amp;#34;muteHttpExceptions&amp;#34;: true,
    &amp;#34;contentType&amp;#34;: &amp;#34;application/json&amp;#34;,
    &amp;#34;payload&amp;#34;: JSON.stringify(payload)
  };

  UrlFetchApp.fetch(webhookUrl, options);
}

// 休日か否かを判定する関数
function isHoliday_(date) {
  if (isWeekend(date) || isHolidayEvent(date) || isSpecialHoliday(date)) {
    return true;
  }
  return false;
}

// 土日判定
function isWeekend(date) {
  const dayOfWeek = date.getDay();
  return dayOfWeek === 0 || dayOfWeek === 6;
}

// 祝日イベント判定
function isHolidayEvent(date) {
  const calendarId = &amp;#34;ja.japanese#holiday@group.v.calendar.google.com&amp;#34;;
  const events = CalendarApp.getCalendarById(calendarId).getEventsForDay(date);
  return events.length &amp;gt; 0;
}

// 特定の休日判定
function isSpecialHoliday(date) {
  const specialHolidays = [&amp;#34;0101&amp;#34;, &amp;#34;0102&amp;#34;, &amp;#34;0103&amp;#34;, &amp;#34;1229&amp;#34;, &amp;#34;1230&amp;#34;, &amp;#34;1231&amp;#34;];
  const formattedDate = Utilities.formatDate(date, &amp;#34;JST&amp;#34;, &amp;#34;MMdd&amp;#34;);
  return specialHolidays.includes(formattedDate);
}

// 月末最終日を取得する関数
function getLastDateOfMonth(date) {
  return new Date(date.getFullYear(), date.getMonth() + 1, 0);
}

// 特定の日に通知を送るためのヘルパー関数
function sendNotificationIfDue(today, baseDate, offsetDays, message) {
  const targetDate = dayCount(baseDate, offsetDays);
  if (isSameDay(today, targetDate)) {
    slackSend(message);
  }
}

// 二つの日付が同じ日か判定する関数
function isSameDay(date1, date2) {
  return date1.getDate() === date2.getDate();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行トリガーの作成&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
