Google HomeにIDCFクラウドの料金をしゃべらせる。その2

[その１](https://qiita.com/ken_hikita/items/1d177aabf83697a3b2e9)からの続きです。


左ペインのFulfillmentをクリックします。
Webhook横のトグルをクリックし、ENABLEDにします。
URLに、http://localhost/webhook と入力し、【SAVE】をクリックします。
（後ほどURLは変更しますが、ひとまずlocalhostのURLで設定します。）
![019.PNG](https://qiita-image-store.s3.amazonaws.com/0/48100/8332c7d1-7a91-08c0-3fd7-cb996970bf63.png)

左ペインのIntentsをクリックします。
[その1](https://qiita.com/ken_hikita/items/1d177aabf83697a3b2e9)で作成した、billingsayをクリックします。
下のほうにスクロールし、Fulfillmentをクリックします。
Use Webhookにチェックを入れ【SAVE】をクリックします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/48100/097cccc7-7b2e-796f-193d-9d24765eaae7.png" width="50%">

# pythonソースを変更する
[IDCFクラウドのビリングAPIをpythonで利用する方法](https://qiita.com/ken_hikita/items/574f04ad22acab31a23b)を変更していきます。
（非プログラマが、頑張ってやっているので、エラー処理は全然やってなかったり、
つくりが適当だったりだと思いますのでのアドバイス頂けるとうれしいです！）

```py3
 # -*- conding: utf-8 -*-

import os
import json
import requests
import hashlib,hmac
import time
import base64

from flask import Flask,jsonify
from flask import request
from flask import make_response

app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
        req = request.get_json(silent=True, force=True)
        #print(json.dumps(req,sort_keys=True,indent=4,separators=(',', ': ')))
        cmd = req['result']['parameters']['command']
        m = req['result']['parameters']['date-period']
        if cmd == "料金":
                print("料金を提示")
                yyyymm = m[:7]
                ret = str(idcf_billing(yyyymm)) + "円です。"
                print(ret)
                r = make_response(jsonify({'speech':ret,'displayText':ret}))
                r.headers['Content-Type'] = 'application/json'
                return r


def idcf_billing(month):
        #IDCF billing API
        METHOD='GET'
        QUERY_STRING = 'format=json'
        APIKEY=os.getenv("IDCF_APIKEY")
        SECRET_KEY=os.getenv("IDCF_SECRETKEY")
        ENDPOINT='https://your.idcfcloud.com'
        ENDPOINT_URI='/api/v1/billings/history'
        EXPIRATION_SECONDS = 240

        expiration = int(time.time()) + EXPIRATION_SECONDS
        #print(expiration)

        message = METHOD + "\n" + ENDPOINT_URI + "\n" + APIKEY + "\n" + str(expiration) + "\n" + QUERY_STRING
        #message = METHOD + "\n" + ENDPOINT_URI + "\n" + APIKEY + "\n" + QUERY_STRING
        secret = SECRET_KEY

        signature=hmac.new(bytes(secret, 'ascii'), bytes(message, 'ascii'), hashlib.sha256).digest()
        sig=base64.b64encode(signature)

        head = {'X-IDCF-APIKEY': APIKEY, \
                'X-IDCF-Expires' : str(expiration), \
                'X-IDCF-Signature' : str(sig,'utf-8') }
        #print(head)
        uri = ENDPOINT + ENDPOINT_URI + '?' + QUERY_STRING
        res = requests.get(uri, headers=head)
        data = res.json()
        #print(json.dumps(data,sort_keys=True,indent=4,separators=(',', ': ')))
        data = data['data']
        for amt in data:
                if amt['month'] == month:
                        return amt['billing_amount']
                        #print(amt['month'] + ":" + str(amt['billing_amount']))

if __name__ == "__main__":
        app.run(host='0.0.0.0')
```

# 実行してみる
上記のソースコードで実行します。

```shell-session
$python3.6 idcf.py
*Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
```

ngrokを利用して外部からアクセスができるようにします。
ngrokの設定は、[ngrokを使ってローカル環境上で実行するWebアプリケーションにインターネットからアクセスする](https://qiita.com/rubytomato@github/items/3ffb51d60fec24863a5b)を参考にさせていただきました。

コマンドプロンプトを起動し、下記コマンドを実行します。

```bat
>ngrok.exe http 5000
```

```bat
ngrok by @inconshreveable                                       (Ctrl+C to quit)

Session Status                online
Account                       k (Plan: Free)
Update                        update available (version 2.2.8, Ctrl-U to update)
Version                       2.2.8
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://1XXXXXX0.ngrok.io -> localhost:5000
Forwarding                    https://1XXXXX0.ngrok.io -> localhost:5000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00
```

httpsのURLをコピーします。(Google Assistantを利用する場合、httpsでないと入力できません）
Dialogflowに戻り、FulfillmentのWebhook URL欄へコピーします。
今回 /webhook にきた場合と定義しているので、https://1XXXXX0.ngrok.io/webhook のように入力し、【SAVE】をクリックします。

右ペインでテストをします。
その１と同様に、Try it nowに、今月の金額は？　と入力しEnterキーを押します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/48100/1588a230-9ba6-90ad-40f8-72f7d8145ef5.png" width="50%">
DEFAULT RESPONSEに、該当月の金額＋円です。と応答があれば成功です！
SHOW JSONをクリックすると、JSONが表示されます。

# googleアシスタント側の設定
## App informationを設定する
各項目の値すべてを入力していきます。
途中アプリ用画像を設定する項目があり、large,small画像が必須となっているので、
適当な画像を用意して、設定していきます。
![024.PNG](https://qiita-image-store.s3.amazonaws.com/0/48100/4ea92ff3-cc50-664a-84c4-ee3f54359355.png)

app nameをIDCFクラウドと設定してみました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/48100/29286101-8992-eff3-d2df-afb1bab5a9bc.png" width="50%">

左ペインのOverviewをクリックします。
【TEST DRAFT】をクリックします。
![30.PNG](https://qiita-image-store.s3.amazonaws.com/0/48100/a2921206-07f8-537d-b9c1-54ee73c7bef8.png)


## シミュレータでテストする
左ペインのSimulatorをクリックします。
app nameで指定したアプリ名＋につないで　という文言がすでに入った状態となるため、
このままEnterを押します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/48100/3e5027aa-dc6c-b680-f5a7-7fada0ac15f7.png" width="50%">

IntentのDefault Welcome IntentのDefault Responseの内容が返ってきます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/48100/88aa6df8-cd2c-ef70-c0e7-cf922384d03d.png" width="50%">

今月の料金は？と問いかけてみます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/48100/26400bb6-3608-264b-d3d2-664d14d80e38.png" width="50%">

2016年9月はなんぼ？　とも問いかけてみます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/48100/e8cf0ec8-a9ac-8c97-2100-3ea1cafb9759.png" width="50%">

# google homeに問いかけてみる
前提として、Actions on Googleの設定をしたアカウントと同じアカウントでgoogle homeがセットアップされている必要があります。
画像をクリックするとYoutubeに飛びます。
<a href="https://youtu.be/Y-GoozpypLs"><img src="https://qiita-image-store.s3.amazonaws.com/0/48100/ccb6cc5c-7b79-d6e7-a124-6bfc286ae4d3.png" width="50%"></a>


pythonアプリが反応して、応答を返していることがわかります。
![vscode-ret.PNG](https://qiita-image-store.s3.amazonaws.com/0/48100/f061525d-99b3-729d-b772-105b5eba6815.png)

サーバを声だけで作成できる仕組みとかもできそうですね。