LoginSignup
3
0

More than 5 years have passed since last update.

デバイス毎に挙動を変えるAlexaスキルの作り方

Last updated at Posted at 2018-12-18

前置き

  • Amazon Echo シリーズには様々なデバイスがあり、画面の有無、画面のサイズ感でデバイス毎に挙動を変えたいという時に利用できる方法
  • APLが登場して、画面サイズからデバイスの判定が行えるようになった
  • 以下の5つを判別
    • 画面なし Echo (Echo, Echo Dot, Echo Plus)
    • Echo Spot (480*480)
    • 旧型 Echo Show (1024*600)
    • 新型 Echo Show (1280*800)
    • FireTV (1920*1080)
  • 2018年12月現在の方法なので、今後UIやインターフェースが変更される可能性があります。

考え方

  • スキルからの JSON 入力の値を解析してデバイスを判別する。
  • 画面の無いデバイスは handlerInput.requestEnvelope.context.Viewportundefined になる
  • 画面のあるデバイスの中から、どのデバイスであるかを判別するには画面の縦横サイズを表す以下の値を確認する
    • handlerInput.requestEnvelope.context.Viewport.currentPixelWidth
    • handlerInput.requestEnvelope.context.Viewport.currentPixelHeight

環境

ローカル環境

  • Node.js 8.10.0
  • NPM 5.6.0

AWS Lambda 環境

  • Node.js 8.10

プロジェクト構成

device-check-skill/
   ├ index.js
   ├ package.json
   ├ package-lock.json
   ├ ja-JP.json(モデル)
   └ node_modules/

実装

モデル 実装

スキル作成

  • alexa developer console にログインする
  • スキルを作成する(エンドポイントなどの説明は割愛します)

インターフェース

  • 左メニューの インターフェース から以下をオンにする
    • Alexa Presentation Language
  • インターフェースを保存 を行う

JSONエディター

  • 呼び出し名を デバイス確認 にしています。
  • カスタムインテントは今回使いませんが、ビルドに必要なので適当なものを入れてます。
  • JSONエディターを以下のように編集する
{
    "interactionModel": {
        "languageModel": {
            "invocationName": "デバイス確認",
            "intents": [
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.NavigateHomeIntent",
                    "samples": []
                },
                {
                    "name": "HogeIntent",
                    "slots": [],
                    "samples": [
                        "ほげほげ"
                    ]
                }
            ],
            "types": []
        }
    }
}

ビルド

  • モデルの保存 を行う
  • モデルのビルド を行う
  • 左メニューのカスタムから、4つの必須項目に全てチェックが入ってることを確認する

Lambda 実装

ディレクトリ作成

  • > mkdir device-check-skill
  • > cd device-check-skill

package.json 作成

  • > npm init -y

package のインストール

  • > npm install --save ask-sdk-core@2.3.0
  • > npm install --save ask-sdk-model@1.10.1

index.js 作成

  • > touch index.js
  • 以下のコードが index.js の中身
const Alexa = require('ask-sdk-core');
const SPOT_WIDTH = 480;
const SPOT_HEIGHT = 480;
const OLD_SHOW_WIDTH = 1024;
const OLD_SHOW_HEIGHT = 600;
const NEW_SHOW_WIDTH = 1280;
const NEW_SHOW_HEIGHT = 800;
const FIRE_TV_WIDTH = 1920;
const FIRE_TV_HEIGHT = 1080;

const LaunchNoDisplayRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest'
      && !handlerInput.requestEnvelope.context.Viewport;
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak('これは 画面なしの Echo です')  
      .getResponse();
  },
};

const LaunchSpotRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest'
      && handlerInput.requestEnvelope.context.Viewport.currentPixelWidth === SPOT_WIDTH
      && handlerInput.requestEnvelope.context.Viewport.currentPixelHeight === SPOT_HEIGHT;
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak('これは Echo Spot です')
      .getResponse();
  },
};

const LaunchOldShowRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest'
      && handlerInput.requestEnvelope.context.Viewport.currentPixelWidth === OLD_SHOW_WIDTH
      && handlerInput.requestEnvelope.context.Viewport.currentPixelHeight === OLD_SHOW_HEIGHT;
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak('これは旧型 Echo Show です')
      .getResponse();
  },
};

const LaunchNewShowRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest'
      && handlerInput.requestEnvelope.context.Viewport.currentPixelWidth === NEW_SHOW_WIDTH
      && handlerInput.requestEnvelope.context.Viewport.currentPixelHeight === NEW_SHOW_HEIGHT;
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak('これは新型 Echo Show です')
      .getResponse();
  },
};

const LaunchFireTvRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest'
      && handlerInput.requestEnvelope.context.Viewport.currentPixelWidth === FIRE_TV_WIDTH
      && handlerInput.requestEnvelope.context.Viewport.currentPixelHeight ===  FIRE_TV_HEIGHT;
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak('これは Fire TV です')
      .getResponse();
  },
};

const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchNoDisplayRequestHandler,
    LaunchSpotRequestHandler,
    LaunchOldShowRequestHandler, 
    LaunchNewShowRequestHandler,
    LaunchFireTvRequestHandler
  )
  .lambda();

AWS Lambda 関数にアップロード

  • AWS Lambda 関数に以下のファイルをZIPに圧縮してアップロードする
    • index.js
    • package.json
    • package-lock.json
    • node_modules/
  • 保存する

確認方法

ブラウザで確認

  • alexa developer console にログインする
  • 上タブから テスト を選択
  • スキルテストが有効になっているステージ:開発中 に変更
  • Alexaシミュレーターで 呼び出し名 を入力するか、マイクから発話して挙動を確認する
  • Device Display にチェックを入れて下にスクロールすると、試したいデバイスの選択が可能
  • 画面なしデバイスの確認はできない

実機で確認

  • Amazon Echo デバイスに alexa developer console で利用した Amazon アカウントを設定する
  • 「Alexa 呼び出し名」で呼び出してみる
3
0
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
3
0