LoginSignup
6
4

More than 5 years have passed since last update.

MS BotFramework(Azure Bot Service) for Node.js で使えるTips

Last updated at Posted at 2017-12-19

はじめに

  • MS BotFrameworkはMicrosoftが提供する多チャネル対応のChatBot開発Frameworkです。
  • Node.js / C# に対応しています。
  • ユーザーの状態、セッション管理やデータ管理(永続化)などが簡単に行なえます。
  • 同MicrosoftのLUISと連携させたりすれば、イケてるChatBotが作れる気がします。
  • サーバーは自前で用意する必要があります。

BotFramework for Node.jsの基本

  • npm packageのBotBuilderによって実装されている。
  • 基本はwaterflowモデルにて実行される。

waterflowモデル

  • 基本的に上のfunctionから実行されていく
  • next(result) メソッドを呼び出すと、強制的に次のfunctionへ制御が移行する。
    resultはoptionalで指定すれば次のfunctionのargsで取得可能
    nextを使用する際はfunction自体の引数にnextを含める必要がある。(2つめのfunction)
function(session, args, next) {
    session.send('次のfunctionに遷移します');
    next({'status': 'ok'});
},
function(session, result) {
    session.send('遷移しました');
    session.send('引数は' + result.status + 'です。');
}

Prompt

  • ユーザーからの入力値(選択肢)を取得するメソッド
  • promptを出すと、BOTの制御は一旦そこで止まる
  • ユーザーが何らかのアクション(文字入力、選択肢を選ぶなど)をすると、自動的に次Functionが開始する
  • ユーザーの入力値は次functionの引数に設定されている
  • テキスト入力を受け付けるには

    • builder.Prompts.text(session, messageObject) について
      • ユーザーの自由入力を待つ
      • 次functionの引数の['response']のキーに値が格納される
      • messageObjectにattachment等を設定するとリッチなUI選択肢が表示可能
  • 選択肢を提示してユーザーの選択を受け付けるには

    • builder.Prompts.choice(session, text, 'choice1|choice2|choice3', {retryPrompt: '正しい選択肢を選んで下さい'})
      • choiceはユーザーに選択肢を与える
      • 次functionの引数の['response']['entity']に選択した値が格納される
      • 選択肢はArrayも設定可能
      • retryPromptを設定すると、ユーザーが選択肢を選ばなかった場合(直接文字入力など)に表示する文言を設定可能

session

  • session内にユーザー固有の情報や、BOTの接続チャネル、今までのメッセージ履歴など多くの情報を保持している
  • 頻繁に使用するものは以下
    • session.endConversation()
      • 会話を明示的に終了する。
    • session.dialogData
      • そのDialog(後述)内でのみ有効な一時的なデータ保存領域。
      • functionを跨いでデータを保持したい場合などに使用する。
    • session.conversationData
      • その会話内で有効なデータ領域(?)
      • session.endConversation() を呼ぶとクリアされる
    • session.userData
      • ユーザー毎にデータを永続化できる保存領域。
      • どのようにしてユーザーを特定しているかは分からないが、各ユーザー毎にデータを保存しておける。
      • session.userData.hogehoge = 'hogehoge' のようにして値を格納する。
      • delete session.userData.hogehoge 削除できる。
    • session.send(message)
      • Botにmessageを発言させる。
    • session.sendTyping()
      • Botにタイピングインジケータを表示させる
      • Botが次のアクションをしたタイミングで消える
      • プラットフォームに依る(と思う)が、一定時間経過でも自動的に消える
    • session.message.address
      • このaddressをbotの発言時に付加すると、確実に対象の相手へsendできる
      • 例えば遅延処理などで自動でreplyする際などはaddress指定しないと別のユーザーと混線する

Facebook Messenger連携

  • Facebook Messenger上で表現できるUI(jsonで記述)は以下のようにして実装可能
// FacebookAPIのQuickReplyボタン(画像カスタム)を表示
var reply = new builder.Message(session).text('カスタムボタンを出します。');

reply.sourceEvent({
    facebook: {
        quick_replies: [
            {
                content_type:"text",
                title:"はい",
                payload:"ANY STRINGS",
                image_url:"https://hogehoge.com/images/yes.png"
            },
            {
                content_type:"text",
                title:"いいえ",
                payload:"ANY_STRINGS",
                image_url:"https://hogehoge.com/images/no.png"
            }
        ]
    }
});

session.send(reply);
// FacebookAPIのSendLocationボタンを表示
var reply = new builder.Message(session).text('現在地を送信するボタンを出します。');

reply.sourceEvent({
    facebook: {
        quick_replies: [{
            content_type:"location"
        }]
    }
});

session.send(reply);

dialog

  • Botの今処理している場所(状態)をdialogという表現で管理する
  • 別のDialogを開始する
    • session.beginDialog('hogehoge/dialog_name', args)
      • hogehoge/dialog_nameのdialogを開始する
      • argsは任意だが、指定すれば次dialogへ値を渡すことができる
      • dialogを開始しても後続のコードは実行されるので、以下のようなコードは注意
function(session, args) {
    session.send('次のDialogに遷移します');
    session.beginDialog('/next/start', {'status': 'ok'});

    // beginDialogの後にreturnしていないので、
    // '/next/start'のDialogが開始するのとほぼ同時に以下のコードも実行される
    session.send('次のDialogが終わりました。');
}
  • 別のDialogに置きかえる

    • session.replaceDialog('hogehoge/dialog_name', args)
      • hogehoge/dialog_nameのdialogを開始する
      • beginDialogとは違い、replaceDialogは今までのdialogStackがすべて消える
      • つまり、hogehoge/dialog_nameが終了しても元のdialogへは戻らない
  • Dialogを終了する

    • session.endDialog()
      • 今現在のdialogを終了する
      • 引数は渡せない
      • endDialogにより、一つ前のdialogの次functionから始まる
  • Dialogを終了し、戻り先に引数を渡す

    • session.endDialogWithResult(args)
      • endDialogの引数あり版
      • 一つ前のdialogの次functionから始まり、そのfunctionの引数としてargsが渡される

終わりに

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4