Node.js
入門
lambda
Alexa
AlexaSkillsKit
Node.jsDay 11

Alexaに嫁をなだめてもらうSkillを作ってみた。

先日とあるプロジェクトでGASを使って予約フォームを作ったのですが、発生した不具合を解決できずになんとかごまかして乗り切りました。
「今度はGASを使わずにNode.jsでGmail/Googleスプレッドシートを操作する方法を試してみようかな、記事のネタにもなるし」と思っていたらのびすけさんにやられてしまい、ネタに困る事態に……。
そんな時echo dotがやっと届いたのでAlexaといちゃいちゃした様子を記録したいと思います。

なおAWSにあまり慣れてなく、Lambdaも初めてだったのでかなり細かめにキャプチャ取りながらまとめてみました。

動機

  • 妻帯者エンジニア共通の課題は新しく手に入れたガジェットといちゃいちゃしていると背後に危険な視線を感じること
  • 直談判は効果が薄いことが多い
    • 第三者の仲裁(「旦那さんは頑張っているんですよ」的な)が効果的なことが多い

ということから第三者(Alexa)にかばってもらうことを考えました。天才的。

必要なもの

  • echoシリーズなどAlexaがうごくもの
  • Amazon Developerアカウント
  • Amazon Web Servicesアカウント

3行まとめ

思いのほか長くなったので

  • 公式ドキュメントを良く読もう、せめてこれは最初に
  • あまりNode.jsっぽくない話になってしまいました
  • Alexaで嫁は攻略できない

手順

大まかな流れとして

  1. AWS Lambdaにバックエンドを実装する
  2. Amazon Skills Kit(Skill開発ダッシュボード的なもの)でスキル登録とバックエンドへの紐付けなどを設定
  3. 実機テスト

という流れになります。

バックエンドの作成

バックエンドにはLambdaを使います。

関数の作成と設定

001.png

まずは 関数の作成 をクリック。

002.png

名前とロールを設定します。
Lambdaのロールについては適当にLamdba実行用のロールを作成しました。「カスタムロールの作成」を選択すると新しくロールを作成することが出来ます。

003.png

関数の作成 をクリックして進むと、トリガー設定の画面に移ります。何をトリガーにして処理を呼び出すのかを設定するようです。
今回はAlexaから呼び出したいので、Alexa Skills Kitを選択してください。

004.png

トリガーの設定画面が出てきますが、特に設定項目もないので追加をクリック。
クリックすると画面右上部の保存がオレンジ色になるのでクリックして設定を保存してください。

005.png

続けて関数本体の設定をするため中央上部の作成した関数名(ここではMyAppeaseSkill)を選択してください。
コードエントリタイプは.ZIPファイルをアップロードを選択してください。

関数本体の実装

ここまで来たらローカルで関数本体の実装に移ります。
Node.jsはnodebrewなりnvmなりでv6.10を用意してください。

まずは作業場所を確保。

$ mkdir my-appease-skill
$ cd my-appease-skill
$ git init
$ npm init

Alexa SDKを使うので

$ npm install --save alexa-sdk

全体像はこんな感じ。

index.js
'use strict';
const Alexa = require('alexa-sdk');

// APP_ID : optionalらしくundefinedでも問題ないっぽい
const APP_ID = undefined;

//================
// alexaへのハンドラ登録
// ここは定型文で良さそう
//================
exports.handler = (event, context, callback) => {
  const alexa = Alexa.handler(event, context);
  alexa.APP_ID = APP_ID;
  alexa.registerHandlers(handlers);
  alexa.execute();
};

//================
// ハンドラ作成
// 入力したボイスメッセージに対応する実処理をここに実装する
//
// アロー関数使っていないのは呼び出し元で定義されるemit()関数を呼んでいるため
//================
const handlers = {
  'LaunchRequest': function() {
    // スキル呼び出し時の処理を実装する
    // 「(呼び出し名)を開いて」で呼ばれる

    // 別のインテントを呼び出したいときは
    // this.emit('AppeaseIntent');
    // のようにすると呼び出せます

    const speechOutput = 'どうかしましたか?';
    this.emit(':ask', speechOutput);
    },
  'AppeaseIntent': function () {
    // ここにインテントごとの処理を実装する

    const speechOutput = '旦那様は素晴らしい方です。こんな素晴らしい旦那様をお持ちになって奥様は幸せですね。';
    this.emit(':tell', speechOutput);
  },
  //以下については基本機能なのでメッセージ内容を変える程度のほぼ定型文で良さそう
  'AMAZON.HelpIntent': function () {
      const speechOutput = '私に頼りたい時は「なだめて」と、終わりたい時は「ありがとう」と言ってください。どうしますか?';
      const reprompt = 'どうしますか?';
      this.emit(':ask', speechOutput, reprompt);
  },
  'AMAZON.CancelIntent': function () {
      this.emit(':tell', 'さようなら、夫婦仲良く');
  },
  'AMAZON.StopIntent': function () {
      this.emit(':tell', 'さようなら、夫婦仲良く');
  }
};

ポイントはコメントに記載しましたが、結構カンタンに実装できるみたいです。

this.emit()しているところで、第1引数に:askハンドラを指定するとAlexaの応答後待ち受け状態に、:tellハンドラを指定すると応答後スキルを終了します。
詳細はこのあたりに書いてあるようですが、まだ試せていません。
:tellwithcardでAlexaアプリの履歴にも表示できる様子(タイトルと通知本文の引数を2つ追加するみたい)。他にもバリエーションがある様子です。クラスメソッド様の記事でまとめられていました。

