[toioからあなたへ届け！] toio.js から LINE Notify ついでに英語のお勉強とPPAP召喚

この記事は LINEDC アドベントカレンダー12/24（木） のものでもあります。

・ LINEDC アドベントカレンダー

https://qiita.com/advent-calendar/2021/linedc

# toioからLINE Notify

なぜこのテーマにしたか？
単純にやってみたかったからです笑
あとtoio.jsを使ってみたかったのと、ついでにKONAMIコマンドを発火したかった！


# イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/230bf241-9471-5c7d-0823-cb3d10170bc2.png)


# toio.js

Node.jsを使って toio を操作できるアレです。

https://github.com/toio/toio.js/

サンプルが3つ入ってます。

- id-reader
- keyboard-control
- chase

どれも簡単に動かせるので、ちょっとした仕組みを理解するにはとても分かりやすいです。

# id-reader

今回は id-reader のサンプルに手を加えました。
id-readerは、toio専用「簡易カード」のマットのどの位置にキューブが置かれたか？がわかるので、キューブを置いた場所によって処理を変えられます。

こんな感じでキューブを置いた位置を検知できます。

```
[STD ID] { standardId: 3670320, angle: 95 }
[STD ID] { standardId: 3670321, angle: 100 }
[STD ID] { standardId: 3670322, angle: 174 }
```

ちなみに「開発用プレイマット」では以下のように取得できます。

```
[POS ID] { x: 124, y: 161, angle: 100, sensorX: 132, sensorY: 155 }
[POS ID] { x: 120, y: 197, angle: 88, sensorX: 127, sensorY: 189 }
[POS ID] { x: 119, y: 248, angle: 88, sensorX: 126, sensorY: 240 }
```

# 簡易カードマットの各マス目のIDを調べねば

ということで簡易カードマットのIDを地道にログで確認しようと思ったけど、そういえば公開されてました！素敵！

https://toio.github.io/toio-spec/docs/hardware_standard_id#:~:text=0x00380070-,toio%20%E3%82%B3%E3%82%A2%20%E3%82%AD%E3%83%A5%E3%83%BC%E3%83%96%EF%BC%88%E5%8D%98%E4%BD%93%EF%BC%89%E4%BB%98%E5%B1%9E%E3%81%AE%E7%B0%A1%E6%98%93%E3%82%AB%E3%83%BC%E3%83%89,-%23



# LINE Notifyの準備

無事にマス目ごとのIDを検知できるようになったので、LINE Notifyに通知を送れば良いのですが、そもそもLINE Notifyとは？

https://notify-bot.line.me/ja/

LINE Notifyを使うことで、何かをトリガーにLINEのトークルームへメッセージを通知することができます。通常のLINE botの場合、ユーザーからのメッセージに対して応答する形が基本ですが、Notifyを使うことでLINEが提供する公式アカウント"LINE Notify"から通知が届きます。

1 LINE Notifyにログイン

![スクリーンショット 2021-12-22 9.57.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/7cab5c7b-6dff-cc02-af90-232a36254ff9.png)

2 アクセストークンの発行

![スクリーンショット 2021-12-22 9.59.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/73a07455-6675-cbba-8427-c4ec0f5f466a.png)

3 トークン名と誰に通知を送るかを設定（グループに対する通知も可能）

![スクリーンショット 2021-12-22 9.59.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/f0fad4a2-32a2-e494-9c99-b805b2145357.png)

4 発行されたトークンをコピー

![スクリーンショット 2021-12-22 10.00.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/2c92efe0-5c33-f29d-49e6-f792eca57b06.png)


# id-readerでとりあえずNotify!

`${LINE_TOKEN}` は、上記で発行された文字列をセットします。

```id-reader/index.js
    .on('id:standard-id', data => {
      if (isTouched) {
        return;
      }
      isTouched = true;
      console.log('[STD ID]', data);

      const params = new URLSearchParams();
      params.append('message', data.standardId);

      axios(
        {
          method: 'post',
          url: 'https://notify-api.line.me/api/notify',
          headers: {
            Authorization: `Bearer ${LINE_TOKEN}`,
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          data: params,
        }
      ).then((res) => {
        console.log(res.data);
      }).catch((err) => {
        console.error(err);
      });
    })
```


簡易カードの「I」の位置にtoioキューブを置いたら、無事にNotifyが届きました！

![スクリーンショット 2021-12-22 10.33.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/f6be4631-ba57-9bd0-8b17-e58a0cb05f72.png)

# あとはIDごとに送信したいメッセージを設定

こんな感じで動きました。
対応するマス（ID）を読み込んだ時は音を鳴らすようにしてIDを貯めておいて、「=」 を読み込んだらNotifyを飛ばしてます。KONAMIコマンドも発動！

https://twitter.com/h2m_kinoko/status/1473650878095978506


・スタンプを送信する場合

パッケージ識別子(stickerPackagedId)とスタンプID（stickerId）を指定して送信。`message` パラメータは必須なので何かしら文字列をセットします。

https://developers.line.biz/ja/docs/messaging-api/sticker-list/#sticker-definitions

```
const params = new URLSearchParams();
params.append('message', "スタンプ");
params.append('stickerPackageId', 6325);
params.append('stickerId', Sticker6325[touchId]);
```

# 途中で知ったこと

`querystring` が `deprecated` になっていた。代わりに `URLSearchParams` を使うとのこと

https://www.npmjs.com/package/querystring

# 更新（英単語翻訳とPPAP召喚）

toioで読みとったアルファベット（英単語）を、Amazon Translate に投げて翻訳する機能を追加してみました。英語の勉強を楽しくできます。

ついでにPPAP召喚したくなったので召喚しました。

# イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/d64001dd-c76d-316f-c5e7-535c43b698b3.png)


# AWS側

Lambdaのランタイムは、Python3.7を指定。 toio.js から　API GatewayのAPIにリクエストし、`input` にtoioで読み取った英単語が入ってます。translateをかけて日本語にして返却。

```
import json
import boto3

translate = boto3.client('translate')

def lambda_handler(event, context):

    input = event['queryStringParameters']['input']

    response = translate.translate_text(
        Text=input,
        SourceLanguageCode='en',
        TargetLanguageCode='ja')
    
    output = response.get('TranslatedText')

    return {
        'statusCode': 200,
        'body': json.dumps({
            'output': output
        }),
        'isBase64Encoded': False,
        'headers': {}
    }
```

# こんな感じで動作

toioでAPPLEと読み込み、翻訳結果をNotify。ちゃんと「林檎」と翻訳されてますね。PENも同様に「ペン」と。
「PEN」+「PINAPPLE」+「APPLE」+「PEN」でPPAP召喚！


https://twitter.com/h2m_kinoko/status/1474597323200397312