Slackへの出退勤を自動化する

Slack

あなたが勤める会社では、Slackで出退勤を管理していますか?

 フルリモートの会社の場合、Slackで出退勤を管理している会社は少なくないと思います。Slackでの出退勤管理は、クラウド労務管理サービス「Gozal」のような外部のWebサービスと連携すると、さらに便利に利用することができます。

 ただ、出退勤を入力し忘れてしまうケースも多く、フルリモートの会社で出退勤の入力忘れは、出勤していない扱いになってしまいます。普段通りに仕事していたにも関わらず、退勤入力をする際に出勤入力をしていないことに気づき、まるまる1日が無駄になってしまった人もいるかも知れません。

 そこで、Slackへのメッセージ入力を自動化するツールを作成しました。このツールを用いれば、指定した時間に(数分間のブレをあえて発生させ)、Slackの指定したチャンネルに対してメッセージを自動送信することができます。

 ツールは、VBS(VBScript)で開発しました。かつて、Windowsサーバー管理でよく用いられてたスクリプト言語ですが、今ではすっかり、Windows Powershellに置き換わってしまいました。ただ、今でも問題なくVBSは使えますし、エクセルマクロの経験があれば、VBSは簡単に理解できることでしょう。

 ツールのソースコードは、次のとおりです。

Option Explicit

'----------------------------------------
' 定数定義
'----------------------------------------
'ここに、メッセージの送信先のチャンネルのWebhookのURLをコピー
Private Const WEBHOOK_URL = "https://hooks.slack.com/services/〇〇〇"

'送信者の名前
Private Const USER_NAME = "〇〇太郎"

'送信者アイコンURL
Private Const USER_ICON = "https://ca.slack-edge.com/〇〇〇"

Private Const AttendTimeStart = 85500   '出勤    ( 08 時 55 分から 出勤入力開始)
Private Const AttendTimeEnd = 85800     '出勤    ( 08 時 58 分までに出勤入力終了)
Private Const BreakTimeStart = 120000   '昼休みはじめ( 12 時 00 分から 昼休みはじめ入力開始)
Private Const BreakTimeEnd = 120500     '昼休みはじめ( 12 時 05 分までに昼休みはじめ入力終了)
Private Const ResumeTimeStart = 125500  '昼休みおわり( 12 時 55 分から 昼休みおわり入力開始)
Private Const ResumeTimeEnd = 125800    '昼休みおわり( 12 時 58 分までに昼休みおわり入力終了)
Private Const LeaveTimeStart = 180200   '退勤    ( 18 時 02 分から 退勤入力開始)
Private Const LeaveTimeEnd = 180500     '退勤    ( 18 時 05 分までに退勤入力終了)

'Slackに送信するメッセージ
Private Const AttendMessage = "出勤しました"
Private Const BreakMessage = "昼休みに入ります"
Private Const ResumeMessage = "昼休みから戻りました"
Private Const LeaveMessage = "退勤しました"

'----------------------------------------
' 変数定義
'----------------------------------------
Private AttendExecuted                  '出勤済み
Private BreakExecuted                   '昼休みはじめ済み
Private ResumeExecuted                  '昼休みおわり済み

'----------------------------------------
' 処理開始
'----------------------------------------
'出勤時間を過ぎていれば、出勤済みフラグを立てる
If (AttendTimeEnd < NowTime()) Then
    AttendExecuted = True
Else
    AttendExecuted = False
End If

'昼休みはじめ時間を過ぎていれば、昼休みはじめ済みフラグを立てる
If (BreakTimeEnd < NowTime()) Then
    BreakExecuted = True
Else
    BreakExecuted = False
End If

'昼休みおわり時間を過ぎていれば、昼休みおわり済みフラグを立てる
If (ResumeTimeEnd < NowTime()) Then
    ResumeExecuted = True
Else
    ResumeExecuted = False
End If

'退勤時間を過ぎていれば、スクリプトは実行しない
If (LeaveTimeEnd < NowTime()) Then
    Call MsgBox("退勤時間を過ぎています。手動で入力してください。")
    WScript.Quit()
End If

'メイン処理を呼ぶ
Call Main()

'********************************************************************************
' 関数名:Main()
' 概要 :メイン処理
' 引数 :なし
' 戻り値:なし
'********************************************************************************
Sub Main()

    '出勤済みフラグが立っていないばあい
    If (AttendExecuted = False) Then
        ' 08 時 45 分から 09 時 00 分までの間のみ
        If ((AttendTimeStart <= NowTime()) And (NowTime() < AttendTimeEnd)) Then
            Call Preparation(NowTime(), AttendTimeEnd)
            AttendExecuted = True
        End If
    End If

    '昼休み休憩開始済みフラグが立っていないばあい
    If (BreakExecuted = False) Then
        ' 12 時 00 分から 12 時 15 分までの間のみ
        If ((BreakTimeStart <= NowTime()) And (NowTime() < BreakTimeEnd)) Then
            Call Preparation(NowTime(), BreakTimeEnd)
            BreakExecuted = True
        End If
    End If

    '昼休み休憩終了済みフラグが立っていないばあい
    If (ResumeExecuted = False) Then
        ' 12 時 45 分から 13 時 00 分までの間のみ
        If ((ResumeTimeStart <= NowTime()) And (NowTime() < ResumeTimeEnd)) Then
            Call Preparation(NowTime(), ResumeTimeEnd)
            ResumeExecuted = True
        End If
    End If

    If (LeaveTimeStart <= NowTime()) And (NowTime() < LeaveTimeEnd) Then
        ' 18 時 00 分から 18 時 15 分までの間のみ
        Call Preparation(NowTime(), LeaveTimeEnd)
        Exit Sub
    End If

    ' 1 分待機
    WScript.Sleep 60000

    '再帰呼び出し
    Call Main()

