LINE Thingsをはじめて試しつつ、LIFFで打刻する

LINEBot&Clova Advent Calendar 2018 の17日目の投稿です。

先日、LINE DEVELOPER DAY2018に参加させていただきました。そのときに発表されたLINE Thingsに興味を持ちました。LINE Thingsプロダクトを実際に作ってみて試しつつ、打刻（タイムカード）したいと思います。

# 背景

弊社はコアタイムあり、リモートワークありのフレックスを採用している会社で、勤怠管理はエクセル（レガシー）だったり、上司、各自の自己申告でありました。
徐々に社員が増えていき、ひとりひとりチェックするのが結構つらくなってきたのもありますし、会社のシステムを整備していこうということで、今年の10月からAlexa,Clovaを使って打刻できる仕組みを導入しました。

しかし、スピーカーの前で渋滞したり、つい打刻を忘れたりすることが多く、後日「昨日の１０時に打刻お願いします」「了解」「管理画面で修正」的なやりとりがあって、結果的に仕事が減らいない状況です。

そこで、LINE APIを活用してこの問題を解決したいと思いました。
実は、先月からobnizをセントラル、ネイティブアプリをペリフェラルという構成で入退室時に打刻する仕組みを導入していますが、これに置き換えるものとして、LINE Thingsを使って打刻を実現したいと思います。（LINE APIはすごいよ、というのを社内に向けてアピールしたい思いがありましたw)

# 目標
+ ひとまずLINE Thingsを使ってLINEアプリとデバイスをBLEで接続する
+ LIFFを起動し、デバイスをBLEで接続できたら打刻ボタンを押してもらって、APIにPOSTして打刻する

# LINE Thingsとは？

ここに詳しく書かれています。
https://developers.line.biz/ja/docs/line-things/

ひとことでいうと、LIFFからBLEを使ってIoTデバイスに接続し、Read,Write,Notifyができるようになります。

# ハンズオンをやってみる

https://qiita.com/hktechno/items/bb83cc898c75819b2664
このハンズオンを参考に、LINEとESP32をつないでみたいと思います。

ボードはESP-32 NodeMCUを使います。
https://amzn.to/2Gfvalm

