OK, Google. サーバーをスペックアップして

この記事は[富士通クラウドテクノロジーズ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/fjct)の16日目の記事です。

15日目は @ConHumi さんの[ニフクラでもできる！Kubernetes クラスタ](https://qiita.com/ConHumi/items/629bbe27875b8c48dcd9)でした。
簡単にクラスタリングができるみたいなので、そろそろサービスのバックエンドへの取り入れを検討したいです！

# はじめに
オフィス内の誰かがふと思った「サーバーのタイプ変更しないと...」
オフィス内の誰かがふと思った「GoogleHomeでタイプ変更できたら楽しいだろうか...」
誰かがふと思った「みんなのためにつくらねば...」

# 実装

Google Assistant のアプリは Dialogflow で作成することができます。
簡単な応答だけであれば Dialogflow で完結しますが、外部システムと連携するためにはバックエンドを用意する必要があります。

## 環境
* Google Home
* [Dialogflow](https://dialogflow.com/)
* [Amazon API Gateway](https://aws.amazon.com/jp/api-gateway/)
* [AWS Lambda](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html) python3.6
* ニフクラ

## 構成図

Dialogflow は、連携先を Webhook か Coud Functions の javascript を実行するか選べます。 Python で書きたかったので、今回は Webhook を利用し、その先を API Gateway と Lambda で作成します。

![スクリーンショット 2017-12-15 20.14.22.png](https://qiita-image-store.s3.amazonaws.com/0/107806/94db000a-b6a4-2c9e-4e71-e349e8f1f2cd.png)

## Dialogflow

Dialogflowでは、Intents, Entities, Fulfillment の3つの設定が必要になります。

まずは Intents で会話を設計します。
「サーバーhogeをfugaにして」「hogeをfugaにして」と正規表現を書くたくなるようなパターンをいくつも登録していきます。
会話中から連携先に投げるパラメータとなる部分も後述のEntityに割り当てます。

![スクリーンショット 2017-12-15 12.34.54のコピー2.png](https://qiita-image-store.s3.amazonaws.com/0/107806/478fc7e0-2545-76b6-9ce7-87b1e3c11a4d.png)

Entities では先ほどの Intents 内で使用する Entityを定義しておきます。
サーバーのタイプ変更をするため必要な、「サーバー名」と「サーバータイプ名」を定義します。画像はサーバータイプ名Entity `type` の設定です。
「スモール」か「スマール」だったら「small」というように、対応を定義して置くと、自分で変換しなくて済みます。

![スクリーンショット 2017-12-15 12.35.42.png](https://qiita-image-store.s3.amazonaws.com/0/107806/5e9e0a69-0997-3d68-8bec-9fba026569e8.png)

Intents と Entities を設定すると、「Try it now」 に文字またはマイク入力で簡単にテストすることができます。
「App」が `server` へ、「ミニ」が `type` に `mini` に変換されて入っていることが確認できますね。

![スクリーンショット 2017-12-15 12.34.54のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/107806/8bf4703a-fa0c-3ef1-9de4-583db5873089.png)

Fulfillment では、WebhookのURLを登録します。次のステップで作成する API Gateway のURLを入力しました。

![スクリーンショット 2017-12-15 12.36.50のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/107806/ce41b534-ef3b-95e2-d996-a19a2ade3bef.png)

## API Gateway

API Gatewayでは、パスを設計します。以下のパスにリクエストを投げた時に、次に作成する
 Lambda の intancetype にリクエストを横流しするように設定します。

```
POST /instancetype
```

![スクリーンショット 2017-12-15 12.37.59のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/107806/d62569b0-f1ff-3f4a-7745-e79d3259709f.png)

## Lambda

Lambda にのせるコードはこのようになりました。ニフクラのAPIを叩くのには[py_nifcloud](https://github.com/o-hayato/py_nifcloud)を利用しました。
外部ライブラリを利用する際は、`pip install {lib_name} -t {dir_name}` でライブラリもすべて同じディレクトリに格納して、zipで lambda にアップロードする必要があるので注意です。

```python3:lambda_function.py
from py_nifcloud.computing_client import ComputingClient

def lambda_handler(event, context):
    print(event)
    instance_name = event['result']['parameters']['server'].strip()
    instance_type = event['result']['parameters']['type'].strip()
    print(instance_name)
    print(instance_type)

    nif_client = ComputingClient(region_name="jp-east-4",
                                 config_file='./myaccount.yml')
    param = {
        'Action': 'ModifyInstanceAttribute',
        'InstanceId': instance_name,
        'Attribute': 'instanceType',
        'Value': instance_type,
        }
    nif_response = nif_client.request(method="GET", query=param)
    print(nif_response.status_code)
    print(nif_response.text)

    message = "リクエストは受け付けられませんでした"
    if nif_response.status_code == 200:
        message = "リクエストを受け付けました"

    res = {'speech': message, 'displayText': message}
    print(res)
    return res
```

返す時に `speech` に設定したメッセージを Google Home が話してくれます。
Cloud Watch でログが確認できるので、適度にログを出力しておくのが良いと思います。

# 結果

![スクリーンショット 2017-12-15 20.22.49.png](https://qiita-image-store.s3.amazonaws.com/0/107806/e51cf871-53c8-57f8-ae00-92744a47e60a.png)

私「サーバーAppをminiにして」
Google Home「リクエストを受け付けました」

![スクリーンショット 2017-12-15 20.23.46.png](https://qiita-image-store.s3.amazonaws.com/0/107806/e298046f-5f5a-6337-ff42-fb72576bf367.png)

![スクリーンショット 2017-12-15 20.27.57.png](https://qiita-image-store.s3.amazonaws.com/0/107806/66eebe41-e508-6114-bf71-a3d839793e07.png)

サーバー「App」のタイプを「small」から「mini」に変更することができました :tada:

# おわりに

賢い皆さんはもうお気づきかもしれませんが、サーバーのタイプ変更には、使いやすいコントロールパネルを使うかニフクラの[タイマー](https://cloud.nifty.com/service/timer.htm)で自動化しましょう！

あしたは @umiiiiins が「gitlabciのこと書くつもり」のようです。お楽しみに！