遅刻連絡サービスを作ってみた

  • 166
    いいね
  • 14
    コメント

はじめに

社内で「満員電車で携帯を取り出すことも困難な状態で、自動で遅刻の連絡をしてくれるサービスを作れないものか?」という話がちょっと上がったので、週末にコソコソと既存のサービス連携して作ってみました:hammer:

申し訳ありませんが、サービスの使い方とか連携部分とかは一番下の参考を見てみてください(とてもわかりやすくまとまっています:bow:
そしてこの記事の内容はあくまで遊びなので、激しい突っ込みは勘弁してください:cry:

仕様

  • 8時40分(ひとによりけり)に自分の位置情報を確認
  • 会社から1kmの範囲にいなかったら「すみません遅刻します!連絡もできない状況なので詳細は後ほど:innocent:」というメッセージをSlackに投げる。
    範囲内なら仕組みは一応動いているという確認のために「今日も仕事がんばれ:muscle:」というメッセージをSlackの自分専用チャンネルに投げる
  • 地下鉄通勤でも正常に通勤できていれば8時40分には地上に出ているはずという前提の仕様

全体構成

  1. Taskerで現在の自分の位置情報を取得、GoogleAppsScript(GAS)にPost
  2. GASは取得した位置情報をGoogleMapsDistanceMatrixAPIに投げて、会社との距離を計算してもらう。
  3. 計算結果を取得したらその結果からSlackWebApiを通してSlackに通知。

今回使用したもの

タスクとトリガーを組み合わせることで、いろんなことを実現できるAndroidアプリです。

有料ですが、自由度が高いためかなり遊べます。
今回はTaskerを使用しましたが、この遅刻報告サービスでは定時に位置情報を取得して(念のため更新をかけている)HttpPOSTをしているだけなので、他にも代替手段はあると思います。


  • ロジック処理

    • 処理スクリプト
      Google Apps Script
      Googleが提供するjavaScriptで簡単にWebApiをつくれるサービスです。
      こちらも自由度が高く(javascriptかけるので当たり前)とっても便利!
      SlackApp ライブラリなんてのも公開されていて(ありがたや:relaxed:)、簡単にSlackと連携が出来ます。

    • 距離の測定
      Google Maps Distance Matrix API
      GoogleMapのAPI。
      今回使ったのは緯度、経度で渡した2点間の距離を計算してくれるAPIです。 こんな結果を返してくれました。
{
    "destination_addresses": [
        "日本, 〒160-0023 東京都新宿区西新宿6丁目8−1"
    ],
    "origin_addresses": [
        "日本, 〒166-xxxx 東京都杉並区◯◯1丁目1−1"
    ],
    "rows": [
        {
            "elements": [
                {
                    "distance": {
                        "text": "5.8 km",
                        "value": 5777
                    },
                    "duration": {
                        "text": "1時間12分",//mode=walkingと設定したので歩いた場合の時間
                        "value": 4329
                    },
                    "status": "OK"
                }
            ]
        }
    ],
    "status": "OK"
}

ちょっと中身の紹介

Taskerのタスク

 

左: Taskの設定
以下の処理を submit_location というタスクに設定

  • 位置情報を更新(念のために)
  • 位置情報をlocationとしてパラメータにもたせてGASにHttpPOSTする

右: Taskの実行設定

  • 8時15分に submit_location を実行(失敗確認用)
  • 8時40分に submit_location を実行

GASのコード

postリクエストがあると doPost() が呼ばれます。
requestからlocationを取得し、GoogleMapsDistanceMatrixAPIに投げています。

// 会社の緯度経度
var OFFICE_LOCATION_LATITUDE = 35.6939314;
var OFFICE_LOCATION_LONGITUDE = 139.6905425;
var OFFICE_LOCATION = OFFICE_LOCATION_LATITUDE + ',' + OFFICE_LOCATION_LONGITUDE;

var GOOGLE_API_KEY = '[APIKey]';

var URL = 'https://maps.googleapis.com/maps/api/distancematrix/json?origins=[MY_LOCATION]&destinations=' + OFFICE_LOCATION + '&mode=walking&language=ja&key=' + GOOGLE_API_KEY;// language,modeは別に無くても良い

/**
* Postリクエストがここに来る
*/
function doPost(request) {
  try {
    var location = request.parameter.location;
    var url = URL.replace(/\[MY_LOCATION\]/g, location);
    var result = UrlFetchApp.fetch(url);
    var resultStr = result.getContentText();
    var metre = JSON.parse(resultStr).rows[0].elements[0].distance.value;

    // 1km以上離れていたら遅刻連絡
    if (metre > 1000) {
      sendMsgToSlack('test1', 'すみません遅刻します!連絡もできない状況なので詳細は後ほど:innocent:');
    } else {// 別チャンネルにメッセージをポスト
      sendMsgToSlack('test2', '今日も仕事がんばれ:muscle:');
    }
  } catch (e) {
    // エラーをslackに投げる
    sendErrorMsg(e);
  }
}

function sendMsgToSlack(ch, msg) {
  var token = PropertiesService.getScriptProperties().getProperty('SLACK_ACCESS_TOKEN');

  var slackApp = SlackApp.create(token); //SlackApp インスタンスの取得

  var options = {
    channelId: ch, //チャンネル名
    userName: "魚Bot", //投稿するbotの名前
    message: msg //投稿するメッセージ
  };

  slackApp.postMessage(options.channelId, options.message, {
    username: options.userName
  });

}

function sendErrorMsg(msg) {
  sendMsgToSlack('test2', 'エラーが発生したお:ng: \n' + msg);
}

結果

普通に通勤してみたところ、正常に動作しました:clap:

ng.png
ok.png

やったね٩( 'ω' )و

まとめ

こういうの楽しい!!
ここはこうしたら良いんじゃないかとかある方是非教えてください:grinning:

参考

以下、参考にさせて頂きました:bow: