2台のAmazonEchoにジャルジャルの国名分けっこをやらせてみた話

#0. はじめに
2018年7月よりProgateやAidemyでプログラミング（とくにPython）を勉強しています。
いつかAmazonEchoのスキルを作ってみたいと思っていたので、
新しく我が家にやってきたEchoSpotと昨年購入したEchoDot２台でのEcho同士が対話するスキルを開発しました。
今回は題材として、お笑いコンビ「ジャルジャル」さんの「国名分けっこ」ゲームをやってみました。

#1. デモ動画
早速ですが、完成したデモ動画がこちらになります。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Amazon Echo2台にジャルジャルの国名分けっこゲームをやらせてみた <a href="https://twitter.com/hashtag/python?src=hash&amp;ref_src=twsrc%5Etfw">#python</a> <a href="https://twitter.com/hashtag/%E3%82%AF%E3%83%AA%E3%82%B9%E3%83%9E%E3%82%B9%E5%88%B6%E4%BD%9C?src=hash&amp;ref_src=twsrc%5Etfw">#クリスマス制作</a> <a href="https://twitter.com/hashtag/%E3%83%A1%E3%83%AA%E3%82%AF%E3%83%AA?src=hash&amp;ref_src=twsrc%5Etfw">#メリクリ</a>🎄 <a href="https://t.co/eqtUtGAhYf">pic.twitter.com/eqtUtGAhYf</a></p>&mdash; さい (@saisan78) <a href="https://twitter.com/saisan78/status/1077303252083822592?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>




#2. どうして二台のAmazonEchoで対話？
- 我が家のEchoが二台に増えたから
- Gizmodeの記事「[Google HomeとAmazon Echoで2匹のピカチュウの会話を再現した人物が登場、海外メディアも取り上げる](https://gigazine.net/news/20171121-amazon-echo-google-home-pikachu-talk/)」を見て、似たようなことをやってみたかったから
- Qiitaの記事[「ジャルジャルの「国名分けっこ」を実装してみた」](https://qiita.com/wadadon/items/72854db235a4c58d341d)を拝見して、AmazonEchoにやらせてみたい！と思ったから
- 自分のアウトプットとしてなにか作りたかったから

#3. 国名分けっこゲームとは
12月2日に開催さえた「M-1グランプリ2018」の決勝でジャルジャルが1本目に披露したネタです。
くわしくはYoutubeをご参照ください。
https://www.youtube.com/watch?v=b1J39WQFvSs

#4. 実装の全体像
今回は二台のAmazonEchoを使って、以下のように実装をしました。
ユーザが福徳さん役のスキルを呼び出すと、福徳さん役のスキルが後藤さん役のスキルを呼び出し、
二台のAmazonEchoがネタのように「国名わけっこ」ゲームを開始します。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/133230/f2ff3ef5-0ffe-1532-06e2-cf7affacfbbe.png)



#5. 苦労＆工夫したところ
###Echoから相方Echoのスキルを呼び出す
デモ動画では、福徳さん役のEchoSpotがが、EchoDotから後藤さん役のスキルをよびだしていますよね。
呼び出し方が「エコー、ごとうをひらいて」になっていることにお気づきでしょうか？
「アレクサ」だとEchoSpot自身も呼び出してしまうため、**相方の本体の呼び方（ウェイクワード）を変更**しました。

【参考】[ウェイクワードを変更する](https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=201971890)

さらに、セリフの中に**SSMLの中に休止時間**を設けることで、相方のEchoに認識してもらいやすくしました。

```SSMLの設定
<speak><voice name='Takumi'>くにめいわけっこをはじめるぜ！エコー<break time='0.3s'/>後藤をひらいて</voice></speak>
```

###Echoの発話を相方Echoに認識してもらう
福徳さん役のEchoが話す音声を、後藤さん役のEchoが正確にに認識できないという課題がありました。たとえば、オーストラリアの**「オースト」が「ゴースト」**と認識されたり、アルゼンチンの**「アルゼン」は「ある前」**と認識されてしまいました。そこで、以下のように認識を調整しました。

- 原作に出題される国名と分け方にのっとりAmazonのIntentを網羅的に作成（アルゼンチン用に、"アル"と"アルゼン"のIntentを作成するなど、全パターンのIntentを作成しました。）
- Echoにどう認識されるか、実際にテストした上で、発話例に登録（アルゼンは"ある前"などと認識されることがテストでわかるため登録しました。）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/133230/81435ad8-51c7-2d64-4abf-b58c6a7def81.png)




###SSMLを編集してキャラクターづくり
２人の異なるキャラクターを演出するために、Amazon公式の[音声合成マークアップ言語（SSML）のリファレンス](https://developer.amazon.com/ja/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html#break)を参考にしました。男性の声[Takumi]を利用し、後藤さんのスキルのほうは、[x-high]をいれることで、やや高い声に設定しています。

```SSMLの設定の例
<speak><voice name='Takumi'><prosody pitch='x-high'>ここに話したいメッセージをいれよう！</prosody></voice></speak>
```

SSMLのテストは、ポータル内のテストツールが便利でした。
https://developer.amazon.com/ja/

#5. ソースコード(国名ワケっこの後藤さんスキル)

本スキルはすべて、Python(Flask)で作成し、Herokuにデプロイしています。以下の記事を参考にさせていただきました！

- [Amazon Echo (Alexa) のSkillの開発に必要な基本概念を押さえる](https://qiita.com/chroju/items/3f30fe424df36e4b4d80)
- [HerokuでLINE BOT(python)を動かしてみた](https://qiita.com/akabei/items/38f974716f194afea4a5)




<details><summary>ソースコード ※初心者向けにシンプルに書いています。（クリックすると開きます）</summary><div>

```main.py
from flask import Flask,request,abort,jsonify
import json
import os
app = Flask(__name__)

@app.route("/post_request", methods=['POST'])
def post_callback():
    data = request.json
    message = ""
    endflag = False
    print(json.dumps(data, ensure_ascii=False))

    #インテントを判別する
    try:
        type = data["request"]["type"]
    except KeyError:
        type=""

    try:
        intent = data["request"]["intent"]["name"]
    except KeyError:
        intent=""

    #スキル起動時の場合のメッセージを記載する
    if type == "LaunchRequest":
        message = "よし、はじめよう！"

    #ここから下にインテントごとの処理を記載する
    if intent == "input_any":
        try:
            message = data["request"]["intent"]["slots"]["any"]["value"] + "ってしらんわ"
        except KeyError:
            print("KeyError")
    elif intent == "aru":
        message = "ぜんちん"
    elif intent == "aruzen":
        message = "ちん"
    elif intent == "in":
        message = "どねしあ"
    elif intent == "indo":
        message = "ネシア"
    elif intent == "ita":
        message = "リア"
    elif intent == "ame":
        message = "リカ"
    elif intent == "kana":
        message = "だ"
    elif intent == "ousuto":
        message = "らりあ"
    else:
        message = "わからんわ"

    reply_body = {
        "version":"1.0",
        "response":{
            "outputSpeech":{
                "ssml": "<speak><voice name='Takumi'><prosody pitch='x-high'>" + message + "</prosody></voice></speak>",
                "type": "SSML"
            },
            "reprompt": {
                "outputSpeech": {
                    "type": "SSML",
                    "ssml": "<speak><voice name='Takumi'><prosody pitch='x-high'>つづけて</prosody></voice></speak>"
                }
            },
    		"shouldEndSession": endflag
        }
    }

    return jsonify(reply_body)

@app.route("/")
def hello_world():
    return "Hello world!!" #デバック用

if __name__ == "__main__":
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

```
</div></details>

#6. 最後に
簡単ですが、二台のEchoで２つのスキルを連携を実装することができました！
本スキルは一台ずつでも遊ぶことが可能なようにつくっています。（今の所リリースする予定はございません。）


今回は本当にEcho（後藤さんのスキル）が音声認識をして対話しているのですが、
外のノイズ音の影響をうけるので、サーバ間で連携したほうが安心だと思います。笑