(MS謹製のbot作成フレームワーク「botbuilder」で遊んでみた! - Qiitaの続き。)
前回の記事の発展として「対話」を行ってみたいと思います。
対話(Conversation)はbotkitでも用意されているのですが、初めて見た時は大感動したものの、ちょっと癖が強くない・・?という風に感じられました。
もしコレがBotbuilderで簡単になっているなら嬉しいな・・・
公式docのCollecting Inputの内容をベースに書いてみました。
今回やること
簡単に会話(=連鎖的なやり取り、くらいの意味です)の内容を覚えてみよう〜ということでやってみます。
名前教えて→名字教えて→氏名を出力する、という非常に単純なものです。
実際に動かしてみたのが↓↓
Sessionで会話の管理
「会話を始める」「終了する」という状態を管理するために、sessionが用いられます。
Session | Bot Builder SDK Reference Library | Bot Framework
また最初にコードを見てみましょう。
var Botkit = require('botkit');
var builder = require('botbuilder');
var controller = Botkit.slackbot();
var bot = controller.spawn({
token: process.env.token
});
var slackBot = new builder.SlackBot(controller, bot);
var dialog = new builder.CommandDialog();
// 起動時のハンドリング
dialog.matches('名前おしえるね', function (session) {
if (! session.userData.firstName) {
session.beginDialog('/profile/first');
} else if(! session.userData.lastName) {
session.beginDialog('/profile/last');
} else {
session.send(session.userData.lastName + session.userData.firstName + '・・・');
session.send('覚えたぞ!!!');
}
});
// ファーストネームを聞く処理
slackBot.add('/profile/first', [
function (session) {
builder.Prompts.text(session, 'ファーストネーム教えて!!!');
},
function (session, results) {
session.userData.firstName = results.response;
session.endDialog();
}
]);
// ラストネームを聞く処理
slackBot.add('/profile/last', [
function (session) {
builder.Prompts.text(session, 'ラストネーム教えて!!!');
},
function (session, results) {
session.userData.lastName = results.response;
session.endDialog();
}
]);
slackBot.add('/', dialog);
slackBot.listen(['direct_mention']);
bot.startRTM(function(err,bot,payload) {
if (err) {
throw new Error('Could not connect to Slack');
}
});
dialog.matches('名前おしえるね', function (session){});
となっていますが、これを受けて会話シーケンスを起動します。
その中で、session.userData
の値をチェックして実行するdialogを制御しているのですね。
お察しの通り、このsession.userData
こそがユーザーとの会話を記録していく場所になります。
doc→ session.userData
もう1つの要がsession.beginDialogであり、これによって「いまどんなdialogが走っているか」が制御できるわけです。
第1引数に「どのdialogを実行するか」を渡しており、またそのdialog中でsession.endDialog()
をコールすることで会話の終了を管理するという流れです。
子dialogの方を見てみると、第2引数がリストで指定されていることが特徴です。
これによって、順番に逐次実行を行うことが可能です(Waterfall)。
まず最初に builder.Prompts.text()
で質問文を投げかけ、その後に実行される処理で入力値の受け取り→ストレージへの格納→dialogの終了処理を行っています。
この辺りは割と公式docが分かりやすかったので、目を通してみることをおすすめします。
Core Concepts | Documentation | Bot Framework
返事の内容をチェック(バリデーション)することはできるの・・?
いまいち正解がわかっていないのですが・・
たとえば「名前は5文字以上での入力を必須にしたい」、といった場合。
session.replaceDialog()
を用いて、「同じDialogに再度飛ばす」ことで実現できているように思いました。
// ファーストネームを聞く処理
slackBot.add('/profile/first', [
function (session, results) {
if (results.response.length < 5) {
session.send('名前5文字以上にしてね!!');
session.replaceDialog(this);
return;
}
session.userData.firstName = results.response;
session.endDialog();
},
function (session, results) {
session.userData.firstName = results.response;
session.endDialog();
}
]);
感想
botkitの会話より楽だと良いな・・とは冒頭で書きましたが、実際に触ってみるとこちらの方がシンプルな感じがしました!(ちょろっと触った程度ですが、回答内容のバリデーションをして引っかかったら再質問を・・という処理に難儀した記憶があります。)
また、今回は触れていませんが、Promptsには他にもconfirm()
・choice()
・time()
といったメソッドも用意されていて、自然なインターフェイスを作りやすいのではないか?という印象でした。
知見を深めたいですね・・!