はじめに
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」
以下のような画面が開くので、適当に入力します。
プロジェクトの情報を入力します。
適当にカテゴリを選択します。
Invocation SETUP
左のメニューから「Invocation」を選択します。「Display name」にGoogle Homeに呼びかける名前を入力して「SAVE」しておきます。「Google Assistant voice」はお好みで。
Actions SETUP
左のメニューから「Actions」‐「ADD YOUR FIRST ACTION」を選択。
よくわからないので「Custom intent」で「BUILD」。Dialogflowが開きます。
Dialogflowでプロジェクトを作る
※ Dialogflowを始めて使う場合、アカウントの権限許可を求められるので、許可します。
メニューから「Create Agent」で「CREATE」します。プロジェクトが作成されます。
先にGoogle Assistantと統合しておきます。「Integrations」でGoogle Assistantの「INTEGRATION SETTINGS」を選択します。
とりあえず、「MANAGE ASSISTANT APP」を選択します。
Actions on Googleに戻り、Dialogflowと連携されたことがわかります。
新しいIntentを作る
まず、アプリの起動のIntentとなる「Default Welcom intent」を選択し、「output context」に「gomi_context」を入力します。
Dialogflowの「Intents」から「CREATE INTENT」します。
「input context」を先ほど指定した「gomi_context」とします。
「Training phrases」にユーザからの呼びかけのパターンを入力し、ごみを表す部分を変数「word」で受け取るようにします。ENTITYはsys.anyとしています。
「Fulfillment」ではwebhookを有効にしておきます。
Fulfillmentの設定
Webhookを「ENABLED」としてAPIのURLを指定します。
指定するURLは「AWSでゴミ分別APIを作った - Qiita」で作成したものです。
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の実機でも確認ができます。
おわりに
やっていることは難しいわけではないのですが、実際に試してみないと難しいですね。
参考
Actions on Googleチュートリアル - Qiita
Dialogflowで会話中に値を保持する方法 - Qiita
Actions on Google と AWS Lambda で Google Home から Slack にポストする - ユニファ開発者ブログ