1. はじめに
通常、Alexaスキルを開発する際のシステム構成とし、「Amazon Alexa + AWS Lambda」の構成がベストプラクティスだとは思いますが、諸事情により「AWS Lambda」を用いることができない場合も稀に存在します。
ただ、2019年1月現在、AWS Lambda以外のクラウド環境(Node.js)を用いた参考サイトは、ほとんど見つけることができません。
今回は、自分への備忘録も兼ねて、「AWS Lambda」の代わりに「Microsoft Azure Functions(Node.js)」を用いたAlexaスキルの開発方法をお伝えします。
参考文献
1-1. この記事を読んでできること
- Alexaスキルを Microsoft Azure Functions(Node.js)環境で開発できるようになる。
1-2. 前提条件
- Alexaスキルの知識があること。
- Microsoft Azure Functionsの知識があること。
1-3. 必要なアカウント
- Amazon.co.jpアカウント Amazon Developer Portalログイン用
- Microsoft Azureの開発アカウント
1-4. 必要なソフトウェア
ブラウザ
- ブラウザ:Chrome(推奨)
- Chrome拡張機能:Advanced REST client(ローカル環境でのPOSTテスト用)
エディタ
- エディタ:Visual Studio Code(推奨)
- Visual Studio Code 用 Azure Functions 拡張機能:azure functions
ツール
- .NET Core SDK 2.2
- Node.js(npmコマンド含む)
- Azure Functions Core Tools:azure-functions-core-tools
1-5. 注意事項
- Nodeモジュールにalexa-skill-sdk-for-azure-functionを用います。
- alexa-skill-sdk-for-azure-functionモジュールは、Alexa SDK V1 alexa-sdkにのみ対応しています。
- Alexa SDK V1 alexa-sdkは、2019年1月現在、開発が終了しており、Alexa SDK V2 ask-sdkの利用が推奨されています。
- Alexa SDK V2 ask-sdkを用いたMicrosoft Azure Functions環境での開発方法をご存知の方がいらっしゃいましたら、コメントをお待ちしております。
2. index.jsサンプルソース
- Microsoft Azure Functions環境版のFACTスキル(宇宙の豆知識)です。
'use strict';
// コメントアウト
// var Alexa = require('alexa-sdk');
// var APP_ID = "amzn1.ask.skill.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
var APP_ID = undefined;
// 定数定義
var SKILL_NAME = "豆知識";
var GET_FACT_MESSAGE = "知ってましたか?";
var HELP_MESSAGE = "豆知識を聞きたい時は「豆知識」と、終わりたい時は「おしまい」と言ってください。どうしますか?";
var HELP_REPROMPT = "どうしますか?";
var STOP_MESSAGE = "さようなら";
// 音声応答定義
var data = [
"水星の一年はたった88日です。",
"金星は水星と比べて太陽より遠くにありますが、気温は水星よりも高いです。",
"金星は反時計回りに自転しています。過去に起こった隕石の衝突が原因と言われています。",
"火星上から見ると、太陽の大きさは地球から見た場合の約半分に見えます。",
"木星の<sub alias='いちにち'>1日</sub>は全惑星の中で一番短いです。",
"天の川銀河は約50億年後にアンドロメダ星雲と衝突します。",
"太陽の質量は全太陽系の質量の99.86%を占めます。",
"太陽はほぼ完璧な円形です。",
"皆既日食は一年から二年に一度しか発生しない珍しい出来事です。",
"土星は自身が太陽から受けるエネルギーの2.5倍のエネルギーを宇宙に放出しています。",
"太陽の内部温度は摂氏1500万度にも達します。",
"月は毎年3.8cm地球から離れていっています。"
];
// AWS Lambda Node.js V6.10 + alexa-sdk V1の場合の表記
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);
}
};
// ーーーー 追記ここから AzureFunctions対応 ーーーー
module.exports = function (context, req) {
var alexa = require('alexa-skill-sdk-for-azure-function');
alexa.setup({
azureCtx: context,
azureReq: req,
handlers: [handlers],
trackInvokedIntents: true,
enforceVerifier: false,
// i18nSettings: i18nSettings
});
alexa.execute(avsCallback(context, req));
}
var avsCallback = function (azureCtx, req) {
return function (err, obj) {
if (err) {
azureCtx.res = {
status: 400,
body: err
};
} else {
azureCtx.res = {
body: obj
};
}
azureCtx.done();
};
};
// ーーーー 追記ここまで AzureFunctions対応 ーーーー
3. package.json
- package.jsonは自分で作る必要がある。
// プロジェクトフォルダ直下(host.jsonファイルがある同一フォルダ内で実行する)
// package.jsonの作成
$ npm init
// alexa-skill-sdk-for-azure-function のインストール
$ npm i alexa-skill-sdk-for-azure-function
{
"name": "functions-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"alexa-skill-sdk-for-azure-function": "^1.0.8"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
4. 関数のURLの取得
- Azure Functions の関数ページから、関数のURLを取得する。
5. Alexaスキルのエンドポイント設定
- 左メニューから、「エンドポイント」を選択する。
- サービスのエンドポイントの種類に、「HTTPS」を選択する。
- デフォルトの地域に、Azure Functions(クラウド)の「関数のURL」を設定する。
- ドロップダウン選択肢から、「開発用のエンドポイントは、証明機関が発行したワイルドカード証明書をもつドメインのサブドメインです」を選択する。
- 「エンドポイントを保存」をクリックする。
6. Amazon Developer Portalでのテスト実施(クラウド環境テスト)
- 「<スキル名> を開いて」と発話し、テストする。
- スキル名が「宇宙の豆知識」の場合、Amazon公式のスキルが動作するため、スキル名呼び出しは重複しないように注意すること。(例では、「宇宙豆知識」としています。)
6. Visual Studio Codeでのテスト実施(ローカル環境テスト)
- メニューから、「デバッグ」→「デバッグの開始」をクリックする。
- テストURL(ローカル環境)をコピーする。
7. ローカル環境テスト用ツールの用意
- Chrome拡張機能に「Advanced REST client」を追加し、アプリを起動する。
8. テスト用 Request JSON(ローカル環境テスト用)
- テスト用 Request JSON(LaunchRequest)は以下のとおり。
{
"session": {
"new": true,
"sessionId": "amzn1.echo-api.session.[unique-value-here]",
"attributes": {},
"user": {
"userId": "amzn1.ask.account.[unique-value-here]"
},
"application": {
"applicationId": "amzn1.ask.skill.[unique-value-here]"
}
},
"version": "1.0",
"request": {
"locale": "ja-JP",
"timestamp": "2016-10-27T18:21:44Z",
"type": "LaunchRequest",
"requestId": "amzn1.echo-api.request.[unique-value-here]"
},
"context": {
"AudioPlayer": {
"playerActivity": "IDLE"
},
"System": {
"device": {
"supportedInterfaces": {
"AudioPlayer": {}
}
},
"application": {
"applicationId": "amzn1.ask.skill.[unique-value-here]"
},
"user": {
"userId": "amzn1.ask.account.[unique-value-here]"
}
}
}
}
9. ローカル環境テスト用ツールの設定&実行
- Methodに、「POST」を選択する。
- Request URLに、先ほどコピーした「テストURL(ローカル環境)」をペーストする。
- 「Body」を選択する。
- Body contenxt typeに、「application/json」を選択する。
- Editor viewに、「Raw Input」を選択する。
- テキストエリアに、「テスト用 Request JSON(ローカル環境テスト用)」をペーストする。
- 「SEND」ボタンをクリックする。
実行結果として、画面下部に「200 OK」と「Response JSON」が出力される。
10. おまけ(Azure Function クラウド環境での単体テスト)
- 「テスト」を、クリックする。
- HTTPメソッドに、「POST」を選択する。
- 要求本文に、「テスト用 Request JSON(ローカル環境テスト用)」をペーストする。
- 「実行ボタン」をクリックする。
実行結果として、画面下部に「進捗状況:200 OK」と「Response JSON」が出力される。
11. おわりに
いかがだったでしょうか?ご参考になりましたでしょうか?
わたしじしんが、Microsoft Azure Functionsを始めて2日目で知識がとぼしいため、Azure Functionsの関数作成手順などは、今回割愛させていただきました。
Azure Functionsの関数作成については、公式サイトのAzure Functions のドキュメントが参考になるかと思います。
また、もしかしたら間違ってるよ、とかありましたら、コメント頂けると幸いです。
そして、Alexa SDK V1 alexa-sdk ではなく、Alexa SDK V2 ask-sdk でも Microsoft Azure Functions(Node.js)環境で開発できる方法をご存知の方がいらっしゃいましたら、ご教示のほどお待ちしております。
2019/01/17 TAKAHIRO NISHIZONO
追記:2019/01/20
Alexa SDK V2 ask-sdkを用いた、Microsoft Azure Functions(Node.js)環境での開発方法を、以下の記事に書き起こしました。あわせてご参照ください。