python3
lambda
APIGateway
dialogflow
NIFCLOUD

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

この記事は富士通クラウドテクノロジーズ Advent Calendar 2017の16日目の記事です。

15日目は @ConHumi さんのニフクラでもできる!Kubernetes クラスタでした。
簡単にクラスタリングができるみたいなので、そろそろサービスのバックエンドへの取り入れを検討したいです!

はじめに

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

実装

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

環境

構成図

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

スクリーンショット 2017-12-15 20.14.22.png

Dialogflow

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

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

スクリーンショット 2017-12-15 12.34.54のコピー2.png

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

スクリーンショット 2017-12-15 12.35.42.png

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

スクリーンショット 2017-12-15 12.34.54のコピー.png

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

スクリーンショット 2017-12-15 12.36.50のコピー.png

API Gateway

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

POST /instancetype

スクリーンショット 2017-12-15 12.37.59のコピー.png

Lambda

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

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

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

スクリーンショット 2017-12-15 20.23.46.png

スクリーンショット 2017-12-15 20.27.57.png

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

おわりに

賢い皆さんはもうお気づきかもしれませんが、サーバーのタイプ変更には、使いやすいコントロールパネルを使うかニフクラのタイマーで自動化しましょう!

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