LoginSignup
4
1

More than 1 year has passed since last update.

Slack Outgoing Webhookでスプレッドシートに打刻する

Last updated at Posted at 2022-04-17

Slackで勤怠管理してみませんか?

私の職場ではSlackを使用しているのですが、「#greetings」というチャンネルに、出勤時と退勤時に挨拶(+勤務実績報告等)を書き込み、勤怠を管理しています。

しかし、各々の生活習慣から、毎日数分早く出社したり、また遅く帰ったり、ごく少数の時間ながら、残業時間が積み重なっていきがちです。

とはいえ、「昨日は10分残業したから、今日は10分早く帰ろう!」 などとするのは、いくら認められた権利とはいえ、何となく気まずいものです。そういった少しずつ積もった残業時間を正確に把握し、堂々と消化できるのが、こちらの勤怠管理システムになります。

同じような勤怠管理の形式をとっている職場にお勤めの際は、ぜひ使用してみてください!

作るシステムのイメージ

・勤怠報告専用のチャンネルがあり、いつも 「おはようございます」「お疲れ様です」 といったワードが飛び交います。 スタンプで挨拶をする人もいます。
image.png
image.png
・時折、離席する人もいます。
image.png
image.png

・それぞれの投稿において、特定のキーワード(おはよう、お疲れ)やスタンプに反応し、現在時刻をスプレッドシートに打刻してくれるようにします。
・さらに、『退勤』の項目が打刻されたら、勤務時間と残業時間を算出してくれるようにします。(私の職場は勤務時間が7時間30分となっているので、図の例では、残業時間は0となります。)

・月ごとの累計残業時間も計算してくれます。(こちらはスプレッドシートのSUMIF関数で導出しています。)

Outgoing Webhookの設定

・Slack側の設定は、「Outgoing Webhook」 を使用します。

①左上のハンバーガーメニューをクリックし、ファイル>設定と管理>App管理>カスタムインテグレーション を選択します。
image.png

②Outgoing Webhook>Slackに追加>Outgoing Webhookインテグレーションの追加 を選択します。

③設定画面を開くことができました。最初に、「Outgoingペイロードとレスポンス」を確認しておきましょう。(「開く」をクリック)。
こちらに表記されているデータはPOST送信され、後ほど使用することになります。
特に「token」「user_id」「trigger_word」は実際に使用します。

image.png

④チャンネル名、引き金となる言葉を設定します。
・「:おはようございます:」という表記がありますが、これはスタンプを表します。ホバーで確認できます。
・URLは後ほど設定します。
・トークンは後ほど使用します。変更する必要はありません。
image.png
image.png
・「名前をカスタマイズ」「アイコンをカスタマイズする」をお好みで設定したら、いったんSlackの準備は終了しますが、まだ設定は保存しないでください。 Googleスプレッドシートの設定がまだ終わっていないためです。

Googleスプレッドシートの設定

次にGoogleスプレッドシートの設定を行います。
ここでは 「Gas」(Google Apps Script) という言語で記述していきます。

①まずは新規シートを作成してください。
・タイトルは好きなものを設定してください。
・シート名は、SlackのユーザーIDにしてください。Slackの個人プロフィールで確認できます。
image.png

②拡張機能>Apps Script を選択します。
image.png

③タイトル、ファイル名をお好みで設定してください。当記事では「勤怠管理」「attendance.gs」とします。
image.png

④プロジェクトの設定>「appsscript.json」マニフェスト ファイルをエディタで表示する を選択し、チェックマークをいれます。
image.png

⑤エディターでappsscript.jsonは次のように記載します。
image.png

appsscript.json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "webapp": {
    "executeAs": "USER_DEPLOYING",
    "access": "ANYONE_ANONYMOUS"
  }
}

⑥テストコードとして、下記のように記載してください。
※詳しい文法は、別途調べてみてください。

attendance.gs
function doPost(e) {
  // xxxxxxxxxxxxxxxxxxxxxxxはURLを入力してください。
  const ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxxxxx"); 
  const sheet = ss.getSheetByName(e.parameter.user_id);

  const datetime = new Date();
  sheet.getRange(1,1).setValue(datetime);
  sheet.getRange(2,1).setValue('Post送信成功!');
  sheet.getRange(3,1).setValue(e.parameter.user_id);
  sheet.getRange(4,1).setValue(e.parameter.trigger_word);
  sheet.getRange(5,1).setValue(e.parameter.token);

  return;
}

⑦プロジェクトを保存し、デプロイ>新しいデプロイ を選択します。
image.png

⑧アクセスできるユーザー「自分のみ」を選択し、「デプロイ」ボタンを押します。(「自分のみ」の権限は変更してもOKです。)
image.png

⑨自分のGoogleアカウントでログインした後、詳細を表示>(安全ではないページ)に移動>許可 を選択します。
このあたりはこちらのページでも詳しく解説されています。
Google Apps Scriptでデプロイしてウェブアプリとして公開する方法【2021年更新】
image.png

⑩下記の画面が出れば完了です。そのままURLをコピーします。
このURLをSlackの設定に使用します。
image.png