End Sub

'********************************************************************************
' 関数名:SendSlack()
' 概要 :Slackにメッセージを送信
' 引数 :[targetTime]...送信するメッセージの選別のため
' 戻り値:なし
'********************************************************************************
Sub Preparation(ByVal startTime, ByVal endTime)

    '開始時刻と終了時刻の差を求める
    Dim rangeValue
    rangeValue = endTime - startTime

    '開始時刻と終了時刻の差までの間で、ランダムな値を取得し、その分を待機時間とする
    Dim execTime
    Do
        Randomize
        execTime = endTime - Int((rangeValue - 0 + 1) * Rnd())

        Dim c
        c = Right("000000" + CStr(execTime), 6)

        Dim m
        m = CInt(Mid(c, 3, 2))
        Dim s
        s = CInt(Right(c, 2))

        '時刻(hhmmss)に変換できないものは処理しない
        If ((m < 60) And (s < 60)) Then
            Exit Do
        End If
    Loop

    'Slackに送信するメッセージを取得
    Dim msg
    msg = GetSlackMessage(endTime)

    'Slackにメッセージを送信するまで待機する
    Do
        If (execTime < NowTime()) Then
            Call SendSlack(msg)
            Exit Sub
        End If

        WScript.Sleep 1000
    Loop

End Sub

'********************************************************************************
' 関数名:GetSlackMessage()
' 概要 :Slackに送信するメッセージを返す
' 引数 :[endTime]...Slack送信終了時間
' 戻り値:なし
'********************************************************************************
Function GetSlackMessage(ByVal startTime)

    Dim ret
    ret = ""

    Select Case startTime
    Case AttendTimeEnd      '出勤
        ret = AttendMessage
    Case BreakTimeEnd       '昼休み休憩開始
        ret = BreakMessage
    Case ResumeTimeEnd      '昼休み休憩終了
        ret = ResumeMessage
    Case LeaveTimeEnd       '退勤
        ret = LeaveMessage
    Case Else
        Call MsgBox("プログラムエラー: 想定外の開始時間")
        WScript.Quit()
    End Select

    GetSlackMessage = ret

End Function

'********************************************************************************
' 関数名:SendSlack()
' 概要 :Slackにメッセージを送信する
' 引数 :[msg]...送信するメッセージ
' 戻り値:なし
'********************************************************************************
Sub SendSlack(ByVal msg)

    Dim json
    json = ""
    json = json & "{"
    json = json & "   ""username"": """ & USER_NAME & ""","
    json = json & "   ""icon_url"": """ & USER_ICON & ""","
    json = json & "   ""text"": """ & msg & """"
    json = json & "}"

    On Error Resume Next

    Dim req
    Set req = CreateObject("MSXML2.XMLHTTP")

    If (Err.Number <> 0) Then
        Call MsgBox(CStr(Err.Number) & ": " & Err,Description)
        Exit Sub
    End If

    With req
        .Open "POST", WEBHOOK_URL, False
        .SetRequestHeader "Content-Type", "application/json"
        .Send (json)
    End With

    If (Err.Number <> 0) Then
        Call MsgBox(CStr(Err.Number) & ": " & Err,Description)
        Exit Sub
    End If

End Sub

'********************************************************************************
' 関数名:NowTime()
' 概要 :現在時刻をhhmmssの数値型で返す
' 引数 :なし
' 戻り値:なし
'********************************************************************************
Function NowTime()

    Dim execTime
    NowTime = Hour(Now()) * 10000 + Minute(Now()) * 100 + Second(Now())

End Function

 事前に、メッセージの送信先となるチャンネルのWebhookのURLを知る必要があります。”Slack” “Webhook”辺りで検索してみてください。同様に、メッセージの送信者であるユーザーのアイコンを用意しておく必要があります。あくまで、メッセージを送信するのはWebhookであり、デスクトップでSlackを開いているユーザーではありません。そのため、メッセージを送信するユーザーの名前とアイコンを、ソースコード上で指定する必要があります。

 あとは、このVBSをダブルクリックして実行しておけば、指定した時間に

  • 出勤
  • 昼休み始め
  • 昼休み終わり
  • 退勤

が自動的にSlackに送信されます。

コメント

タイトルとURLをコピーしました