はじめに
Alexa道場で勉強を進め、基本的なスキルを作成する方法を学んだため、一度オリジナルスキルを作って復習&知識の定着を図ってみることにした。
結論、2時間じゃ無理だったので、続きはまた今度やる。
やってみたこと
計画を立ててみた
- 何作るべきか考える(30分)
- 自分が何欲しいか考えてみる(5分)
- 自分以外に欲しい人がいそうか考えてみる(5分)
- 似たようなモノで、市場で必要とされているものを調べてみる(10分)
- 自分が作る方向性を決める(10分)
- モックを作る
- 設計する(30分)
- 実装する(60分)
21:00 – 21:30 アイディア出しをしてみた
自分たちが欲しい物を色々と考えてみる。思いついたのは以下。
- バーチャル面接官(加藤)
→志望動機はなんですか?とか聞いてくる
→しゃべったことをテキスト化して、あとで回答が見れる
→何秒間堪えられなかったか記録
→何秒空白があったか記録(くま)/(けん)
21:30 – 21:40 似たようなモノで、市場で必要とされているものを調べてみる
- Googleで検索してみた
- Amazon.co.jp: 圧迫面接 : Alexaスキル https://www.amazon.co.jp/Ga9-%E5%9C%A7%E8%BF%AB%E9%9D%A2%E6%8E%A5/dp/B07BQHXLJF
- ベリーグッドは「Amazon Alexa」に対応する面接練習用の「面接シミュレーション」をリリース。 | 株式会社ベリーグッド https://www.verygoodinc.biz/archives/293
→今は存在しない?
- その他、スキルストアで検索してみた。結果は次の通り
スキルストアには面接系のAlexaアプリはあまりなさそうだった。
なので、「圧迫面接」じゃない方向性で面接対策スキルを作るとよさそう、という話になった。
21:37 – 22:12 方向性の話し合いをしてみる
誰に向けて作るか話し合ってみた。結果は以下。
- for ユーザ
→バイトの面接を控えている学生や、転職活動したい社会人の練習台になる - for 自分たち
→Alexaの勉強になる
→(儲からなくてもいい)
どんな質問がされるといいか調べながら話し合ってみた。結果は以下の記事にあるような方向性
- 面接対策まとめ|よくある質問の回答例、準備~面接後のやりとり・流れ|マイナビ転職 https://tenshoku.mynavi.jp/knowhow/mensetsu
→「面接でよくある質問の回答50例」の内容をAlexaに仕込んで見る
→とりあえず「自己紹介」と「志望理由」
22:12 – 22:45 設計
ユーザにどうなってもらうかを考えてみた。結果は以下。
- 想定ユーザ:けんとくんみたいなアルバイトの面接控えている、ガジェット好きな学生
- ユーザの動き:
・(そもそもAlexaで面接したい、って思わせる何か)
→Alexaで面接できるという認知をさせる?
・ユーザが面接の練習をAlexaでできないかな?と思う
・ユーザがAlexaストアで「面接」で検索する
→Alexaストアに登録する必要あり
・ユーザがスキルの説明を見て、使いたいと思う
→説明ちゃんと入れる必要あり
・ユーザがAlexaスキルをインストールする
・ユーザがAlexaでウェイクワードを発する
・Alexaが、ユーザは何をすればいいかを説明する
→「これから面接練習をします。質問に回答してください。よろしいですか?」
・ユーザが「はい」と答える
・Alexaが最初の質問をする
・ユーザが最初の質問に答える
・Alexaが次の質問をする
・ユーザが次の質問に答える
〜ループ〜
・Alexaが最後の質問をする
・ユーザが最後の質問に答える
・Alexaが、すべての質問に回答し終わったことを伝える
・Alexaが、どこかで回答内容が確認できるようにする
→例えば、テキスト化して、どこかに置いておく
・Alexaが、回答内容の確認方法をユーザに伝える
どんな実装作業が必要か考えてみた。結果は以下。
- じゃあどんな機能とかが必要か
- ウェイクワードを設定する
- インテントを作る
- コードエディタで編集する
- 起動時に最初に呼ばれるリクエストハンドラを作る
- ユーザは何をすればいいかを説明「これから面接練習をします。質問に回答してください。よろしいですか?」
- 質問リクエストハンドラを作る
- 質問を順番に行う
- 回答内容を記録する
- 最後の質問が終わったら、説明をする
22:45 – 23:00 作り始めてみた
Developer Consoleで新しいスキルを作成
- Alexa-hosted(Node.js)
- スクラッチ
スキルの呼び出し名を設定
インテントを作成
リクエストハンドラなどをコードエディタで実装(途中まで)
初めに呼ばれるリクエストハンドラと、StartIntentのハンドラを実装。
こんな感じ
/* *
* This sample demonstrates handling intents from an Alexa skill using the Alexa Skills Kit SDK (v2).
* Please visit https://alexa.design/cookbook for additional examples on implementing slots, dialog management,
* session persistence, api calls, and more.
* */
const Alexa = require('ask-sdk-core');
const LaunchRequestHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
},
handle(handlerInput) {
const speakOutput = 'これから面接練習をします。質問に回答してください。よろしいですか?';
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse();
}
};
const StartIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'StartIntent';
},
handle(handlerInput) {
// 流れ
// 1回目の場合(引数が空の場合):
// 質問をする
// 回答をテキストで、どこかに記録する
// StartIntentHandlerをまた呼び出す()
// 2回目の場合(引数が空でない場合):
// 質問をする
// 回答をテキストで、どこかに記録する
// 最後の質問だったかどうかを判別する
// 最後の質問だった場合
// 最後の処理をする
// 最後の質問じゃなかった場合
// StartIntentHandlerをまた呼び出す(次の質問を引数に入れる)
const speakOutput = 'スタート';
return handlerInput.responseBuilder
.speak(speakOutput)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
}
};
const HelloWorldIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'HelloWorldIntent';
},
handle(handlerInput) {
const speakOutput = 'Hello World!';
return handlerInput.responseBuilder
.speak(speakOutput)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
}
};
const HelpIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const speakOutput = 'You can say hello to me! How can I help?';
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse();
}
};
const CancelAndStopIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& (Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.CancelIntent'
|| Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.StopIntent');
},
handle(handlerInput) {
const speakOutput = 'Goodbye!';
return handlerInput.responseBuilder
.speak(speakOutput)
.getResponse();
}
};
/* *
* FallbackIntent triggers when a customer says something that doesn’t map to any intents in your skill
* It must also be defined in the language model (if the locale supports it)
* This handler can be safely added but will be ingnored in locales that do not support it yet
* */
const FallbackIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.FallbackIntent';
},
handle(handlerInput) {
const speakOutput = 'Sorry, I don\'t know about that. Please try again.';
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse();
}
};
/* *
* SessionEndedRequest notifies that a session was ended. This handler will be triggered when a currently open
* session is closed for one of the following reasons: 1) The user says "exit" or "quit". 2) The user does not
* respond or says something that does not match an intent defined in your voice model. 3) An error occurs
* */
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'SessionEndedRequest';
},
handle(handlerInput) {
console.log(`~~~~ Session ended: ${JSON.stringify(handlerInput.requestEnvelope)}`);
// Any cleanup logic goes here.
return handlerInput.responseBuilder.getResponse(); // notice we send an empty response
}
};
/* *
* The intent reflector is used for interaction model testing and debugging.
* It will simply repeat the intent the user said. You can create custom handlers for your intents
* by defining them above, then also adding them to the request handler chain below
* */
const IntentReflectorHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest';
},
handle(handlerInput) {
const intentName = Alexa.getIntentName(handlerInput.requestEnvelope);
const speakOutput = `You just triggered ${intentName}`;
return handlerInput.responseBuilder
.speak(speakOutput)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
}
};
/**
* Generic error handling to capture any syntax or routing errors. If you receive an error
* stating the request handler chain is not found, you have not implemented a handler for
* the intent being invoked or included it in the skill builder below
* */
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
const speakOutput = 'Sorry, I had trouble doing what you asked. Please try again.';
console.log(`~~~~ Error handled: ${JSON.stringify(error)}`);
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse();
}
};
/**
* This handler acts as the entry point for your skill, routing all request and response
* payloads to the handlers above. Make sure any new handlers or interceptors you've
* defined are included below. The order matters - they're processed top to bottom
* */
exports.handler = Alexa.SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
StartIntentHandler,
HelloWorldIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
FallbackIntentHandler,
SessionEndedRequestHandler,
IntentReflectorHandler)
.addErrorHandlers(
ErrorHandler)
.withCustomUserAgent('sample/hello-world/v1.2')
.lambda();
動かしてみる
テストしてみる。モックがとりあえず動いた。
最後に
方向性は決まったものの、スキルとして必要最低限の機能はまだまだ足りない。
とりあえず、次は固定の質問をして、回答内容をテキスト化して、どこかでユーザが参照できるようにする。
参考
- 面接対策まとめ|よくある質問の回答例、準備~面接後のやりとり・流れ|マイナビ転職 https://tenshoku.mynavi.jp/knowhow/mensetsu
- Alexaの買い物リストとやることリストにアクセスする | Alexa Skills Kit
- https://developer.amazon.com/ja-JP/docs/alexa/custom-skills/access-the-alexa-shopping-and-to-do-lists.html