GASでハーモス勤怠から出勤、退勤情報を取得し、チャットに通知する

全社員テレワークの弊社では、勤怠管理をハーモス勤怠(旧称:IEYASU勤怠)を利用しています。仕事を開始する際に、下の画面の「出勤」ボタンを押します。

ハーモス勤怠の画面

今まではGoogle Chatの方にも「業務を開始します」や「業務を終了します」といった連絡を入れてもらってました。

Googleチャットの「挨拶の部屋」


勤怠管理で出勤や退勤ボタンを押しているのに、チャットでも出勤や退勤の連絡をするのは非常に無駄ですが、これが無くなると、みんなが出勤している雰囲気が伝わらず、少し寂しく感じます。そこで、ハーモス勤怠で出勤や退勤を押したことをチャットボットで通知することにしました。

チャットボットで勤怠情報を通知する

少し無機質な感じにはなりましたが、無駄を省き、今、誰が出勤しているのかもわかるようになりました。
出勤、退勤ではなく、「チェックイン」「チェックアウト」と表記したのは、弊社は子育て中の社員が多いため、頻繁に中抜けなどをする場合もあるためです。

ハーモス勤怠の情報を取得する

ハーモス勤怠APIの情報は下記のサイトに掲載されています。
https://ieyasu.co/docs/api.html

私が参照した時点では、バージョンは1.0.6でした。

まずは、APIキーなどを変数に設定します。

const api_key = "xxxxxxxxxxxxx";//期限: 2022/09/11 15:42:34
const api_url = 'https://ieyasu.co/api/';
const company_name = 'xxxxxx';
let today = new Date();
let today_day = GetDate(today);
//15分前
let before15min_unix = today.getTime() - 900000; //ミリ秒
let before15min = new Date(before15min_unix);
//Google chat Webhook URL
const googlechat_webhook = 'https://chat.googleapis.com/v1/spaces/xxxxxxx';

1行目のapi_keyの変数には、ハーモスのAPIキーを設定します。

APIキーには有効期限があるため、期限を記載しています。有効期限が切れる前に新しいキーを発行して、書き換える必要があります。

APIキーを取得するには、ハーモス勤怠に管理者としてログインし、「システム管理」ー>「システム設定」の画面を開きます。
編集ボタンを押して、「API KEYの設定」の項目まで画面をスクロールします。
「API KEYの生成」ボタンを押すと、API KEYが生成されます。
ハーモスのヘルプページ
http://faq.ieyasu.co/kintai/8794/

2行目のapi_urlの変数は、「https://ieyasu.co/api/」が固定です。

3行目のcompany_nameの変数 会社ID

ハーモス勤怠にログインする時のURLの「https://ieyasu.co/xxxxx」のxxxxxの部分が入ります。

let today = new Date();
let today_day = GetDate(today);
//15分前
let before15min_unix = today.getTime() - 900000; //ミリ秒
let before15min = new Date(before15min_unix);

上記の部分は、今日の日時、15分前の日時を習得しています。
ハーモス勤怠のAPIには、情報を取りに行くことができても、出勤ボタンなどが押されたタイミングで、情報をプッシュしてもらうことはできません。
ですので、15分刻みに勤怠情報をハーモスに取りにくいようにしています。

GoogleチャットボットのWebhook URLを取得する

10行目に記載したgooglechat_webhookの変数には、GoogleチャットボットのWebhook URLを取得して記載します。
チャットツールはSlackやChatWorkなど色々ありますので、下記の記事を参照してください。

ハーモスの認証トークンを取得する

次にハーモスの認証トークンを取得する関数を書きます。
勤怠情報を取得したり、ユーザー情報を取得したりと、ハーモスのAPIには様々なAPIが用意されてますが、APIを利用するときに認証トークンが必要になりますので、最初に取得します

//ハーモスAPI 認証用Tokenの取得
function HrmosApiGetToken() {

  let headers = {
    'Authorization': 'Basic '+api_key,
    'Content-Type':'application/json'
  };
  let options = {
    'method' : 'get',
    "headers" : headers
  };
  let response = UrlFetchApp.fetch(api_url+company_name+'/v1/authentication/token', options);
  return JSON.parse(response);
}

認証用Tokenの取得 API 

15分刻みに打刻履歴の一覧を取得する

今から15分前までの打刻情報を取得します。
打刻情報を取得する関数は下記になります。

//ハーモスAPI 日付指定の打刻履歴の一覧
function HrmosApiGetDaily(token,from_d,to_d)
{
  let headers = {
    'Authorization': 'Token '+token,
    'Content-Type':'application/json'
  };
  let options = {
    'method' : 'get',
    "headers" : headers
  };
  let response = UrlFetchApp.fetch(api_url+company_name+'/v1/stamp_logs/daily/'+today_day+'?limit=100&from='+from_d+'&to='+to_d, options);
  return JSON.parse(response);
}

第1引数に、先程取得した認証トークンを渡します。
第2引数、第3引数に、15分前の日時と、現在の日時を渡し、その範囲の打刻情報を取得するようにします。
※1度に100件まで取得できます。弊社の場合は、15分間に100件以上の打刻をされることはないので、100件以上ある場合の処理は書いていません。

指定された日の日次勤怠データの一覧 取得API

日付のフォーマットを変換する

fromとtoで渡す日時のフォーマットに注意が必要です。
「2020-10-28T09:00:00.000+09:00」のような形で渡します。W3CDTFと呼ばれるフォーマットのようです。日付オブジェクトから変換する関数も作成しました。

