aws chaliceとlambda(python)でalexaスキルをサックリ作る話。DialogDelegateも使うでよ。
前回書いた この記事とだいたい同じ、というか続きみたいなもんです。
(ちなみに魚へんクイズは別のクイズに作り変えて申請しました。申請通ったら記事にしよう)
で、気づいたんだけど
スキル開発者への特典の12月までに4つ以上スキル公開したらEcho Showを無料で購入できるクーポンをプレゼント
ってやつ、これやっぱり期間中に新たに4つって意味かなぁ。2つあるから2つ追加して4つだ、って都合よく思い込んでた。
そんなわけで、4つ作るかはわからんがもう一つ思いついたのを作っておこう。
開発言語予報
というスキルにしますよ。
プロジェクトコードは、alexa-proglangで。
まずは前回同様、プロジェクトを作ります。
1.まずgithubでレポジトリ作る(なんかローカルからだと弾かれたので)
2
$ cd !$
$ git init
$ git add remote origin [email protected]:ikegam1/alexa-proglang.git
$ git merge --allow-unrelated-histories origin/master <- git pullしたら.gitignoreがぶつかったのでmergeした
$ git add . && git commit -m 'init' && git push -u origin master
$ source ../venv/bin/activate <- 一つ上にvenv関連のがある
3
.chalice/config.jsonを少し編集。もうprodのみにしたった。
{
"version": "2.0",
"app_name": "alexa-proglang",
"prod": {
"environment_variables":
{
"DEBUG_MODE": "1"
},
"lambda_timeout": 120,
"lambda_memory_size": 128,
"lambda_functions": {
"default": {}
}
}
}
app.pyをHelloWorld的に
from chalice import Chalice
import logging
import json
import random
import re
import os
import sys
import alexa-speech
app = Chalice(app_name='alexa-proglang')
logger = logging.getLogger()
debug = os.environ.get('DEBUG_MODE')
if debug == '1':
logger.setLevel(logging.INFO)
else:
logger.setLevel(logging.ERROR)
@app.lambda_function()
def default(event, context):
return welcomeIntent()
def welcomeIntent():
#何を聞かれてもこんにちはと返しておきます
return alexa-speech.QuestionSpeech('こんにちは').build()
alexaへのレスポンスjson関連はvendor/alexa_speech.pyにした
class BaseSpeech:
def __init__(self, speech_text, should_end_session, session_attributes=None, reprompt=None):
"""
引数:
speech_text: Alexaに喋らせたいテキスト
should_end_session: このやり取りでスキルを終了させる場合はTrue, 続けるならFalse
session_attributes: 引き継ぎたいデータが入った辞書
reprompt:
"""
if session_attributes is None:
session_attributes = {}
self._response = {
'version': '1.0',
'sessionAttributes': session_attributes,
'response': {
'outputSpeech': {
'type': 'SSML',
'ssml': '<speak>'+speech_text+'</speak>'
},
'shouldEndSession': should_end_session,
},
}
if reprompt is None:
pass
else:
"""リプロンプトを追加する"""
self._response['response']['reprompt'] = {
'outputSpeech': {
'type': 'SSML',
'ssml': '<speak>'+reprompt+'</speak>'
}
}
self.speech_text = speech_text
self.should_end_session = should_end_session
self.session_attributes = session_attributes
def build(self):
return self._response
class OneSpeech(BaseSpeech):
"""1度だけ発話する(ユーザーの返事は待たず、スキル終了)"""
def __init__(self, speech_text, session_attributes=None):
super().__init__(speech_text, True, session_attributes)
class QuestionSpeech(BaseSpeech):
"""発話し、ユーザーの返事を待つ"""
def __init__(self, speech_text, session_attributes=None, reprompt=None):
super().__init__(speech_text, False, session_attributes, reprompt)
class DialogDelegate(BaseSpeech):
def __init__(self, speech_text='', session_attributes=None, reprompt=None):
super().__init__(speech_text, False, session_attributes, reprompt)
def build(self):
self._response['response'] = {
"directives": [{
"type": "Dialog.Delegate"
}]
}
return self._response
- そしてレッツdeploy.
$ chalice deploy
ちなみにalexa-speech.pyにDialogDelegateってClassを追加してあるのがポイント。
さてここまでやったら一回alexa skillの方へ。
alexa skills console
まず流れを考えよう
- QuestionIntent 今日の気分とかを問いかけ(5段階)
- StatusSlot
- HangrySlot
- EmotionSlot
- HopeSlot
- WeatherSlot
実はこんだけ。alexa上のIntentはこれだけにしたった。
もう起動したらQuestionIntentで発話集めて回答しておしまい。ちょーシンプル。
で、今回はダイアログとやらを使ってみる。
1.
2.
alexa skillの方はこんな感じ。
5つ必須スロットを作ってそれぞれに質問とサンプル発話を設定します。
でもこれだけだとまだ足りなくて、バックエンドでこのDialogを使うようにしてやる必要がある。
必須dialogが設定してあるintentの場合、requestにdialogState
というのが乗ってくるのですが、そこにdialogの状態が書いてある。状態は3つ。いや、実はもっとあるかも。でも意識してるのはこれだけです。
- STATED
- IN_PROGRESS
- COMPLETE
つまり、これをバックエンドで拾って、dialog使いたい時にはやり取りをalexaにぶん投げて(delegate)やればいい。
具体的にはこんな感じ。
def onDialogState(request, intent, dialogState):
if dialogState == 'STARTED':
return alexa_speech.DialogDelegate().build()
if dialogState == 'IN_PROGRESS':
if 'value' not in intent['slots']['emotionSlot']:
return alexa_speech.DialogDelegate().build()
elif 'value' not in intent['slots']['hopeSlot']:
return alexa_speech.DialogDelegate().build()
elif 'value' not in intent['slots']['statusSlot']:
return alexa_speech.DialogDelegate().build()
elif 'value' not in intent['slots']['weatherSlot']:
return alexa_speech.DialogDelegate().build()
elif 'value' not in intent['slots']['hangrySlot']:
return alexa_speech.DialogDelegate().build()
else:
return answerIntent(request, intent, intent['slots'])
DialogDelegateの中身はこの記事の上の方にあるalexa_speech.py
の中身です。
まああんまり状態は気にせずにslotが埋まってるかどうかを見てる感じ。
結果、うまくいきました。早くこれ、使ってればよかったなー。
ソースはこちら
後記
あ、なんか3つ申請したやつ全部通りました。
雑なやつですんません。
あと一個でEcho Showいけるな。そっちはすでに作り始めてるのでまた記事にします。
今度はディスプレイ使わんと。
Author And Source
この問題について(aws chaliceとlambda(python)でalexaスキルをサックリ作る話。DialogDelegateも使うでよ。), 我々は、より多くの情報をここで見つけました https://qiita.com/ikegam1/items/6dbde1041fe4dded14a2著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .