GoogleHome
dialogflow
ActionOnGoogle

Google Home miniをもらったから遊んでみた


はじめに

Google Playで課金をしていたらGoogle Home miniを頂きました。

せっかくなので、何か作ってみることにします。


つくるもの

年末でちょうど大掃除をしていたので、ゴミの分別を教えてくれるものを作ることにしました。

「OK, Google. 電池の捨て方!」

みたいな。

APIは慣れているという理由でAWS Lambdaを使い、Pythonで実装しました。


前提知識


用語


  • Actions on Google


    • Google Home のアプリを Action と呼び、そのプラットフォームのこと。



  • Dialogflow


    • 会話型サービスを構築するサービス。

    • Google Assistantに依存するものではない。



  • Invocation


    • 呼びかけ。Actionを呼び出す設定。



  • Intents


    • 意図。会話の1キャッチボール単位。



  • Fulfillment


    • 履行。処理の実装。




実装


Actions on Googleでプロジェクトを作る

Actions on Google にアクセスして「Add/import project」

以下のような画面が開くので、適当に入力します。

image

プロジェクトの情報を入力します。

image

適当にカテゴリを選択します。


Invocation SETUP

左のメニューから「Invocation」を選択します。「Display name」にGoogle Homeに呼びかける名前を入力して「SAVE」しておきます。「Google Assistant voice」はお好みで。

image


Actions SETUP

左のメニューから「Actions」‐「ADD YOUR FIRST ACTION」を選択。

よくわからないので「Custom intent」で「BUILD」。Dialogflowが開きます。

image


Dialogflowでプロジェクトを作る

※ Dialogflowを始めて使う場合、アカウントの権限許可を求められるので、許可します。

メニューから「Create Agent」で「CREATE」します。プロジェクトが作成されます。

image

先にGoogle Assistantと統合しておきます。「Integrations」でGoogle Assistantの「INTEGRATION SETTINGS」を選択します。

image

とりあえず、「MANAGE ASSISTANT APP」を選択します。

image

Actions on Googleに戻り、Dialogflowと連携されたことがわかります。

image


新しいIntentを作る

まず、アプリの起動のIntentとなる「Default Welcom intent」を選択し、「output context」に「gomi_context」を入力します。

image

Dialogflowの「Intents」から「CREATE INTENT」します。

「input context」を先ほど指定した「gomi_context」とします。

「Training phrases」にユーザからの呼びかけのパターンを入力し、ごみを表す部分を変数「word」で受け取るようにします。ENTITYはsys.anyとしています。

image

「Fulfillment」ではwebhookを有効にしておきます。

image


Fulfillmentの設定

Webhookを「ENABLED」としてAPIのURLを指定します。

指定するURLは「AWSでゴミ分別APIを作った - Qiita」で作成したものです。

image


APIの対応

AWSでゴミ分別APIを作った - Qiita」で作成したAPIをDialogflowのWebhookの仕様に合わせて修正します。

Webhookの仕様は「How fulfillment works  |  Dialogflow」を参考にします。

WebhookからのアクセスはPOSTなので、template.yamlを修正します。

AWSTemplateFormatVersion: '2010-09-09'

Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
garbage:
Type: 'AWS::Serverless::Function'
Properties:
Handler: garbage/lambda_function.lambda_handler
Runtime: python3.6
Description: ''
MemorySize: 128
Timeout: 15
CodeUri: .debug/
Events:
LambdaMicroservice:
Type: Api
Properties:
Path: /garbage
Method: POST
garbagePermission:
Type: 'AWS::Lambda::Permission'
Properties:
Action: 'lambda:InvokeFunction'
FunctionName:
'Fn::GetAtt':
- garbage
- Arn
Principal: apigateway.amazonaws.com
SourceArn:
'Fn::Sub': 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*/*/*'

Intentsの設定でパラメータを「word」としたため、リクエストから取得するために以下のように変更しました。

    body = json.loads(event.get('body', {}))

word = body.get('queryResult', {}).get('parameters', {}).get('word', None)

レスポンスは以下のように、「fulfillmentText」で返却するように変更します。

日本語で返却するため、Content-Typeにcharsetを設定しておきます。

    {

'statusCode': '200',
'body': {
'fulfillmentText': result,
},
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
},
}


テスト

Actions on Googleの「Simulator」でも、Google Homeの実機でも確認ができます。

image


おわりに

やっていることは難しいわけではないのですが、実際に試してみないと難しいですね。


参考

Actions on Googleチュートリアル - Qiita

Dialogflowで会話中に値を保持する方法 - Qiita

Actions on Google と AWS Lambda で Google Home から Slack にポストする - ユニファ開発者ブログ