はじめに
私の勤めている会社は退勤時にweb上で打刻、もしくは後で退勤時間を記載するという仕組みになっています。
その打刻するサイトのUIがあまりも使いにくく、さらに23時頃に退勤の日とかいちいちwebを開いて打刻するのが超めんどくさいのです。
そこで会社から離れたら自動的に打刻するシステムを作ろうと思ったのでレシピを下記に記述します。
前提条件
Node.jsがローカルPCに入っていること
npm or yarnがローカルPCに入っていること
会社の無線LANに接続できること(有線と同時接続でもOK)
googleApiに登録していること(無料。クレジットカード登録とかもいらない)
仕組み
PCのMACアドレスから現在地を特定して会社にいる場合は時間を記録し続けるという仕組み
作り方
googleApiは下記2つを使用する
Google Maps Geolocation API
Google Maps Geocoding API
googleApiに登録していてAPIキーを取得していれば2つともそのキーで下のソースのAPIを叩けるため特に意識することはないです。
mkdir worktimelog
cd worktimelog
mkdir timecard
mkdir logs
npm init
npm initの内容は適当でいいです。(一応サンプル載せます)
package name: worktimelog
version: (1.0.0) 1.0.0
description: worktimelog
entry point: (index.js) cron.js
test command: node cron.js
git repository:(エンターキー押してスキップしてください)
keywords: worktimelog
author: taisei_otsuka
npm init完了しましたら
npm install date-utils
npm install fs
npm install request
npm install wifi_location
vim cron.js
cron.jsの中身です。
#!/usr/bin/env node
require("date-utils");
const fs = require("fs");
const request = require('request');
const wifiLocation = require("wifi_location");
// googleApiのapiキー
const apikey = "apikey";
const date = new Date();
// logsまでの絶対パス
const logFile = "logsまでの絶対パス" + date.toFormat("YYYYMMDD") + "_log.txt";
// timecardまでの絶対パス
const timecardFile = "timecardまでの絶対パス" + date.toFormat("YYYYMMDD") + "_timecard.txt";
// 会社の郵便番号
const address = "000-0000";
const dateFormat = date.toFormat("YYYY-MM-DD HH24:MI");
const timeAndMemory = "time -> " + dateFormat + " memory -> " + process.memoryUsage().rss;
function writeLog(log) {
fs.appendFile(logFile, "\n" + log, function (err) {
if (err) {
throw err;
}
});
}
fs.access(timecardFile, fs.constants.R_OK | fs.constants.W_OK, (err) => {
if (err) fs.writeFile(timecardFile, date.toFormat("YYYY-MM-DD HH24:MI"));
});
fs.access(logFile, fs.constants.R_OK | fs.constants.W_OK, (err) => {
if (err) fs.writeFile(logFile, date.toFormat("ログを開始します。" + timeAndMemory));
});
wifiLocation.wifiTowers(function(err, obj) {
if (obj.length === 0) writeLog("MACアドレスを取得できませんでした。" + dateFormat);
let array = [];
obj.map((value) => {
delete value.ssid;
return array.push({macAddress:value.mac_address,signalStrength:value.signal_strength});
});
let optionsPost = {
url: "https://www.googleapis.com/geolocation/v1/geolocate?key=" + apikey,
method: "POST",
body: '{"considerIp": "false","wifiAccessPoints": ' + JSON.stringify(array) + '}',
headers: {
"Content-Type": "application/json"
},
};
request(optionsPost, (error, response, body) => {
if (!error && response.statusCode == 200) {
body = JSON.parse(body).location;
latlng = body.lat + "," + body.lng;
let optionsGet = {
url: "https://maps.googleapis.com/maps/api/geocode/json",
qs: {
latlng: latlng,
key: apikey
}
};
request(optionsGet, (error, response, body) => {
if (!error && response.statusCode === 200) {
let addressBool = false;
JSON.parse(body).results[0].address_components.map((value) => {
if (value.types[0] === "postal_code") addressBool = value.long_name === address;
});
if (addressBool) {
fs.writeFile(timecardFile, dateFormat);
writeLog("書き込みました。" + timeAndMemory);
}
}
});
}
});
});
はい、お気づきかと思いますがローカルpcでcronする必要があります。
*/15 0,18-23 * * 1-5 /usr/local/bin/node /hogehoge/worktimelog/cron.js /dev/null 2>&1
月~金の18時~0時までの間15分おきにcron.jsを実行しますという意味です。
cronの設定方法がわからない方は、foreverを使用しcronの処理をデーモン化してみてください。
npm install cron time
npm install forever -g
foreverとnpm cronの併用の場合の記述方法
const {CronJob} = require("cron");
new CronJob("*/15 0,18-23 * * 1-5", () => {
// ここに上記のcr....