はじめに
Microsoft Bot Frameworkでは、Skypeはもちろん、FacebookやSlackともやり取りできるボットを作成することができます。そしてその他にDirect Lineというチャンネルが用意されており、これを使うとターミナルやpowershellなどのコマンドラインからボットとやり取りすることができます。ここでは、Microsoft Bot FrameowrkのDirect Lineを実際に使ってコマンドからボットと通信する手順をメモします。
できるようになること
以下のGIF画像のように、コマンドラインを通して作成したボットとやり取りすることができます。なお、以下のGIF画像で動作しているボットは、ユーザの投稿内容と同じ内容を返すエコーボットです。
また、今回関係する要素と構成のイメージ図は以下になります。自分のパソコン(図1中Laptop)から、Direct LineというMicrosot Bot Frameworkで作成したボットのチャンネルを使用して、作成したMicrosot Bot Framework上のボット(図1中 Echo bot)にメッセージを送信します。すると、Echo botがLaptopから送ったメッセージと同じ内容のメッセージを返してくれます。
図1 Microsoft Bot Framework イメージ図
前提と環境
以降の作業は、以下の環境、前提になります。
- Microsoft Azure上でEcho bot (エコーボット)作成済。詳しくは以下
- Direct Lineを使ってEcho botとやり取りする端末(図1中のLaptop)のOSはWindows10。Windows10+Vagrant+Ubuntu16.04
- Vagrant上のUbuntu16.04ではNode.jsとnpmが使用できる環境構築済
Microsoft Bot FrameworkでSkypeのエコーボットを作成する手順
Skype用のボットを作成する場合、Microsoft Bot Frameworkを使います。まず手始めとして自分の発言をそのまま返すEchoボット(エコーボット、オウム返しボット)をSkype用に作成したのでその手順をメモします。
手順概要
まずはじめに、Microsoft Bot Framework上で作成したボットに、「Direct Line」という名前のチャンネルを追加します。Microsoft Bot Frameworkでは、対応させるアプリのことをチャンネルと呼んでおり、「Direct Line」はターミナルや端末、powershell等のコマンドラインインターフェースに対応するためのチャンネルです。Microsoft Bot Frameworkで「Direct Line」を追加すると、シークレットキーが発行されるのでこれを使用します。
そしてVagrant上のUbuntu16.04から、 Microsoft Bot Framework上のボットとやり取りするためのコード(Node.jsで記述)を実行します。発行した「Direct Line」のシークレットキーはこのNode.jsのコード内で使用します。
Direct Lineチャンネルを追加する
Microsoft Azure上での作業になります。
Microsoft Azureにログインし、自身の「Web App bot」のダッシュボードに行きます。そしてメニューの中から「チャンネル」をクリックすると、以下のように地球のマークの「Direct Lineチャンネルを構成」というアイコンボタンがあるのでこれをクリックします。
クリックすると、以下のように「Direct Lineを構成」という画面が展開します。ここで、シークレットキーが2つ用意されているので、どちらか一方の「表示」をクリックして表示し、それをコピーします。コピーしたら「完了」をクリックします。なぜシークレットキーが2個用意されているかの理由についてはわかりませんでした。
なお、同じ画面で下にスクロールしていくと以下のようにバージョンがありますが、デフォルトのままで大丈夫です。
「完了」をクリックすると、以下のようにチャンネルにDirect Lineが追加されていることがわかります。 (地球マークがDirect Lineのアイコンです。)
Echo botとやり取りするための環境とNode.jsのコードを準備する
自分のパソコン上での作業になります。
必要なパッケージをインストールする
準備として、Vagrant上のUbuntu16.04で任意の場所に適当なディレクトリを作成してnpm init
で初期化します。以下ではdirectlinebot
という名前のディレクトリを作成しています。
$ mkdir directlinebot
$ cd directlinebot
$ npm init
なおnpm init
については、以下のサイトが大変参考になりました。
初心者向けにnpm initの使い方について解説しています。npm initで初期化処理を行い、package.jsonを生成する流れを説明しています。コマンドの使い方と実際に使う例を分かりやすく紹介しているので、実際に書きながら覚えていきましょう。
あとは公式ページに従い以下のように必要なパッケージをインストールします。
$ npm install --save open
$ npm install --save request
$ npm install --save request-promise
$ npm install --save swagger-client@2.1.18
上記のうち、npm install --save swagger-client@2.1.18
ではswagger-client
のバージョンを2.1.18
以下に指定しています。これは、これ以上のバージョンだと以降の作業でエラーが出てしまうためです。詳しくは後述していますのでエラーが出た方はみてみてください。
Direct Lineを使ったコードを用意する
コード自体は公式サイトに掲載されているものと全く同じになりますので、ここでは省略します。コードが掲載されているリンクはこちらです。ここのセクションのJavascriptのコードをコピーし、app.js
という名前でnpm init
や他のパッケージのインストールを行ったディレクトリ内に作成します。なお、公式サイトに掲載されているコードのうち、var directLineSecret
の値を上記の手順で取得したシークレットキーに置き換える必要があります。
var Swagger = require('swagger-client');
var open = require('open');
var rp = require('request-promise');
(...途中省略...)
// Change the Direct Line Secret to your own
var directLineSecret = 'your secret here'; // 'your secret here'を上記の手順で取得したシークレットキーに置き換える。
var directLineClientName = 'DirectLineClient';
var directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
(...途中省略...)
console.log('*' + contentLine(attachment.content.title) + '*');
console.log('*' + ' '.repeat(width) + '*');
console.log('*' + contentLine(attachment.content.text) + '*');
console.log('*'.repeat(width + 1) + '/');
}
あとは実際に実行して動作確認を行います。
動作確認する
以下のように実際に実行してみます。
$ node app.js
Command> Starting polling message for conversationId: 688383CooiCaAOS5sO4cOZfnsdf8
Command> test
You said test
少し待機すると、Command>
で入力待ち状態になり、そこで適当な文字を入力してEnterをおすと、その入力内容に対してボットが応答します。ここでは、こちらの手順で作成したエコーボットが動作しているので、自分の入力内容をそのまま応答として返します。
遭遇したエラーと解決策
swagger-clientのバージョン問題
Microsoftの公式ドキュメントには、準備として npm install --save swagger-client
を実行するように書かれていますが、2018年9月時点ではswagger-client
のバージョンとして3.8.21
がインストールされます。ただし、バージョン2と3の間で変更があったようで、その変更が原因でMicrosoft公式ドキュメントそのままのコードでは、実行時に以下のエラーが出てしまいます。
$ node app.js
Error initializing DirectLine client TypeError: Cannot read property 'add' of undefined
at /vagrant/directlinebot/app.js:22:37
at tryCatcher (/vagrant/directlinebot/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/vagrant/directlinebot/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/vagrant/directlinebot/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/vagrant/directlinebot/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/vagrant/directlinebot/node_modules/bluebird/js/release/promise.js:694:18)
at _drainQueueStep (/vagrant/directlinebot/node_modules/bluebird/js/release/async.js:138:12)
at _drainQueue (/vagrant/directlinebot/node_modules/bluebird/js/release/async.js:131:9)
at Async._drainQueues (/vagrant/directlinebot/node_modules/bluebird/js/release/async.js:147:5)
at Immediate.Async.drainQueues (/vagrant/directlinebot/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:810:20)
at tryOnImmediate (timers.js:768:5)
at processImmediate [as _immediateCallback] (timers.js:745:5)
Unhandled rejection TypeError: Cannot read property 'Conversations' of undefined
at /vagrant/directlinebot/app.js:31:12
at tryCatcher (/vagrant/directlinebot/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/vagrant/directlinebot/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/vagrant/directlinebot/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/vagrant/directlinebot/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/vagrant/directlinebot/node_modules/bluebird/js/release/promise.js:694:18)
at _drainQueueStep (/vagrant/directlinebot/node_modules/bluebird/js/release/async.js:138:12)
at _drainQueue (/vagrant/directlinebot/node_modules/bluebird/js/release/async.js:131:9)
at Async._drainQueues (/vagrant/directlinebot/node_modules/bluebird/js/release/async.js:147:5)
at Immediate.Async.drainQueues (/vagrant/directlinebot/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:810:20)
at tryOnImmediate (timers.js:768:5)
at processImmediate [as _immediateCallback] (timers.js:745:5)
調査したところswagger-client
のバージョンが2.1.18
以下でないと動作しないコードのようです。詳しくは以下に書いてありました。
client.clientAuthorizations is null · Issue #191 · Microsoft/BotBuilder-Samples · GitHub
client.clientAuthorizations is null · Issue #191 · Microsoft/BotBuilder-Samples · GitHub
実際にバージョンを指定せずにswagger-client
をインストールしてバージョンを確認してみると、3.8.21
がインストールされていることがわかります。
$ npm i swagger-client
npm WARN directlinebot@0.0.0 No description
npm WARN directlinebot@0.0.0 No repository field.
+ swagger-client@3.8.21
updated 1 package in 6.713s
よって、2.1.18
をインストールし直すか、もしくは最新のバージョン3の書き方に直すかになりますが、ここでは手っ取り早くバージョン2を使用するために以下のようにバージョンを指定してインストールし直しました。これでエラー出ずに実行できます。
$ npm install --save swagger-client@2.1.18
まとめ
コマンドライン経由で作成したボットとやりとりすることができると、ボットに所定の処理を行ってもらった結果をターミナルやPowershellで受け取って処理することができ、ボットの応用先が広がりそうです。
SPONSORED LINK