2
1

More than 3 years have passed since last update.

Hello World. ゼロから始める Alexa 開発

Last updated at Posted at 2020-03-31

前回までは ITFFF を用いてちょっとした通知アプリを作ってみました
しかし、本命は Alexa Skills Kit を用いてアプリケーションを作成したいと思ってる!

今回は、 Hello World. ゼロから始める Alexa 開発 と題して始めてみたいと思ってます

環境

  • Amazon Echo Dot (通称:あれくさ)
  • AWS Lambda
  • Visual Studio Code
  • node.js
  • Alexa Skills kit(開発者コンソール)

まずはじめに

やさしくはじめるスマートスピーカープログラミングを読んで実装するつもりだった。
しかし…うまく動かない:sweat:
であればもっと初心者向けに色々あるんじゃないかと調べて、サンプルを作るにあたって学習した内容からまとめてみました

学習編

You Tube を用いて仕組みを説明しながらサンプルプログラミングの作り方を説明してくれる
この構築の場合は、AWS Lambda がなくても実装できるのでお手軽で仕組みの理解もしやすかった

Alexa 道場で学習中に軽く見たけれどコードの書き方などがまとまっている
多分本格的に実装するときには参考にすることが増えそう

得た知識

Alexa Skill Kit でアプリケーションを実行するには以下のような呼び出し方をする

パターンA

声:へろーわーるどを開いてぬるぽして
あれくさ:ヽ( ・∀・)ノ┌┛ガッΣ(ノ`Д´)ノ(実際はガッって言うだけ)

パターンB

声:へろーわーるどを開いて
あれくさ:「ぬるぽ」と言ってください
声:ぬるぽ
あれくさ:ヽ( ・∀・)ノ┌┛ガッΣ(ノ`Д´)ノ(実際はガッって言うだけ)

1行で言い切るか、対話形式でやり取りが出来る
やり取りできるものを スキル というらしい
(スマホ(Alexa)のアプリ(スキル)と意識するとわかりやすいかも?)

Alexa の Request の種類について

LaunchRequest

「xxxを開いて」をトリガーとしてスキルを実行する
実行したときの最初に呼び出されるリクエスト種別

IntentRequest

スキルを起動後に呼び出されるリクエスト種別
LaunchRequest の後に「yyyして」などを付けると呼び出される
「xxxを開いてyyyして」とした時は LaunchRequest を飛ばして、IntentRequest が呼ばれる
リクエストと組み合わせて intent(インテント) が実行される
intent はアクションという認識で、自作で作るものから、ヘルプ、キャンセルという Alexa Skills Kit にデフォルトで用意されているものが存在する

SessionEndedRequest

応答がなかった場合等に呼び出される
例)xxxを開いて (この後放置する)等

実装編

処理のイメージ

  1. Amazon Echo Dot(命令)
  2. Alexa スキル(声を受け取る)
  3. AWS Lambda(声を処理する)
  4. Amazon Echo Dot(返答)

作るもの

声:あれくさ、応答テスト
あれくさ:「ぬるぽ」と言ってください
声:ぬるぽ
あれくさ:ヽ( ・∀・)ノ┌┛ガッΣ(ノ`Д´)ノ(実際はガッって言うだけ)

デフォルトの無料枠内のものではなく AWS Lambda を用いる

スキルを作成する

Alexa Skills kit 開発者コンソール上で「スキルの作成」を押下する
image.png

スキル名は単語2つを組み合わせるような形で設定する必要があるので「応答テスト」とする
設定については以下の画像の選択を行うものとする

image.png

インテントを作成する

スキルを作成したら、声の受け口インテントを作成する
ビルトインテントは Alexa が用意しているアクションなので今回はスルーする
このサンプル発音に該当する発音が行われた場合 HelloIntent が呼び出されるようになる
image.png

AWS Lambda の側を作成しスキルと連携する

連携するためにスキル ID をコピーしておく

image.png

AWS コンソールからLambdaを選択して関数を作成する
image.png

完成作成後、トリガーに Alexa Skills Kit を選択する
image.png

Lambda の右上にARNがあるのでこれをコピーしエンドポイントのデフォルトの地域に張り付けて保存しておく
image.png

ここまで出来るとスキルと Lambda の連携は完了しているはず!

AWS Lambda の実装を行う

Visual Studio Code を開く
空のディレクトリに移動して以下の呪文を唱えていく

npm init
npm install --save ask-sdk-model
npm install --save ask-sdk-core

以下のようにしたいけど容量が大きくてzipファイルアップロードをすると
AWS コンソール上でソースの編集が出来なくなるので必要なものだけ取り込む

npm init
npm install --save ask-sdk

直下に index.js を作成して以下のソースコードを張り付ける

/* eslint-disable  func-names */
/* eslint-disable  no-console */

const Alexa = require('ask-sdk-core');

// 起動時に処理するハンドラ
const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    const speechText = 'ようこそ。「ぬるぽ」と言ってください。';

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .withSimpleCard('こんにちは。', speechText)
      .getResponse();
  },
};

// スキル起動後に実行される intent.name で処理を分岐している
const HelloIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'HelloIntent';
  },
  handle(handlerInput) {
    const speechText = 'ガッ';

    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('5ch', 'ヽ( ・∀・)ノ┌┛ガッΣ(ノ`Д´)ノ')
      .getResponse();
  },
};

// デフォルトで用意されているインテントでスキル起動後「ヘルプ」というと実行される
const HelpIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    const speechText = '「ぬるぽ」と話しかけてください。';

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .withSimpleCard('5ch', speechText)
      .getResponse();
  },
};

// デフォルトで用意されているインテントでスキル起動後「キャンセル」「ストップ」というと実行される
const CancelAndStopIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && (handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent'
        || handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    const speechText = 'さようなら。';

    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('こんにちは。', speechText)
      .getResponse();
  },
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

// 応答できなかった場合等のエラー対応
const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('すみません。理解できませんでした。もう一度お願いします。')
      .reprompt('すみません。理解できませんでした。もう一度お願いします。')
      .getResponse();
  },
};

// ハンドラを作成した後は以下で登録する必要がある
const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    HelloIntentHandler,
    HelpIntentHandler,
    CancelAndStopIntentHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

動作させてみる

すべて緑色のチェックがついていることを確認する
チェックされていなければされていない部分をクリックする
image.png

ソースのビルドを行う
個人的にはモデル保存時にビルドするのが良いと思っている
image.png

スキルテストが有効になっているステージを「開発中」に変更する
そのあと、下の入力またはマイク長押しで「応答テスト」と言ってみる
image.png
。。。
image.png
うまくいったね!
ここまで来たら自分のあれくさに言ってみる
「あれくさ、応答テスト」
アレクサと楽しい会話ライフが始まるかもしれません
今回のサンプルは実際動かしてみると、抑揚のない「ガッ」に失笑間違いなし!
(ところどころ単語に誤字があったりしますがご了承ください)

最後に

withSimpleCard を用いるとディスプレイに文字が出るらしいが、テストだと表示されなかった・・・
うまく動くかわからないので、ディスプレイ型のスマートスピーカーも気になる:persevere:

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1