アレクサスキル開発を始めてみる
一時は、ピカチュウを呼ぶ機械と化していた
我が家のecho dotも、現在はTVを消したり、
豆芝呼んだり、天気を伝えたり、
それなりに活躍の場を増やしています。
(相変わらずその程度、という見方をしてもいい。)
それはそれとして、
Facebookの広告等で度々目にして
気になっていたのがこのキャンペーン。
スキルを開発して、特典をもらおう | Amazon Alexa | アレクサ
期間中にスキルを作成、公開すると
特製Tシャツが貰えるらしい。
3月くらいからスタートしてましたが、何だかんだ毎月行われていて8月も継続中。
ちょっと欲しい。
マラソン参加賞以外のノベルティTシャツが欲しい。
ということで、試しにアレクサスキルを作ってみようと思います。
まずはお試し。公式のトレーニングに沿ってチュートリアルを行う。
Alexaスキル開発トレーニングシリーズ 第1回 初めてのスキル開発 : Alexa Blogs
チュートリアルの内容
宇宙の豆知識を教えてくれるサンプルスキルの作成を通して、スキル開発の一連の流れを学ぶというもの。
このサンプルスキル、仕組みとしては、複数の文字列の候補からランダムで一つ返す、という最も単純なものだと思われる。
単に、全く同じスキルを作るのも少し退屈なので、娘(1)がお気に入りの、今日のわんこを題材にスキルを作成します。
アカウント作成
- Amazonアカウント
- Amazon開発者アカウント(注意)
- AWSアカウント
まずはアカウント作成。
通常のAmazonアカウント以外に
Amazon開発者アカウントとAWSアカウントが必要になります。
但し、開発者アカウントは、新規に作るのではなく、echoなどのalexaデバイスと紐付いたamazonアカウントでログインする必要があります。これが、割と深く広い落とし穴で、実際ハマリました。
alexaデバイスと紐付いたamazonアカウントでログインしてスキル開発をすれば、作成したスキルを自宅のechoなどで試すことが出来ます。一方で、新規に開発者アカウントを作成すると、(まあ、考えてみると当然なんですが)、紐付けがなされず公開前のスキルを実機で試すことが出来ません。
また、amazon.co.jpとamazon.com(U.S.A)で、同一のメールアドレス、パスワードのアカウントを持っていると、既存アカウントでログインしても勝手に.comの方にリダイレクトされて、上手くいかないようです。
僕の場合は、よく確認せず突っ走って、新規に開発者アカウントを作ってしまい、完成したスキルが実機で使えない現象に陥りました。 同一アドレス、パスワードの米国アカウントも持っていたので、パスワードを変更してから再度ログインし、一からスキルを作り直す羽目に。
前置きが長くなりましたが、ここからが本番。
といっても以降はトレーニングに沿って、進めていけば
特に詰まるところはなかった。
スキル設定と対話モデルの作成
- スキル名
- 呼び出し名
- インテント作成
まずは開発者コンソールで対話部分の構築を行います。
スキル名は単純にスキルの名称。
呼び出し名は、「アレクサ、○○開いて」の○○部分に該当。
インテントは、ユーザが命令する際の想定フレーズを列挙するもの。
同じ命令でも複数種のフレーズがあるので、たくさん用意しておく必要がある。
対話モデルの品質面で割と重要な要素だと思います。
AWS lambda関数作成
次にAWSに移って、lambda関数を作成。
スキルの実際の処理部分はlambda関数に記載する。
トレーニングではサンプルプログラムをDLしてコピペすることになっている。
以下、サンプルプログラム。
'use strict'; var Alexa = require('alexa-sdk'); //========================================================================================================================================= //TODO: このコメント行より下の項目に注目してください。 //========================================================================================================================================= //Replace with your app ID (OPTIONAL). You can find this value at the top of your skill's page on http://developer.amazon.com. //Make sure to enclose your value in quotes, like this: var APP_ID = "amzn1.ask.skill.bb4045e6-b3e8-4133-b650-72923c5980f1"; var APP_ID = undefined; var SKILL_NAME = "豆知識"; var GET_FACT_MESSAGE = "知ってましたか?"; var HELP_MESSAGE = "豆知識を聞きたい時は「豆知識」と、終わりたい時は「おしまい」と言ってください。どうしますか?"; var HELP_REPROMPT = "どうしますか?"; var STOP_MESSAGE = "さようなら"; //========================================================================================================================================= //「TODO: ここから下のデータを自分用にカスタマイズしてください。」 //========================================================================================================================================= var data = [ "水星の一年はたった88日です。", "金星は水星と比べて太陽より遠くにありますが、気温は水星よりも高いです。", "金星は反時計回りに自転しています。過去に起こった隕石の衝突が原因と言われています。", "火星上から見ると、太陽の大きさは地球から見た場合の約半分に見えます。", "木星の<sub alias='いちにち'>1日</sub>は全惑星の中で一番短いです。", "天の川銀河は約50億年後にアンドロメダ星雲と衝突します。", "太陽の質量は全太陽系の質量の99.86%を占めます。", "太陽はほぼ完璧な円形です。", "皆既日食は一年から二年に一度しか発生しない珍しい出来事です。", "土星は自身が太陽から受けるエネルギーの2.5倍のエネルギーを宇宙に放出しています。", "太陽の内部温度は摂氏1500万度にも達します。", "月は毎年3.8cm地球から離れていっています。" ]; //========================================================================================================================================= //この行から下のコードに変更を加えると、スキルが動作しなくなるかもしれません。わかる人のみ変更を加えてください。 //========================================================================================================================================= exports.handler = function(event, context, callback) { var alexa = Alexa.handler(event, context); alexa.APP_ID = APP_ID; alexa.registerHandlers(handlers); alexa.execute(); }; var handlers = { 'LaunchRequest': function () { this.emit('GetNewFactIntent'); }, 'GetNewFactIntent': function () { var factArr = data; var factIndex = Math.floor(Math.random() * factArr.length); var randomFact = factArr[factIndex]; var speechOutput = GET_FACT_MESSAGE + randomFact; this.emit(':tellWithCard', speechOutput, SKILL_NAME, randomFact) }, 'AMAZON.HelpIntent': function () { var speechOutput = HELP_MESSAGE; var reprompt = HELP_REPROMPT; this.emit(':ask', speechOutput, reprompt); }, 'AMAZON.CancelIntent': function () { this.emit(':tell', STOP_MESSAGE); }, 'AMAZON.StopIntent': function () { this.emit(':tell', STOP_MESSAGE); }, 'SessionEndedRequest': function () { // Nothing to do } };
node.jsとか使ったことないけど、
dataの配列の中の文字列をランダムに返すのだな、
という雑な理解をした。
var data = [ "ゆずくん オス 1才。 ポメラニアン", "春くん オス 2才6ヵ月。雑種", "ベイリーくん オス 1才5ヵ月。トイ・プードル。", "花子ちゃん メス 6ヵ月。柴犬" ];
今日のわんこ情報に書き換えた。
参考:
スキルとlambda関数の接続
作成したlambda関数とスキルを紐付けます。
開発者コンソールに戻ってlambdaのARNをエンドポイントに設定。
テスト
完成したスキルは、シミュレータを使ってPC上でテストできます。
また、amazon.co,jpアカウントと紐付け出来てれば*1
自分のalexaデバイスでスキルが実行できるようになっています。
これで今日のわんこを教えてくれるスキルが完成しました。
※今日の、といいつつ聞くたびに内容が変わる。
※テキスト情報だけなので犬種とかから、姿を想像するしかない
何の役に立つの?何の役にも立たない。
まとめ
普通のプログラムだと本当にしょうもない処理ですが、
音声対話として形になると、わりと満足感があるのが面白いですね。
次回は、公開用のスキル作成に挑戦しようと思います。
*1:前述の通り、ここで過ちに気づき1から作り直した