toioとTwitterAPIを合わせて使ってみた

# toio.jsとTwitter APIを合わせて使ってみた
久しぶりの記事投稿。今回は[toio](https://toio.io/#four-attracts)をJavascriptで制御するのとTwitterAPIを合わせて使っていく。 

## toioとは
toioとはソニーインタラクティブエンタテインメントより発売されているロボットトイである。詳しくは公式サイトを見てほしいが、子供から大人まで楽しめるモノになっている。公式から[toio.js](https://github.com/toio/toio.js)というNode.js(サーバサイドで動くJavaScript環境)のライブラリが公開されているので今回をそちらを利用していく。 

## 今回やること
toioの最大の特徴は主役であるデバイスのキューブ(下図)の光学センサーを用いて、付属のマットやシールに施されている特殊印刷を読み取り、キューブの絶対座標やIDを取得できる点だ。 
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/61170182-d4d4-42aa-3290-a22e1647e037.png" width=70%>

今回はその絶対座標や各シールのIDを取得した後、TwitterAPIを介してそれらをTweetするのを目標とする。 
なおJavascriptを触るのは初めてなのであしからず。

## 環境構築 
環境構築は以下を行った。今回は手順は省く。 
- Node.js及びtoio.jsの環境構築([公式を参照](https://github.com/toio/toio.js))
- TwitterAPIの導入([参照記事](https://tasoweb.hatenablog.com/entry/2018/06/01/002438)) 
 
なおTwitterのアプリケーション作成方法はアップデート毎に変更されているようだ。3年前に一度Androidアプリ開発で触ったことがあったが、開発者アカウントの作成などは審査などが追加されており少々面倒くさくなっていた。 

## できたもの
今回はクラフトファイターの技カードのIDを識別してツイートする内容とした。(マットを使った座標は今後考えていく･･･) 
以下が機能である。 

- キューブはキーボードの矢印キーで走行可能 
- プログラム実行中は常にIDを取得し続ける 
- スペースキーを押すと現在のIDを利用してツイート文を判定・投稿  
   
以下はオートタックルのカードを認識している。 
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/66d04f5f-a291-97fe-7db6-c38222ded87d.jpeg" width=30%>
  
スペースキーを押すと何やら詳細情報がたくさん吐き出されてTwitterに投稿される。 
<img width="846" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/7d830e62-b236-7679-d1d5-068dfadca416.png">

以下が投稿結果  
<img width="501" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/d2153431-e6df-72f3-6f6b-1ea527a46fc8.png">
ちゃんと投稿できてる。 

投稿が完了するとプログラムは終了するようにした。
toioコンテンツ内の特殊印刷から得られるIDは[こちら](https://toio.github.io/toio-spec/docs/ble_id)の技術情報から参照できる。  

ちなみにもうひとつも(今度はタイフーン) 
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/6f35cb14-1bef-4390-8cdf-b0ab24b16478.jpeg" width=30%>　
ツイート！ 
<img width="845" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/c48490c8-93cb-640c-5075-a84330788e4b.png">
結果 
<img width="500" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/c6e401f7-0505-85fa-3c19-ebc795a5d57f.png">

 

## ソースコード 
~~~twio.js
const twitter = require("twitter");
const fs = require("fs");
const client = new twitter(JSON.parse(fs.readFileSync("secret.json", "utf-8")));
const keypress = require('keypress')
const { NearestScanner } = require('@toio/scanner')

const DURATION = 700 // ms
const SPEED = {
    forward: [70, 70],
    backward: [-70, -70],
    left: [30, 70],
    right: [70, 30],
}

//tweet
function tweet(sentence) {
    client.post('statuses/update', { status:sentence }, function (error, tweet, response) {
        if (!error) {
            console.log(tweet);
            console.log('tweet complete & program end')
            process.exit(0);
        } else {
            console.log('error');
            process.exit(1);
        }
    });
}

//make sentences from id_data
function make_sentence(id_data){
    var today = new Date();
    if(id_data === 3670016){
        out = 'Typhoon!'+ '\n' + today
    }else{
        if(id_data === 3670054){
            out = 'Rush!'+ '\n' + today
        }else{
            if(id_data === 3670018){
                out = 'Auto Tackle!'+ '\n' + today
            }else{
                if(id_data === 3670056){
                    out = 'Random!'+ '\n' + today
                }else{
                    if(id_data === 3670020){
                        out = 'Stab Power Up!'+ '\n' + today
                    }else{
                        if(id_data === 3670058){
                            out = 'Slapping Power Up!'+ '\n' + today
                        }else{
                            if(id_data === 3670022){
                                out = 'Side Attack!'+ '\n' + today
                            }else{
                                if(id_data === 3670060){
                                    out = 'Easy Mode!'+ '\n' + today
                                }else{
                                    out = 'not defined ID, ' + '\n' + 'ID : ' + id_data + '\n' + today
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}


//main
async function main() {
    // start a scanner to find nearest cube
    const cube = await new NearestScanner().start()

    // connect to the cube
    await cube.connect()
    console.log('cube connected')

    //tweet data initialize
    var id = []

    //get id data
    cube
      .on('id:standard-id', data => {id.unshift(data.standardId)})

    //move and tweet
    keypress(process.stdin)
    process.stdin.on('keypress', (ch, key) => {
        // ctrl+c or q -> exit process
        if ((key && key.ctrl && key.name === 'c') || (key && key.name === 'q')) {
            process.exit()
        }

        switch (key.name) {
            //space is id tweet
            case 'space':
                var value = id[0]
                console.log('Data get : ', value)
                make_sentence(value)
                console.log('Tweet : ',out)
                tweet(out)
                break
            case 'up':
                cube.move(...SPEED.forward, DURATION)                
                break
            case 'down':
                cube.move(...SPEED.backward, DURATION)
                break
            case 'left':
                cube.move(...SPEED.left, DURATION)
                break
            case 'right':
                cube.move(...SPEED.right, DURATION)
                break
        }
    })

    process.stdin.setRawMode(true)
    process.stdin.resume()

}

main()
~~~

いかにもJavascript初心者っぽいコーディングだがあしからず･･･ 
IDを判別して文章を決める大量のif else文をなんとかしたいが、何かいい方法はないだろうか･･･  

## 今後
初挑戦のNode.jsもといJavaScriptだったがtoioの整った環境と使いやすいデバイス、仕様のおかげで1つ作成することができた。
今回は利用するID(toio内の利用物)を絞ったが、次回はマットから取得できるX,Y座標やアングル等を利用して発展させたいと考えている。  

### ※ソースコード更新
2020/01/19 

- 細かい修正 
- ツイート内容に日付を追加しツイート文かぶりによるエラーを解決 
- 技カード以外のIDを「not defined ID」としIDと一緒にツイートできるようelseを設定
 
<img width="450" alt="8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/259e2515-2d29-3b25-546c-10116ce28527.png">
タイフーンカードに日付追加 
 
<img width="447" alt="9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/64ab94ac-5081-bb6d-404e-fbfb545ac9dc.png">
リズム＆ゴーのひだり(ツイート文未定義)