はじめに
動機づけ
いちいち出勤・退勤時刻を記録するのが面倒なので、ShellスクリプトとGASを使用して自動化してしまいます。
方法
- GAS上にWeb APIを用意し、HTTPリクエストを飛ばすと時刻が記録される口を作ります。
- Mac側でshellスクリプトを定期実行して、職場のWi-Fiに接続していれば、上記APIを叩きに行きます。
- 一日の終わりに記録を集計し、出勤時刻、退勤時刻、滞在時間を計算します。
Macでの定期実行は、Linuxによくあるcronではなくlaunchdを使用するようです。
実行環境
- MacOS Sierra 10.12.2
GASスクリプト
ちょっとした準備
スクリプトのプロパティに下記のプロパティを設定します。
-
FILENAME
: 勤怠記録をつけるGoogleスプレッドシートの名前。事前にGoogleドライブにファイルを作成しておく。 -
SHEET_1st
: 集計前の生データを記録しておくシート名。「シート1」でOK -
SHEET_2nd
: 集計後のデータを記録しておくシート名。「シート2」でOK
Moment.jsを使えるように設定します。外部ライブラリとして導入してもよし、ソース丸コピで突っ込んでもよし。
参考:日付&時刻の便利ライブラリ「Moment.js」をGoogle Apps Scriptで使う方法
その他
-
summarize
関数に時間ベーストリガーを設定。 - Webアプリとして公開しておく。(下の定期実行シェルにURLを記載する)
説明など
-
doGet
関数 :GET
リクエストを受けた時の処理。受けた時刻をスプレッドシートにappend
しているだけです。 -
summarize
関数 : 時間ベーストリガーで毎日1:00-2:00に実行してあげると、前日の最初〜最後の時刻抽出、出勤時刻・退勤時刻・滞在時刻の計算、計算データのappendを実行します。
main.js
// -----------------------------------------------------------------------------
// GETのハンドラ
// -----------------------------------------------------------------------------
function doGet() {
try {
var sp = PropertiesService.getScriptProperties();
var FILENAME = sp.getProperty("FILENAME");
var SHEET_1st = sp.getProperty("SHEET_1st");
var date = new Date();
var ss = getSpreadsheetByName(FILENAME);
var sheet = ss.getSheetByName(SHEET_1st);
sheet.appendRow([date]);
return createContent({status: 'OK'});
} catch(err) {
return createContent({status: 'NG'});
}
}
// -----------------------------------------------------------------------------
// スプレッドシート取得メソッド
// -----------------------------------------------------------------------------
function getSpreadsheetByName(filename) {
var fileIter = DriveApp.getFilesByName(filename);
if (fileIter.hasNext()) {
var file = fileIter.next();
return SpreadsheetApp.open(file);
} else {
throw FileError("File Not Found.")
}
}
// -----------------------------------------------------------------------------
// 返却データの生成
// -----------------------------------------------------------------------------
function createContent(res) {
return ContentService.createTextOutput(JSON.stringify(res))
.setMimeType(ContentService.MimeType.JSON);
}
// -----------------------------------------------------------------------------
// 昨日のデータをサマライズ(1:00-2:00に実行)
// -----------------------------------------------------------------------------
function summarize() {
var sp = PropertiesService.getScriptProperties();
var FILENAME = sp.getProperty("FILENAME");
var SHEET_1st = sp.getProperty("SHEET_1st");
var SHEET_2nd = sp.getProperty("SHEET_2nd");
var ss = getSpreadsheetByName(FILENAME);
var sheet1st = ss.getSheetByName(SHEET_1st);
var rows = sheet1st.getDataRange().getValues();
var FORMAT = "YYYY/MM/DD";
var yesterday = moment().subtract("days", 1).startOf('day');
rows = rows.filter(function(row) {
return moment(row[0]).format(FORMAT) == yesterday.format(FORMAT);
});
if (rows.length == 0) return;
var entrDay = moment(rows[0][0]);
var exitDay = moment(rows[rows.length-1][0]);
var diff = exitDay.diff(entrDay, "hours", true);
var sheet2nd = ss.getSheetByName(SHEET_2nd);
sheet2nd.appendRow([yesterday.toDate(), entrDay.toDate(), exitDay.toDate(), diff, diff-1])
sheet1st.deleteRows(1, rows.length);
}
定期実行シェル
--------------------ー
airport
コマンドで取得したWi-Fi接続情報をgrep
やらsed
やらを使用して整形し、接続先のSSID名を抽出します。その後、職場のSSIDに一致した場合は前述のGASの口をcurlで叩きます。
attrec.sh
#!/bin/bash
SSID=your_office_ssid
GASURL=https://script.google.com/macros/s/your_script_id/exec
AIRPORT=/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
CURRENT_SSID=`$AIRPORT -I | egrep "^\s+SSID:" | sed -e 's/ *SSID: //g'`
if [ $SSID = $CURRENT_SSID ]; then
curl $GASURL
fi
launchd
- Label: 登録する名前。任意。
- ProgramArguments: 実行コマンド等。
$HOME/.attrec/attrec.sh
にシェルが置いてある想定 - StartInterval: 実行間隔。10分おき(600[sec])の設定。
カスタマイズは、下記あたりを参考に。
参考:Mac(OS X)ではcronじゃなくてlaunchdでやる - Furudateのブログ
参考:Mac OS Xでlaunchdでcronのように定期実行するメモ - launchd.plistの作成とか - tweeeetyのぶろぐ的めも
attrec.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>jp.ryskiwt.attrec</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>$HOME/.attrec/attrec.sh</string>
</array>
<key>StartInterval</key>
<integer>600</integer>
</dict>
</plist>
インストール
シェルの配置とlaunchdへの登録。
mkdir -p $HOME/.attrec
vi $HOME/.attrec/attrec.sh
vi $HOME/Library/LaunchAgents/attrec.plist
Launchctl load $HOME/Library/LaunchAgents/attrec.plist
アンインストール
launchdからの登録解除とシェルの削除。
launchctl unload $HOME/Library/LaunchAgents/attrec.plist
rm -rf $HOME/.attrec