myThings Developersを使って音声アシスタント機能を作ってみる

[myThings Advent Calendar 2016](http://qiita.com/advent-calendar/2016/mythings) 24日目の記事になります。
#概要
音声アシスタント市場が近頃熱いですね。私は昔からロボットやBOTと人間が会話する様が好きなので、音声アシスタント市場が盛り上がった2016年はとても激アツな1年でした。
Amazon EchoやGoogle Homeなど注目のデバイスに実際に話しかけてみたいのはもちろんですが、試しに似たようなものを自作してみるのもかなりワクワク感があります。

というわけで、今回は[myThings Developers](https://mythings-developers.yahoo.co.jp/)を利用してサクッと音声アシスタントを作ってみることについて記事を（夜な夜なスマートフォンに話しかけながら）書こうと思います。もしご興味をお持ちいただけましたら、しばしお付き合いください！


#準備するもの
###・[myThings Developers](https://mythings-developers.yahoo.co.jp/) + 自分のサーバ
![ba60d69b-0188-09bd-dc0e-643d2e656453.png](https://qiita-image-store.s3.amazonaws.com/0/66341/cddfafea-f3f6-7a2a-032b-8857c92c770a.png)

myThings Developersはさまざまなサービス、デバイスのAPIを共通のI/Fで利用を可能にしてくれるサービス連携プラットフォームで、すばやく音声アシスタントを構築してみるのにうってつけのサービスです。(詳しくは後述)
また、利用するにあたって自分のサーバを1台用意します。音声認識で得たテキストをmyThings Developersへ渡すときに利用します。

###音声認識が可能なデバイス 
音声認識を行うことのできるデバイスを用意します。今回はAndroid端末を音声認識用のデバイスとして利用します。
Androidでは[SpeechRecognizer](https://developer.android.com/reference/android/speech/SpeechRecognizer.html)を利用すれば素早く音声認識機能を用意することができます。今回は画像のような音声認識用のアプリを用意しました。(据え置き型デバイス感を出すために当初Raspberry Piで作成予定でしたが連休が尽きそうだったため断念いたしました。)

![banner.png](https://qiita-image-store.s3.amazonaws.com/0/66341/8391c4f8-28b6-0fb9-e712-fff814483f21.png)

#構成図
![guide_tweet.png](https://qiita-image-store.s3.amazonaws.com/0/66341/5029e5f5-5a1e-a5ce-ebbd-394b508542ca.png)
上の画像は、「○○とツイートして」と発話した時の処理の流れを示しています。
###1. 音声入力
音声認識用デバイスから自サーバへ発話したテキストを送信します。
###2. ドメイン選択
ユーザから発話された内容が求める処理(ドメイン)が何であるかを判断します。ここで、「○○とツイートして」というユーザの発話が文字列をツイートすることを求めていることをプログラム上で選択する必要があります。
###3. ドメインに対応するアクションの実行
myThings Developersに実行したい処理をリクエストし実行します。ここでは、後述するmyThings Developersのカスタムトリガーという機能と各サードパーティのアクションを紐づけて実行をします。この例の場合、ツイートをする引き金となるmyThings Developers上で設定されたトリガーへリクエストを送ると、それに紐づいたTwitterの「ツイートする」アクションが呼ばれ、ツイートが実行されます。本来、サードパーティへのリクエスト処理を１つ１つ実装する必要がありますが、サードパーティとの橋渡しをすべてmyThings Developersが代わりに行ってくれます。トリガーとアクションの組み合わせはmyThings Developers上のGUI操作で作成することができるため、この構成さえ作ってしまえば、ほとんどコードを書くことなく発話に対応する機能を追加していくことができるようになります。

#作成手順

#myThings Developrsの準備
[myThings Developers](https://mythings-developers.yahoo.co.jp/)へアクセスし、利用登録する。その後の進め方についてはこちらを参照→[チュートリアル](https://mythings-developers.yahoo.co.jp/document/tutorial_section1)
組み合わせを作成する準備ができたら、先ほど上で説明したトリガーとアクションの設定を行う。まずは初めに「発話したらツイートする」と「発話したら自分にGメールを送る」という２つの組み合わせを作ってみた。
<img width="244" alt="スクリーンショット 2016-12-24 6.12.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/66341/551bd654-647e-1ec6-6459-9c46613f443d.png">
<img width="891" alt="スクリーンショット 2016-12-24 6.13.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/66341/b513381d-f79d-8755-42e7-7001bb5c0242.png">
左側の緑アイコンがmyThings Developersのカスタムトリガーという機能、右側のTwitterアイコンがつぶやきを行うアクションです。
<img width="299" alt="スクリーンショット 2016-12-24 6.16.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/66341/ccd2c8ea-a337-4727-2518-6d01dbb946a2.png"><img width="303" alt="スクリーンショット 2016-12-24 6.17.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/66341/fb94a202-44d3-e756-b103-af0d49a0bc4c.png">
カスタムトリガーにはツイート内容をリクエスト項目に設定し、「ツイートする」アクションのツイート内容にはカスタムトリガーから送られてきたツイート内容が入るよう設定します。この設定により、「ツイートする」アクションと紐づいたカスタムトリガーが呼ばれると、カスタムトリガーにリクエストしたテキストをツイートできるようになります。

<img width="607" alt="スクリーンショット 2016-12-24 6.20.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/66341/e15e696c-d12b-6635-b21b-be6a8f2fe1a9.png">
組み合わせが作成できたら、ページ下部にある「テスト > 疎通確認」の設定を順番に行います。この過程でサンプルコードと一緒にこの組み合わせをリクエストするためのURLとアクセストークンを取得できます。[チュートリアル](https://mythings-developers.yahoo.co.jp/document/tutorial_section1)に沿って自分サーバへ必要なプログラムを置けば、自分のサーバから作成した組み合わせを実行することができるようになります。

このように組み合わせを作成すると、１つの組み合わせにつき１つのリクエスト用URLが与えられます。このURLと先ほど上で説明をした「ドメインの選択」を紐づけることでユーザの発話に応じたアクションを実行できるようにしていきます。


#発話とmyThings Developersカスタムトリガーを紐づける。
ユーザがどのようなドメインを想定して発話をしたか理解する箇所の実装は、音声アシスタントの肝となる部分です。正規表現のパターンを大量に用意してユーザの発話の意図を判断する方法や機械学習を用いて高度な判定を行う方法など様々な手法が考えられます。
(参考:[発話理解API | DOCOMO](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=speech_understanding&p_name=api_reference) )
この記事では発話理解部分については深く考えず、正規表現のパターンを用意してドメインに紐づけるということをやろうと思います。
ツイートするアクションに対しては例えば次のようなパターンを用意します。

```php:send_tweet
    $parttern_self_tweet = array(
        "/(.*)(とツイート)(.*)/s" => 1,
        "/(.*)(とつぶやいて)(.*)/s" => 1,
    );
```
配列のkeyにパターン、valueには正規表現でマッチした場合カスタムトリガーにツイート内容として渡す文字列のインデックスを設定しておきます。「メリークリスマスとツイートして」と発話した場合、「メリークリスマス」という文字列がカスタムトリガーにリクエストされツイートされます。カスタムトリガーには複数のパラメータが渡せますが、ひとまずツイート内容だけ渡してみました。


#動作
実際に音声でツイートをしてみた動画です。
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/MiHvRbcju2Y/0.jpg)](http://www.youtube.com/watch?v=MiHvRbcju2Y)
ちゃんとツイートされました！

#まとめ
ざっくりとした説明になってしまいましたが、myThings Developersを使って手軽に音声アシスタント機能を作ることができました。サードパーティへリクエストをする実装をしないですむため非常にスピーディに構築をすることができますね。
組み合わせの追加とパターンの追加をするだけで発話に対応するアクションを増やせるので、しばらく便利そうな音声コマンドを色々と考えながら遊んでみようと思います。

それではこの辺で２４日目[myThings Advent Calendar 2016](http://qiita.com/advent-calendar/2016/mythings)の記事を終わらせていただこうと思います。良いクリスマスを〜！