//DateオブジェクトをW3CDTFフォーマットに変換 YYYY-DD-MMTHH:MM:SS+09:00
function SetDateFormat(date)
{
  return date.getFullYear()+'-'+(date.getMonth() + 1).toString().padStart(2, '0')+'-'+date.getDate().toString().padStart(2, '0')+ "T" + date.getHours().toString().padStart(2, '0') + ":" + date.getMinutes().toString().padStart(2, '0') + ":" + date.getSeconds().toString().padStart(2, '0')+'+09:00';

}

fromとto以外に、打刻情報を取得する日付も渡しています。
today_day変数に格納しています。こちらはシンプルに「2018-08-01」というフォーマットになります。

//Dateオブジェクトを日付だけ抽出 YYYY-DD-MM
function GetDate(date)
{
  return date.getFullYear()+'-'+(date.getMonth() + 1).toString().padStart(2, '0')+'-'+date.getDate().toString().padStart(2, '0');
}

チャット画面に表示する日付は、W3CDTFではなく、一般的な「2022-06-21 15:48:47」のような表示になりますので、その変換用の関数も用意します。

//Dateオブジェクトを日付と時間を表示 YYYY-DD-MM HH:MM:SS
function GetDateTime(date)
{
  return date.getFullYear()+'-'+(date.getMonth() + 1).toString().padStart(2, '0')+'-'+date.getDate().toString().padStart(2, '0')+' '+ date.getHours().toString().padStart(2, '0') + ":" + date.getMinutes().toString().padStart(2, '0') + ":" + date.getSeconds().toString().padStart(2, '0');
}

ユーザー一覧を取得するAPI

打刻情報を取得するAPIでは、ユーザー名は渡してくれず、ユーザーIDが返ってきます。
ユーザーIDから名前を参照するため、ハーモスAPIを利用してユーザー一覧を取得し、ユーザーIDとキーに、ユーザー名を値にした配列「user_array」を作成します。

function GetUserList(token)
{
  let headers = {
    'Authorization': 'Token '+token,
    'Content-Type':'application/json'
  };
  let options = {
    'method' : 'get',
    "headers" : headers
  };
  let response = UrlFetchApp.fetch(api_url+company_name+'/v1/users?limit=100', options);
  let userlist = JSON.parse(response);
  //console.log(userlist);
  let user_array = [];
  if(userlist.length){
    for ( var i = 0; i < userlist.length; i++ ) {
      user_array[userlist[i].id] = userlist[i].last_name + userlist[i].first_name;
    }
  }
  return user_array;
}

※100ユーザーまで取得できるように書いています。100名以上ユーザーがいる場合は、追加で処理を書く必要があります。また、このAPIは退社したユーザーもすべて取得してきますので注意してください。

ユーザー一覧 取得API

メインの処理

色々と関数を用意してきましたが、メインの処理は下記になります。

function myFunction() {
 //認証トークンの取得
  let token_object = HrmosApiGetToken();
  let to_d = SetDateFormat(today);
  let from_d = SetDateFormat(before15min);
  //勤怠情報の取得
  let hrmos_object = HrmosApiGetDaily(token_object.token,from_d,to_d);
  if(hrmos_object.length){
    //ユーザー一覧を取得
    let user_array = GetUserList(token_object.token);
    for ( var i = 0; i < hrmos_object.length; i++ ) {
      if(hrmos_object[i].user_id){
          let user_name = '未登録ユーザー';
          if(user_array[hrmos_object[i].user_id]){
            user_name = user_array[hrmos_object[i].user_id];
          }
          let created_datetime = GetDateTime(new Date(hrmos_object[i].created_at));
          let checkinout = '';
          if(hrmos_object[i].stamp_type == 1){
            checkinout = 'チェックイン';
          }else if(hrmos_object[i].stamp_type == 2){
            checkinout = 'チェックアウト';
          }else if(hrmos_object[i].stamp_type == 3){
            checkinout = '休憩開始';
          }else if(hrmos_object[i].stamp_type == 4){
            checkinout = '休憩終了';
          }
          let message = user_name +'さんは、'+created_datetime+'に'+checkinout+'しました。';
          let res = SendGoogleChatMessage(message);
      }
    }
  }
}

弊社の場合は、「出勤」「退勤」ボタンしかありませんが、「休憩開始」「休憩終了」ボタンを表示している場合のために、「休憩開始しました」「休憩終了しました」と表示されるようにしてあります。

休憩打刻についてのハーモスのヘルプ
https://faq.ieyasu.co/kintai/2386/

15分置きに実行するトリガーの設定

プログラムが完成したら、15分置きにプログラムを実行させます。
トリガー設定から下の図のように設定しましょう。

ソースコードのダウンロード

作成したソースコードを無料でダウンロードして頂けます。
ダウンロードしたテキストファイルに書かれたソースコードをGASのコード.gsにコピー&ペーストしてください。
1行目のハーモスのAPI KEY、3行目のハーモスの会社ID、11行目のGoogleチャットボットのWebhoookのURLの3箇所を書き換えて頂く必要があります。

    < 利用規約 >
    ダウンロードして頂いたソースコードなど(以下、「ダウンロードファイル」と呼ぶ)は無償で利用することができます。弊社は、ダウンロードファイルを利用されて生じた一切の損害について、その賠償義務を負いません。
    < 個人情報の取扱いについて >
    ご提供いただいた個人情報につきましては、下記の目的の範囲内で取り扱います。
    その他の取扱いについては当社のプライバシーポリシーに従います。

    ・お客さまの本人確認・与信管理
    ・当社のサービスまたは製品のご案内のため(電子メールによるものを含む)
    ・当社によるアンケート、各種セミナーのご案内、市場調査のため
    ・当社のサービス品質改善に向けた利用分析及び統計データ作成のため
    ・その他重要なご連絡のため