⑪再び、Slackの「Outgoing Webhook」の設定に戻ります。(まだ設定は保存しないでください。 と記載した場所になります。)
URLに、先ほどデプロイしたアプリのURLを貼り付け、設定を保存します。
image.png
image.png

POST送信テスト

さて、テストコードは次のようになっていました。

attendance.gs
function doPost(e) {
  // xxxxxxxxxxxxxxxxxxxxxxxはURLを入力してください。
  const ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxxxxx"); 
  const sheet = ss.getSheetByName(e.parameter.user_id);

  const datetime = new Date();
  sheet.getRange(1,1).setValue(datetime);
  sheet.getRange(2,1).setValue('Post送信成功!');
  sheet.getRange(3,1).setValue(e.parameter.user_id);
  sheet.getRange(4,1).setValue(e.parameter.trigger_word);
  sheet.getRange(5,1).setValue(e.parameter.token);

  return;
}

実際に、Slackでトリガーワードの1つである 「出勤」 を含む投稿をしてみましょう。
image.png
すると、このように、スプレッドシートの中身が変わっていることが分かります。
無事にPOST送信が成功しました。
また、 3~5行目の様子から、POSTデータが「e.parameter」の中に配列で格納されていることが分かります。
image.png

オリジナルの勤怠管理シートを作成

さて、残るは実際に使用するプログラムを記述するのみですが、会社によって、もちろん勤務制度は異なりますので、そのままコピーすることは難しいかと思います。
サンプルを記載しておきますので、良ければアレンジしてみてください。

【サンプルの仕様】
スプレッドシート(ご自由にコピーしてお使いください)
・勤務時間は7時間半とする
・4時間以上勤務する場合、1時間の休憩が認められる
・社員は3名と仮定(社員の分だけシート数を用意します。)

attendance.gs
function doPost(e) {
  const ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxx/edit#gid=0"); 
  const sheet = ss.getSheetByName(e.parameter.user_id); // スプレッドシートのシート名もslackのuser_idにしておくこと
  const token = 'xxxxxxxxxxxxxxxxxxxx';

  if (token !== e.parameter.token) return; // token値が一致していない場合は打刻を行わない

  let category = e.parameter.trigger_word;

  const startArr = ['おはよう', ':おはようございます:']; // コロンで囲まれているものはSlackのスタンプを表す
  const finishArr = ['お疲れ', ':おつです:', ':お疲れさまです:'];
  if (startArr.indexOf(category) >= 0) category = '出勤';
  if (finishArr.indexOf(category) >= 0) category = '退勤';

  let lastRow = sheet.getLastRow();
  let addRow = lastRow;

  if (sheet.getRange(addRow, 7).isBlank() === false) addRow++; // 「退勤」に打刻されていれば、新しい行に追加する

  const datetime = new Date();
  let timeArr = {
    'year': datetime.getFullYear(),
    'month': datetime.getMonth() + 1,
    'date': datetime.getDate(),
    '出勤': sheet.getRange(addRow, 4).getValue(),
    '離席': sheet.getRange(addRow, 5).getValue(),
    '再開': sheet.getRange(addRow, 6).getValue(),
    '退勤': sheet.getRange(addRow, 7).getValue(),
  };

  // 例:8時→08の後ろから2文字,17時→017の後ろから2文字
  timeArr[category] = (('0' + datetime.getHours()).slice(-2) + ':' + ('0' + datetime.getMinutes()).slice(-2));

  // 列番号を割り振らないと、シートに書き込みができないため。
  array = [[timeArr['year'],timeArr['month'],timeArr['date'],timeArr['出勤'],timeArr['離席'],timeArr['再開'],timeArr['退勤']]];
  sheet.getRange(addRow,1,1,7).setValues(array); // 行番号,列番号,行数,列数

  // 「退勤」に打刻されていれば、勤務時間・残業時間を計算する
  if (category === '退勤') {

    let workingHours = (Number(timeArr['退勤'].slice(0,2)) - Number(timeArr['出勤'].slice(0,2)) + Number(timeArr['再開'].slice(0,2)) - Number(timeArr['離席'].slice(0,2)));
    let workingMinutes = (Number(timeArr['退勤'].slice(-2))- Number(timeArr['出勤'].slice(-2))+ Number(timeArr['再開'].slice(-2))- Number(timeArr['離席'].slice(-2)));

    if (workingHours >= 4) workingHours--; // 4時間以上勤務していれば、昼休み1時間を付与
    if (workingMinutes < 0) {
      workingHours--;
      workingMinutes += 60;
    };

    timeArr['実勤務時間'] = ('0' + workingHours.toString()).slice(-2) + ':' + ('0' + workingMinutes.toString()).slice(-2);
    timeArr['残業時間'] = workingHours * 60 + workingMinutes - 450; // 残業時間=実勤務時間ー7時間半(450分)
    sheet.getRange(addRow,8,1,2).setValues([[timeArr['実勤務時間'], timeArr['残業時間']]]); // 行番号,列番号,行数,列数
  }

  return;
}

おわりに

以上で 「Slack Outgoing Webhookでスプレッドシートに打刻する」 の解説を終わります。
ぜひとも皆さんの職場でも導入し、勤務の手助けになれば幸いです。

4
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1