aws chalice와 lambda(python)로 alexa 스킬을 빨리 만드는 이야기. DialogDelegate도 사용하자.

전회 썼다.

(덧붙여서 물고기엔 퀴즈는 다른 퀴즈로 만들어 바꾸어 신청했습니다.신청 다니면 기사로 하자)

그래서 깨달았지만
이 기사 의 12월까지 4개 이상 스킬 공개하면 Echo Show를 無料で購入できるクーポンをプレゼント 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만 했다.

config.json
{
  "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로

app.py
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로 만들었습니다.

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
  • 그리고 Letts 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) 하면 된다.

    구체적으로는 이런 느낌.

    main.py
    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개 신청한 녀석 모두 지나갔습니다.

    여기
    물고기의 한자
    국가명의 한자

    어색한 사람이 아닙니다.
    그리고 1개로 Echo Show는 할 수 없다. 그쪽은 벌써 만들기 시작하고 있기 때문에 또 기사로 합니다.
    이번에는 디스플레이 사용하지 않고.

    좋은 웹페이지 즐겨찾기