## LINE BotとLIFF
LINE Botを作って、LIFFを登録します。
[LINE Things Starter](https://github.com/line/line-things-starter/tree/master/liff-app)を使わせていただきます。

```
curl -XPOST \
-H 'Authorization: Bearer {MY ACCESS TOKEN}' \
-H "Content-Type: application/json" \
-d '{
    "view": {
        "description": "liff-ble-test",
        "type": "tall",
        "url": "https://makeitfun.jp/liff-ble-test/liff-app/index.html"
    },
    "features": { "ble": true }
}' \
https://api.line.me/liff/v1/apps
```

ble:trueが大事です。bleパーミッションです。書き忘れると次のLINE Thingsプロダクト作成APIでエラーになります。
"features": { "ble": true }

次にLINE Thingsプロダクトを作ります。プロダクト作成用のAPIにPOSTするだけです。
LINE Things Starterのliff-appのserviceUuidをレスポンスのserviceUuidに書き換えておきます。

レスポンス

```
{
  "id": XXXXXXXXX,
  "name": "liffbletest}",
  "actionUri": "{line://app/XXXXXXXXX}",
  "channelId": XXXXXXXXX,
  "type": "BLE",
  "serviceUuid": "{serviceUuid}",
  "psdiServiceUuid": "{psdiServiceUuid}",
  "psdiCharacteristicUuid": "{psdiCharacteristicUuid}"
}
```

## Arduino IDEからボードに書き込み

https://github.com/line/line-things-starter/blob/master/esp32/README.ja.md
ここを参考にセットアップします。

こんな感じになります。
<img width="303" alt="スクリーンショット 2018-12-15 23.18.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/103426/564b4a05-510f-2783-281e-083d70b22a42.png">

次にこのサンプルコードのserviceUuidを先程LINE Thingsプロダクト作成時に取得したserviceUuidに
書き換えてボードに書き込みます。
https://github.com/line/line-things-starter/blob/master/esp32/arduino/sample/sample.ino

## LINEとESP32を連携

LINEアプリ設定画面のLINE Thingsというメニューをタップすると連携可能なデバイスにLINE Thingsプロダクトが表示されます。 タップして進みます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/103426/d964b415-7619-5f74-eb3a-7a9c69332c90.png" width="20%">
<img src="https://qiita-image-store.s3.amazonaws.com/0/103426/3e242645-4629-2a3a-5707-4f3d392c143c.png" width="20%">
<img src="https://qiita-image-store.s3.amazonaws.com/0/103426/383841f8-6194-fcfe-5e25-848778954f4d.png" width="20%">
<img src="https://qiita-image-store.s3.amazonaws.com/0/103426/112a3f79-531a-c0b6-830f-89c56e8773eb.png" width="20%">

そして、LIFFが起動します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/103426/3b1a8422-2002-3d9d-7938-53a859febf4a.png" width="20%">

念願のLチカまでいけました！！！感動！


![2018-12-15 23.24.59.jpg](https://qiita-image-store.s3.amazonaws.com/0/103426/1798889d-9d5e-da76-919c-c8ea48b02835.jpeg)
![2018-12-15 23.25.18.jpg](https://qiita-image-store.s3.amazonaws.com/0/103426/bfb91515-14d4-6629-13ab-c55ce1e3dbda.jpeg)


# ここから打刻します

## LIFFを作成

LINE Things Starterのliff-appをベースに修正します。

打刻したことをグループLINEに通知しつつ、LambdaにPOSTして時刻を登録します。

```
    var employee = document.getElementById("employee");
    if (employee){
      timePost(employee.value);
    }
    return;
```



```
function timePost(data){

    var xhr = new XMLHttpRequest();    
    xhr.open("POST", "https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod");
    
    xhr.addEventListener("progress", function(){});
    xhr.addEventListener("load", function(evt){

        if (event.target.status == 200){

            liff.sendMessages([
            {
                type:'text',
                text: data + "さんが打刻しました"
            },
            {
                type:'text',
                text: getCurrentTime()
            }

            ])
            .then(() => {
                console.log('message sent');

                setTimeout(function(){
                    liff.closeWindow();
                },600);

            })
            .catch((err) => {
                alert("スイマセン！打刻できませんでした！");
                console.log('error', err);
            });



        }else{
            alert("スイマセン！打刻できませんでした！");
        }

    });
    xhr.addEventListener("error", function(){alert("スイマセン！打刻できませんでした！");;});
    xhr.addEventListener("abort", function(){});
    
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(data));
}
```

![2018-12-16 01.08.30.png](https://qiita-image-store.s3.amazonaws.com/0/103426/47ee6e21-8c2a-08b3-4aea-a8d9ad674257.png)

![2018-12-16 01.09.53.png](https://qiita-image-store.s3.amazonaws.com/0/103426/732fe1bd-2c2e-4dd7-dca2-5c0ace4377e9.png)

<img width="376" alt="スクリーンショット 2018-12-16 2.18.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/103426/9cb8b303-f869-f42d-a4f7-1ed65e025e6c.png">


LINE BOTのwebhookではなく、LIFFから直接POSTしてます。AIアシスタントからpostするgatewayをつかいまわします。


# まとめ

## リッチメニュー
いまのところ「打刻したい」と入力すると、LIFFのURLがReplyされますが、面倒なのでリッチメニューで表示したい。

## アカウント
メンバーを特定するために名前をテキスト入力していますが。LINE IDとアカウント情報を紐づけておけば名前を入力しなくても特定が可能かなと。マルチペアリングなども含め実運用に向けての課題がある。

## 自動BLE通信
Automated BLE Communicationという機能が2019年に実装されるそうなので、取り込みたい。
入室、退室するだけで打刻できるのは便利です。

## サービス化
意外と需要があるのではないかと期待して。