このソースコードindex.jsとパッケージディレクトリnode_modulesをLambdaに登録するためにZIPにまとめます。

実装を登録

再度Lambdaの設定画面に戻ります。

006.png

作成したZIPファイルをアップロードして、保存します。
保存したら動作確認のために隣のテストをクリックします。

007.png

テスト作成画面が出てくるので、イベントテンプレートにAlexa Start Sessionを選択し、適当な名前で作成してください。

008.png

テストをクリックするとテストが実行されます。画面のような緑色の結果が出ればOKです。
Skillと紐付けるために右上のARNの値をコピーしておいてください。

スキルの作成

009.png

Amazon開発者コンソールからALEXAのメニューのAlexa Skills Kitを始めます。

010.png

新しいスキルを追加するをクリック。

011.png

  • 言語は日本語
  • スキル名は適当に
  • 呼び出し名はスキルを起動するときに使う言葉

を設定して、保存をクリック。

012.png

保存をクリックすると、次へがクリックできるようになります。

013.png

対話モデルの設定では最初にこのスキルにどのような機能があるかを登録します。この機能1つ1つをインテントと呼びます。

インテントにはカスタムインテントと基本的な機能を用意した一般的標準インテントがあります。

とりあえず今回は以下の内容で設定します。

{"intents": [
  {"intent": "AppeaseIntent"},
  {"intent": "AMAZON.HelpIntent"},
  {"intent": "AMAZON.StopIntent"},
  {"intent": "AMAZON.CancelIntent"}
]}

014.png

次にサンプル発話の登録をします。ここでは呼び出し名に続けて呼びかける言葉(アクションと呼ばれれる)の登録をします。
出来る限り多くのバリエーションを登録することで融通の聞くコマンド入力ができるようになるようです。

形式としては起動するインテント + 半角空白 + アクションの形式になります。

ここでは以下のように登録します。

AppeaseIntent なだめて
AppeaseIntent 嫁をなだめて
AppeaseIntent 助けて
AppeaseIntent 嫁に言ってやって

これで「アレクサ、大変だ助けて」みたいに呼べばかばってくれるようになりそうです。

入力したら、保存次へをクリックします。

015.png

対話モデルの更新を行うと、しばらくモデルの構築処理が走ります。モデルの構築には数分かかるのでそのまま設定を進めていきます。

016.png

設定ではLambdaで作成した関数との紐付けを行います。コピーしたARNの値(arn:〜で始まる値)を設定してください。

入力したら保存次へをクリックします。

017.png

ここまで来るとテストが行なえます。
発話入力欄に呼びかけるメッセージを入力して動作確認してみてください。

が、しかし実機で動作させる場合とは挙動が異なります。

サービスシュミレータでのテストはかなり楽観的だと思ってください。ここで期待するレスポンスが返ってきても実機での保証にはなりません。

ひとまず先に進みます。

018.png

019.png

020.png

公開情報を登録します。ここは適当な値で入力しておけば良いと思います。

公開する国と地域は日本語しか設定しないのであればJapanに限定しておいたほうが良いかもしれないです。

スキルの説明もそれっぽく入力します。

サンプルフレーズには実際にどう呼びかければ使えるかを入力します。

そしてアイコンの登録も必須なので適当に108x108、512x512のアイコン画像を用意しておきましょう。

021.png

プライバシーとコンプライアンスの設定はそれぞれ適切に設定しておきましょう。

ただし、13歳未満の子供を対象にしたスキルはこのあと出て来るSkills Beta Testing機能が利用できないので注意が必要です。

022.png

ここまでの

  • スキル情報
  • 対話モデル
  • 設定
  • テスト
  • 公開情報
  • プライバシーとコンプライアンス

の全設定が完了するとSkills Beta Testing機能が使えるようになります。

これはスキルを一般公開せずにAlexa対応端末にスキルを適用する機能です。

023.png

テスターのメールアドレスを入力してテスターを追加をクリックします。

024.png

テスターが追加されるのでテストを開始をクリックします。

025.png

このような画面になればテストの準備はOKです。

026.png

このようなメールが指定したメールアドレスに送信されているので、日本の利用者であれば下のリンク先に遷移します。

027.png

Alexaの設定画面にいき、スキルをテストするかどうかの確認ダイアログが出ますので、もちろんスキルテストをクリック。

028.png

有効にするをクリックすればecho実機でテストが出来るようになります!

動かない!!

がしかし「アレクサ、大変だ助けて!」と呼びかけても「すみません、私にはわかりません」

アレクサに見捨てられた!

なんでだ? と思って調べたら公式サイトに「ユーザーによるカスタムスキルの呼び出し」というドキュメントを見つけました。

これによると「呼び出し名」と「アクション」は特定のルールに則っていないと有効ではないようです。

「(呼び出し名)を起動して(アクション)」というルールがあったので、試しに「アレクサ、大変だを起動して助けて」と呼びかけたら無事かばってくれました。

ぐぬぬ……思っていたのと違う。

まとめ

他にもいろいろやれることがたくさんあるのでもっと触っていきたいですね。

カラーコードかるたの読み上げスキルとか作りたい。

嫁に向かってこれを使ったところ、 :fire: :oil: :name_badge: :oil: :fire: な感じでした。