はじめに
はじめまして! t_powerです。
本記事では、社内FAQをBotUIでチャットボット化した話を扱います。
プログラミング知識があまりない・・・
チャットボットを作ってみたいけど難しそう・・・
と思っている人にはぴったりのツールだと思うので、是非ご覧ください!
今回作成する上で下記のサイトを参考にさせていただきました。
この記事を見て実際に作ろうと思っている方はこちらも参考にしてください。
今回作成したもの
「はじめる」と書かれているバナーからチャットボットを使うことができます。
作ろうと思った経緯
before
従来は、問い合わせをメールなどで受け付けて、担当者が直接回答をしていました。
類似の問い合わせも多く、担当者の負担になっていました。
after
それなら・・・
AIが流行っているし、問い合わせ対応をチャットボット化すればいいじゃないか!
という流れになり、チャットボットを開発することになりました。
BotUIとは
チャットボットのUIを構築するためのJavaScriptフレームワーク。直観的なJavaScript APIを使用して、メッセージを追加し、ユーザーが実行できるアクションを表示できる。
(出典: BotUI公式ドキュメント)
要するに、これを使えば、簡単にチャットボットが作れるよ~ってわけです!
チャットボットは大きく分けるとシナリオ型と**AI型(人工知能型)**の2種類存在していて、BotUIは、シナリオ型を簡単に作ることが出来るフレームワークになっています。
※シナリオ型とAI型の違いについてはこちらをご覧ください
シナリオ型・AI型のチャットボットを比較~導入メリットとシナリオ作成のコツ
チャットボット用のフレームワークやライブラリはたくさんあるようですが、今回はBotUIが適していそうだったので、こちらを採用しました。
事前準備
作業環境
OS: Windows10
テキストエディタ: Visual Studio Code
ブラウザ: Microsoft Edge
フォルダ構成
-
css/botui-theme-default.css
独自のテーマを作成することができるファイル(デザインの変更はこちらのファイルがメイン) -
css/botui.min.css
基本レイアウトを設定しているファイル(あまり書き換える必要ない)
※CSSファイルはCDN経由で読み込んでもよいのですが、今回はデザインを変更したかったため、GitHubからダウンロードしました
※とにかく動くチャットボットをはやく作りたい!デザインなんてどうでもいい!という方はダウンロードする必要はございません
-
images/sample.png
BOT側のアイコン
※もしアイコンを表示させたい場合は、こちらの任意の画像と、botui.min.cssをダウンロードして、書き換える必要があります(無くてもチャットボットは動きます) -
bot/index.html
チャットボットを表示させるファイル -
bot/answer.js
質問に対する回答をまとめたファイル -
bot/bot.js
BotUIを使ってシナリオを構成するファイル
基本的な使い方
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>チャットボット</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/botui-theme-default.css" />
<link rel="stylesheet" href="../css/botui.min.css" />
<!-- link rel="stylesheet" href="https://unpkg.com/botui/build/botui.min.css" / -->
<!-- link rel="stylesheet" href="https://unpkg.com/botui/build/botui-theme-default.css" / -->
</head>
<body>
<div id="botui-app" style="white-space:pre-wrap; word-wrap:break-word;">
<bot-ui></bot-ui>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.5/vue.min.js"></script>
<script src="https://unpkg.com/botui/build/botui.min.js"></script>
<script src="./answer.js"></script>
<script src="./bot.js"></script>
</body>
</html>
index.htmlは上記のコードをそのままコピペでOKです。
(デザインにこだわらない人は<!--link rel="stylesheet" href="https://unpkg.com/botui/build/botui.min.css" />
と<!-- link rel="stylesheet" href="https://unpkg.com/botui/build/botui-theme-default.css" / -->
のコメントを外して、お使いください)
また、Bootstrapを導入して、スマホ、PC対応のレスポンシブな画面にしてもよいかもしれません。
-
style="white-space:pre-wrap; word-wrap:break-word;"
について - CDN経由で読み込んでいるVue.jsのバージョンがなぜ最新バージョンではないのか
上記2点は苦戦した点にて記載しています。
bot.js
var botui = new BotUI('botui-app');
var Photo = '../images/sample.png'
//初期メッセージ
botui.message.add({
photo: Photo,
content: 'チャットボットです',
delay: 1000
}).then(showQuestions);
//質問の選択肢を表示する関数
function showQuestions(){
botui.message.add({
photo: Photo,
content: '質問をお選びください',
delay: 1000
}).then(function(){
return botui.action.button({
autoHide: false,
delay: 1000,
action: [
{icon: 'sticky-note-o', text: '採用', value: 'recruitment'},
{icon: 'user', text: '新入社員', value: 'newEmployee'},
{icon: 'ellipsis-h', text: 'その他', value: 'other'}]
});
}).then(function(res){
botui.action.hide();
switch(res.value){
case 'recruitment': showRecruitment(); break;
case 'newEmployee': showNewEmployee(); break;
case 'other': showOther(); break;
default: end();
}
});
}
//採用カテゴリの質問の選択肢を表示する関数
function showRecruitment(){
botui.message.add({
photo: Photo,
delay: 1000,
content: '当てはまるものをお選びください'
}).then(function(){
//ボタンを表示
return botui.action.button({
autoHide: false,
delay: 1000,
action: [
{icon: 'circle', text: '一次面接と最終面接の違い', value: 'interviewDifference'},
{icon: 'circle', text: '筆記試験の合格基準を教えていただけないでしょうか', value: 'successCriteria'},
{icon: 'long-arrow-left', text: '1つ戻る', value: 'return'}]
});
}).then(function(res){
botui.action.hide();
switch(res.value){
case 'interviewDifference': showInterviewDifference(); break;
case 'successCriteria': showSuccessCriteria(); break;
case 'return': showQuestions(); break;
default: end();
}
});
}
function showInterviewDifference(){
botui.message.add({
photo: Photo,
delay: 1000,
content: ansInterviewDifference
}).then(askEnd);
}
/*
省略
*/
//プログラムを終了するか聞く関数
function askEnd(){
botui.message.add({
photo: Photo,
delay: 2000,
content: '他に質問はありますか'
}).then(function(){
return botui.action.button({
delay: 1500,
action: [
{icon: 'circle-o', text: 'はい', value: true},
{icon: 'close', text: 'いいえ', value: false}]
});
}).then(function(res){
res.value ? showQuestions() : end();
});
}
//プログラムを終了する関数
function end(){
botui.message.add({
photo: Photo,
delay: 1500,
content: ansEnd
})
}
今回作成したシナリオはこのような構成です。
(上記のコードには記載していませんが、「新入社員」、「その他」についても、「採用」と同様に作りました)
bot.jsもphotoのパス指定だけ気を付ければ、コピペで問題ないです。
今回使用したメソッドやオブジェクトについて説明します。
method
名前 | 説明 |
---|---|
botui.message.add | 新規メッセージを追加する |
botui.action.button | ボタンを表示する |
botui.action.hide | アクションを非表示にする |
action object
名前 | 説明 |
---|---|
autoHide | 自動的に非表示になるのを防ぐ botui.action.hide()と一緒に使い、これが呼び出されたときにボタンを消す |
action | 今回はbutton objectのicon、text、valueでそれぞれ、ボタンのアイコン、表示させる文、値を設定できる また、iconはFontAwesomeを利用している botui.action.button()などと一緒に使う |
message object
名前 | 説明 |
---|---|
photo | 画像のパスを指定して、アイコンを指定 |
content | 表示されるメッセージを指定 |
delay | 表示されるまでの秒数を設定できる ※ミリ秒単位なので、1000は1秒にあたる |
他のメソッドやオブジェクトに関してはこちらをご覧ください。
}).then(function(res){
botui.action.hide();
switch(res.value){
case 'recruitment': showRecruitment(); break;
case 'newEmployee': showNewEmployee(); break;
case 'other': showOther(); break;
default: end();
}
});
選択した項目からチャットを進めていくために、switch文で条件分岐させ、選択したボタンのvalue
をres
で取得し、それに合った関数を呼び出しています。
//プログラムを終了するか聞く関数
function askEnd(){
botui.message.add({
photo: Photo,
delay: 2000,
content: '他に質問はありますか'
}).then(function(){
return botui.action.button({
delay: 1500,
action: [
{icon: 'circle-o', text: 'はい', value: true},
{icon: 'close', text: 'いいえ', value: false}]
});
}).then(function(res){
res.value ? showQuestions() : end();
});
}
プログラムを終了するか聞く関数のaskEnd()では、「はい」か「いいえ」の2択しかないため、3項演算子を使用して分岐させています。
?の左側res.value
がtrueならshowQuestions()
、falseならend()
を呼び出します。
answer.js
回答メッセージの変数をまとめたファイルです。
後で、回答メッセージをDBから取得するように改修する予定なので、一旦別ファイルに分けて宣言をしています。
var ansInterviewDifference = `一次面接は採用担当が実施します。
最終面接は社長が実施します。`
/*
省略
*/
var ansEnd = `ご利用いただきありがとうございました。
[TOPページへ戻る](http://xxx.xxx.xx.xxx)`
このように、質問に対する回答をまとめています。
また、表示させるメッセージについては、`(バッククォート)で囲むことで、実際にファイルに記載したようにメッセージボックスにも表示されるようになります。
[TOPページへ戻る](http://xxx.xxx.xx.xxx)
については、苦戦した点にて記載します。
<script src="./answer.js"></script>
<script src="./bot.js"></script>
今回のように別のjsファイルに質問に対する回答をまとめる場合、index.html
で先に回答ファイルanswer.js
を読み込む必要があるので注意!
苦戦した点
指定した場所で改行できない
<div class="container" id="botui-app" style="white-space:pre-wrap; word-wrap:break-word;">
var ansEnd = `ご利用いただきありがとうございました。
[TOPページへ戻る](http://xxx.xxx.xx.xxx)`
メッセージ内で\n
や\r\n
などの改行コードを試してもうまくいかず・・・
色々調べてみると・・・
Vue.jsで文字列を改行する場合
style="white-space:pre-wrap; word-wrap:break-word;"
bot-uiタグが囲まれているdivタグの中にこれを記載し、先ほどanswer.jsで紹介したメッセージの内容を`(バッククォート)で囲む必要があるみたいです。
参考記事
Vue.jsでdataの文字列を改行したい
HTMLクイックリファレンス white-space
HTMLクイックリファレンス word-wrap
リンク化できない
<!-- これだとリンク化できない -->
<script src="https://cdn.jsdelivr.net/vue/latest/vue.min.js"></script>
<!-- 2.0.5にすることでリンク化できる -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.5/vue.min.js"></script>
公式ガイドに記載されている通り、Vue.jsの最新バージョンをCDN経由で読み込んでいました。しかし、その場合URLの後に別のメッセージが表示されると、リンク化されなくなってしまうみたいです。
この問題を解決するためには、Vue.jsのバージョンを2.0.5に落とすことで、どのような状況でもリンク化されるようになります。
参考記事
URL loses its markup in javascript framework (BotUI)
URLを新規タブで展開できない
var ansEnd = `ご利用いただきありがとうございました。
[TOPページへ戻る](http://xxx.xxx.xx.xxx)`
[表示文字](URL)で指定すると、同じタブで画面が切り替わってしまって、チャットボットが閉じてしまいます。
var newline = `[BotUI 公式マニュアル](https://docs.botui.org/index.html)^`
新規タブで展開するには、カッコの後ろに^(キャレット)を付けることで解決できました。
デザイン
今回デザインを変更するために、GitHubからダウンロードして読み込んだ、
botui.theme-default.cssとbotui.min.cssで重要だと思った点を紹介します。
botui.theme-default.css
.botui-cotainer
.botui-container{
font-size:14px;
background-color:#fff;
font-family:"Open Sans",sans-serif
}
-
font-size
メッセージの文字やボタンの文字の大きさを指定 -
background-color
チャット背景色を指定 -
font-family
フォントを指定(フォントファミリーと総称フォントの2つがある)
.botui-messages-container
.botui-messages-container{
padding:10px 20px
}
- padding
メッセージのパディングを指定
.botui-actions-container
.botui-actions-container{
padding:0px 20px
}
- padding
アクション(今回はボタン)のパディングを指定
.botui-message
.botui-message{
min-height:30px
}
- min-height
メッセージ間の最小幅を指定
.botui-message-content
.botui-message-content{
padding:7px 13px;
border-radius:15px;
color:#000000;
background-color:#8bf8f8
}
-
padding
メッセージ領域内のパディングを指定 -
color
BOT側(左側)に表示されるメッセージの色を指定 -
background-color
BOT側(左側)に表示されるメッセージ領域内の背景色を指定
※border-radiusは外枠の丸み具合を変更するプロパティだが、ここで値を変更しても変わりませんでした(メッセージの要素内を変更するプロパティだから効かない?)
.botui-message-content.human
.botui-message-content.human{
color:#000000;
background-color:#f8ddaa
}
-
color
人間側(右側)に表示されるメッセージの色を指定 -
background-color
人間側(右側)に表示されるメッセージ領域内の背景色を指定
.botui-message-content.text
.botui-message-content.text{
line-height:150%
}
- line-height
メッセージ領域内の行間の高さを指定
.botui-message-content.embed
.botui-message-content.embed{
padding:5px;
border-radius:5px
}
-
padding
動画のパディングを指定 -
border-radius
外枠の丸みを指定
.botui-message-content-link
.botui-message-content-link{
color:#1A0DAB
}
- color
リンクの色を指定
.botui-actions-buttons-button
.botui-actions-buttons-button{
border:1;
color:#fff;
line-height:1;
cursor:pointer;
font-size:14px;
font-weight:normal;
padding:10px 20px;
border-radius:4px;
font-family:"Open Sans",sans-serif;
background:#777979;
box-shadow:2px 3px 4px 0 rgba(0,0,0,.25)
}
-
cursor
ボタンにカーソルを合わせたときの種類を指定 -
font-weight
ボタンの文字の太さを指定
botui.min.css
.botui-message-content
.botui-message-content{
width:auto;
max-width:80%;
display:inline-block
}
- max-width
メッセージボックスの幅を指定
.profil
.profil{
position:relative;
top: -10px;
border-radius:50%
}
- top
基準の位置からどれくらい上に動かすかを指定
※元々topプロパティは無かったが、アイコンを大きくしたらズレてしまったので、追記して丁度いい位置にくるように指定しました
.profil>img
.profil>img{
width:50px;
height:50px;
border:2px solid #e8e8e8
}
-
width
アイコン画像の幅を指定 -
height
アイコン画像の高さを指定
.profil>img.agent
.profil>img.agent{
/*初期設定だと変な画像になっているため、削除推奨
content:url(http://decodemoji.com/img/logos/blue_moji_hat.svg);
*/
border-radius:50%
}
- content
ここで画像指定していると、photoで表示したい画像を選んでもBOT側のアイコンは強制的にここで設定している画像になるため、削除推奨
おまけ
YouTube動画の埋め込み方
今回作成したチャットボットでは使用していませんが、試したので記載します。
botui.message.add({
type: 'embed',
content: 'https://www.youtube.com/embed/1oSeywNsjak',
delay: 1000
}).then(showQuestions);
YouTubeの動画を埋め込む際に注意する必要があります。
embedは外部要求を許可しているが、watchは許可していないため、URLを書き換える必要があります。
× https://www.youtube.com/watch?v=1oSeywNsjak
○ https://www.youtube.com/embed/1oSeywNsjak
参考記事
youtube html 埋め込み
おわりに
JavaScript初心者でも、BotUIを使うことで、簡単にシナリオ型のチャットボットを作ることが出来ました。
直観的に操作することが出来るので、プログラミングがよくわからなくても、それっぽいものを作れてしまうのが、BotUIのいいところだと思いました。
しかし、数が増えるとボタンも増える(分岐が増えてしまう)ため、見栄えがとても悪くなってしまいます。そのため、今後はAI型にシフトさせるなどの対策が必要だと思いました。
最後まで読んでいただき、ありがとうございました