[Java Alexa] Sessionを使って何回かやり取りするCustom Skillを作成する

2017.07.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Javaで始めるAlexa Custom Skill開発入門の第3回になります。前回ではSlotを使って声掛けによって結果が変わるCustom Skillを作ってみました。前回までは1回でやり取りが終了していましたが、今回はセッションで状態を保持して何回かやり取りするCustom Skillを作成してみたいと思います。今回も第1回で作成したサンプルを修正します。

設計する

まずはどんなやり取りにするかを考える必要があります。 今回は以下のようなやり取りをしてみたいと思います。

ユーザ「Hello.」
Alexa「Can you speak English?」
ユーザ「Yes.」
Alexa「You can speak English.」

実装する

Intent Schema

まずはAmazon Developer Consoleを開いてIntent Schemaの定義をします。今回はAMAZON.YesIntentを追加しています。AMAZON.YesIntentは何かというと、Sample Utterancesにサンプルを登録しなくても使えるIntentです。YesIntentは 「yes」「yes please」「sure」などの声かけをすると呼ばれます。今回は入れていませんが、NoIntentとセットで使われます。他にもBuilt-inのIntentは色々ありますので以下のサイトをご覧ください。IntentSchamaに元から入っていたHelpIntentもBuilt-inのIntentです。
Standard Built-in Intents - Amazon Apps & Services Developer Portal

{
  "intents": [
    {
      "intent": "HelloWorldIntent"
    },
    {
      "intent": "AMAZON.YesIntent"
    },
    {
      "intent": "AMAZON.HelpIntent"
    }
  ]
}

Sample Utterances

次にSample Utterancesを以下のように修正します。

HelloWorldIntent hello

Javaのソースコードを修正する

まず最初にHelloWorldSpeechlet の getHelloResponseの処理を修正します。14行目で会話が終了するまで残しておきたい情報をSessionオブジェクトにキーバリュー形式で入れています。Stateという属性にState_1という情報を入れておきます。会話を終了せずに続けたい場合は19行目にようにSpeechletResponseのnewTellResponsenewAskResponseに変更します。16、17行目はnewAskResponseに必要な引数を作成しています。この辺りは次回詳しく触れたいと思います。会話を終了する場合はtell、続ける場合はaskというのはAlexaではよく使う用語なので覚えておきましょう。

    private SpeechletResponse getHelloResponse(Session session) {

        String speechText = "Can you speak English?";

        // Create the Simple card content.
        SimpleCard card = new SimpleCard();
        card.setTitle("HelloWorld");
        card.setContent(speechText);

        // Create the plain text output.
        PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
        speech.setText(speechText);

        session.setAttribute("State", "State_1");

        Reprompt reprompt = new Reprompt();
        reprompt.setOutputSpeech(speech);

        return SpeechletResponse.newAskResponse(speech, reprompt, card);
    }

HelloWorldSpeechlet の onIntentメソッドを以下のように修正してください。修正したのはハイライトの部分になります。5行目でセッションからStateという名前の情報を取得しています。セッション内のStateがState_1の場合のみYesIntentの処理に入るようにしておきます。

    @Override
    public SpeechletResponse onIntent(final IntentRequest request, final Session session)
            throws SpeechletException {

        String state = (String)session.getAttribute("State");

        Intent intent = request.getIntent();
        String intentName = (intent != null) ? intent.getName() : null;

        log.info("onIntent requestId={}, sessionId={}" , request.getRequestId(),
                session.getSessionId());

        if ("HelloWorldIntent".equals(intentName)) {
            return getHelloResponse(session);

        } else if ("AMAZON.YesIntent".equals(intentName) && "State_1".equals(state)) {
            return getYesResponse();

        } else if ("AMAZON.HelpIntent".equals(intentName)) {
            return getHelpResponse();

        } else {
            throw new SpeechletException("Invalid Intent");
        }
    }

最後にgetYesResponseの処理を追加します。メッセージ返すだけの簡単なものです。

    private SpeechletResponse getYesResponse() {
        String speechText = "You can speak English.";

        // Create the Simple card content.
        SimpleCard card = new SimpleCard();
        card.setTitle("HelloWorld");
        card.setContent(speechText);

        // Create the plain text output.
        PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
        speech.setText(speechText);

        return SpeechletResponse.newTellResponse(speech, card);
    }

確認する

Lambda FunctionをアップロードしてService Simulatorで試してみましょう。 一度、helloと入力した後にYesと入れてみて下さい。以下のように修正した部分がレスポンスに反映されていれば成功です。

alexa_java_03_02

最後に

今回はセッションを使ったサンプルを作ってみました。次回はAlexa Skill Kitの中を見てみたいと思います。

Javaで始めるAlexa Custom Skill開発入門 TOPページへ