使用 Shell Script 加 SleepWatcher 實現上下班自動打卡功能


#Mac#NUEiP#自動打卡#Shell Script

去年有寫一個 Laravel 專案用排程實現公司使用的打卡系統自動打卡的功能,但缺點是上下班卡的時間與 latlng 太固定,雖可以做些 Rand 微調,但可能與實際上下班時間還是有差異。

https://github.com/MTsung/nueip_auto_clock_in

於是又再寫了一隻 Shell Script 讓 Mac 在休眠與喚醒時進行打卡動作,也確保本人在公司,避免有爭議。

SleepWatcher


SleepWatcher 是一個 Mac 的應用程式,可以讓你 Mac 在休眠與喚醒時執行 Shell Script。

使用 brew 安裝,若沒 brew 請執行 (brew 需安裝一段時間,需耐心等待)。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 

安裝 SleepWatcher

brew install sleepwatcher

執行與設定啟用開機自動執行

brew services start sleepwatcher

休眠時會執行 ~/.sleep

喚醒時會執行 ~/.wakeup

問題思考


如果真的休眠與喚醒時就執行上下班打卡動作,那整天不就可能一堆上下班紀錄!那可不行,這時候就有兩點需要判斷:

  1. IP,判斷是否連接公司 Wi-Fi,不是的話代表不在公司不需要打卡。
  2. 時間,判斷是否早於設定上班打卡時間、晚於下班打卡時間,不是的話那就還在上班中。

Shell Script


IP 判斷邏輯

ip="$(curl ifconfig.me)"

if [ $ip = "59.124.13.252" ]; then
    echo "IP 在公司"
else
    echo "IP 不在公司"
fi

上班時間判斷

now="$(date '+%Y-%m-%d %H:%M:%S')"
clockInTime="$(date '+%Y-%m-%d 08:00:00')"

t1=$(date -j -f "%Y-%m-%d %H:%M:%S" "$now" "+%s")
t2=$(date -j -f "%Y-%m-%d %H:%M:%S" "$clockInTime" "+%s")

if [ $t2 -ge $t1 ]; then
    echo "早安~在紛亂的世界中願你有一顆寧靜的心"
else
    echo "上班時間已經過了"
fi

下班時間判斷

now="$(date '+%Y-%m-%d %H:%M:%S')"
clockOutTime="$(date '+%Y-%m-%d 16:00:00')"

t1=$(date -j -f "%Y-%m-%d %H:%M:%S" "$now" "+%s")
t2=$(date -j -f "%Y-%m-%d %H:%M:%S" "$clockOutTime" "+%s")

if [ $t1 -ge $t2 ]; then
    echo "好耶下班了"
else
    echo "下班時間還沒到"
fi

剩下就是一些 curl 的執行,不多說明。

最後寫了一隻安裝用的 Shell Script 就大功告成了

使用方式 

sh ./neuip_auto_clock_in.sh {company_id} {user_id} {user_pwd} {ckick in time(08:00:00)} {ckick out time(16:00:00)}
#!/bin/bash
#sh ./neuip_auto_clock_in.sh {company_id} {user_id} {user_pwd} {ckick in time(08:00:00)} {ckick out time(16:00:00)}

command -v brew > /dev/null 2>&1 || { 
    echo "install brew...";
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 
}

brew list | grep sleepwatcher > /dev/null 2>&1 || { 
    echo "install sleepwatcher...";
    brew install sleepwatcher
}

brew services | grep 'sleepwatcher started' > /dev/null 2>&1 || { 
    echo "start sleepwatcher...";
    brew services start sleepwatcher
}

if [ ! -d ~/.neuip ]; then
    echo "mkdir neuip...";
    mkdir ~/.neuip
fi

echo "#\!/bin/bash

echo \"start: \$(date '+%Y-%m-%d %H:%M:%S')\" >> ~/.neuip/clock_out_log

ip=\"\$(curl ifconfig.me)\"

if [ \$ip = \"59.124.13.252\" ]; then
    now=\"\$(date '+%Y-%m-%d %H:%M:%S')\"
    clockOutTime=\"\$(date '+%Y-%m-%d $5')\"

    t1=\$(date -j -f \"%Y-%m-%d %H:%M:%S\" \"\$now\" \"+%s\")
    t2=\$(date -j -f \"%Y-%m-%d %H:%M:%S\" \"\$clockOutTime\" \"+%s\")

    if [ \$t1 -ge \$t2 ]; then
        echo \"好耶下班了\" >> ~/.neuip/clock_out_log

        inputCompany=$1
        inputID=$2
        inputPassword=$3

        curl -i -X POST -H \"Content-Type: multipart/form-data\" \\
           -F \"inputCompany=\$inputCompany\" \\
           -F \"inputID=\$inputID\" \\
           -F \"inputPassword=\$inputPassword\" \\
           -c ~/.neuip/neuip_cookie \\
           https://cloud.nueip.com/login/index/param

        neuip_token=\"\$(curl https://cloud.nueip.com/home -i \\
           -b ~/.neuip/neuip_cookie \\
           | sed -rn 's@(^.* name=\\\"token\\\" value=\\\")(.*)(\\\">)@\2@p' \\
           | cut -c 1-64 \\
           )\"

        neuip_token=\"\$(echo \${neuip_token:0:64})\"

        curl -i -X POST -H \"Content-Type: multipart/form-data\" \\
           -F \"action=add\" \\
           -F \"id=2\" \\
           -F \"attendance_time=\$(date '+%Y-%m-%d %H:%M:%S')\" \\
           -F \"token=\$neuip_token\" \\
           -b ~/.neuip/neuip_cookie \\
           https://cloud.nueip.com/time_clocks/ajax >> ~/.neuip/clock_out_log
    else
        echo \"下班時間還沒到\" >> ~/.neuip/clock_out_log
    fi
else
    echo \"IP 不在公司\" >> ~/.neuip/clock_out_log
fi
" > ~/.sleep

chmod 777 ~/.sleep

echo "#\!/bin/bash

echo \"start: \$(date '+%Y-%m-%d %H:%M:%S')\" >> ~/.neuip/clock_in_log

ip=\"\$(curl ifconfig.me)\"

if [ \$ip = \"59.124.13.252\" ]; then
    now=\"\$(date '+%Y-%m-%d %H:%M:%S')\"
    clockInTime=\"\$(date '+%Y-%m-%d $4')\"

    t1=\$(date -j -f \"%Y-%m-%d %H:%M:%S\" \"\$now\" \"+%s\")
    t2=\$(date -j -f \"%Y-%m-%d %H:%M:%S\" \"\$clockInTime\" \"+%s\")

    if [ \$t2 -ge \$t1 ]; then
        echo \"早安~在紛亂的世界中願你有一顆寧靜的心\" >> ~/.neuip/clock_in_log

        inputCompany=$1
        inputID=$2
        inputPassword=$3

        curl -i -X POST -H \"Content-Type: multipart/form-data\" \\
           -F \"inputCompany=\$inputCompany\" \\
           -F \"inputID=\$inputID\" \\
           -F \"inputPassword=\$inputPassword\" \\
           -c ~/.neuip/neuip_cookie \\
           https://cloud.nueip.com/login/index/param

        neuip_token=\"\$(curl https://cloud.nueip.com/home -i \\
           -b ~/.neuip/neuip_cookie \\
           | sed -rn 's@(^.* name=\\\"token\\\" value=\\\")(.*)(\\\">)@\2@p' \\
           | cut -c 1-64 \\
           )\"

        neuip_token=\"\$(echo \${neuip_token:0:64})\"

        curl -i -X POST -H \"Content-Type: multipart/form-data\" \\
           -F \"action=add\" \\
           -F \"id=1\" \\
           -F \"attendance_time=\$(date '+%Y-%m-%d %H:%M:%S')\" \\
           -F \"token=\$neuip_token\" \\
           -b ~/.neuip/neuip_cookie \\
           https://cloud.nueip.com/time_clocks/ajax >> ~/.neuip/clock_in_log
    else
        echo \"上班時間已經過了\" >> ~/.neuip/clock_in_log
    fi
else
    echo \"IP 不在公司\" >> ~/.neuip/clock_in_log
fi
" > ~/.wakeup

chmod 777 ~/.wakeup

ps aux | grep sbin/sleepwatcher | grep -v grep > /dev/null 2>&1 && { 
    echo "ok.";
} || {
    echo "fail.";
}

參考:
https://fuzhii.com/2017/10/09/Mac-sleepwatcher