概要
JavaScriptでチャットボットのUIを爆速で作るためのガイドです。
- スマートフォン および PCブラウザ に両対応
- scriptタグを1つ入れるだけで既存のコンテンツをジャマしないチャットUI
2024年3月更新 : LLM(大規模言語モデル) を用いてトークンを逐次生成するストリーミングチャットを構築したいときは 本稿の手法よりも (株)Qualiteg 提供の ChatStream のほうがオススメです
対象読者
- Java Scriptが書ける人(初心者でもOK)
- node.js環境がある人(npmまたはyarnが使える)
- チャットボットに興味がある人
できること
以下のデモのようなPCブラウザとスマホに両対応したチャットボットUIを作ります
スマホの場合は画面にフィットしたチャットUI、PCブラウザの場合はフローティングする小窓にチャットUIを表示します。これを実現するためにどのような技術を使っているかは記事本編にて説明します。
- 選択肢を選択していくタイプのチャットボット
デモ 「クイズボット」
https://riversun.github.io/chatux/ja/quizbot/app/
モバイルで表示 | PCブラウザで表示 |
- テキストを入力するタイプのチャットボット
デモ 「トークボット」
https://riversun.github.io/chatux/ja/talkbot/app/
本編
チャットUIは見た目、チャットサーバーは頭脳に相当する。本稿はチャットUI=見た目に関する内容がメインとなる。
構成
前述のとおり、本稿で紹介するチャットボットは以下のようにチャットUIの部分とチャットサーバー部分の2つのパートで構成されている。
仕組みはシンプルで、ユーザーがチャットUIに入力するとサーバーにテキストが送信され、サーバー側で応答を生成してJSONとして返す。
エコーをかえすだけの簡単なチャットボット
さっそくエコー(自分が書いたテキストをそのまま返す)を返すチャットボットをつくる。
先に完成版デモ。
エコーするだけのチャット
https://riversun.github.io/chatux/ja/echobot/app/chat.html
エコーチャット用のUIを作る
まず、以下の図の左側に相当するチャットUIをさくっと作る
以下のindex.htmlをローカルに保存して実行するだけで、エコーチャットボットを試すことが可能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>エコーボット</title>
</head>
<body>
<script src="https://riversun.github.io/chatux/chatux.min.js"></script>
<script>
const chatux = new ChatUx();
//ChatUXの初期化パラメータ
const initParam =
{
renderMode: 'auto',
api: {
//echo chat server
endpoint: 'https://script.google.com/macros/s/AKfycbzro2SWVx5lMKfbLu4cBt16xbqg4lT7xU5wfu4bbSQs-OMcFsQh/exec',
method: 'GET',
dataType: 'jsonp'
},
bot: {
botPhoto: 'https://riversun.github.io/chatbot/bot_icon_operator.png',
humanPhoto: null,
widget: {
sendLabel: '送信',
placeHolder: '何か話しかけてみてください'
}
},
window: {
title: 'エコーボット',
infoUrl: 'https://github.com/riversun/chatux'
}
};
chatux.init(initParam);
chatux.start(true);
</script>
</body>
</html>
早速このindex.htmlをブラウザで開いてみるとこの通り実行できる。
さて、このコードの重要なところを見ていきたい
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
モバイル表示用に典型的なビューポート制御のmetaタグをいれる。
<script src="https://riversun.github.io/chatux/chatux.min.js"></script>
チャットUI表示用ライブラリ**ChatUx**を読み込む。
このライブラリが今回のミソ。
今は手っ取り早くindex.html内にscriptタグでリンクするが、後で1つのjsファイルにバンドルする。
const chatux = new ChatUx();
まずChatUxインスタンスを作る。
次にChatUxの初期化パラメータ(initParam)を見ていく。
renderMode: 'auto',
api: {
endpoint: 'https://script.google.com/macros/s/AKfycbzro2SWVx5lMKfbLu4cBt16xbqg4lT7xU5wfu4bbSQs-OMcFsQh/exec',
method: 'GET',
dataType: 'jsonp'
}
-
renderMode・・・チャットUIのレンダリングモード
- auto・・・スマホとPCを自動判定して最適なUIを表示する
- pc・・・強制的にPC用のレイアウト(小窓)を表示する
- mobile・・・強制的にスマホ用のレイアウトを表示する
-
api
-
endpoint・・・チャットサーバーのAPIエンドポイント。
ここではデモ用APIサーバーのURLを指定(次章で自前サーバーの例を示す) - method・・・チャットサーバーにアクセスするときのHTTPメソッド。ここではGETメソッドを指定。
- dataType・・・チャットサーバーにAjaxアクセスするときの方法をjsonまたはjsonpで指定。
-
endpoint・・・チャットサーバーのAPIエンドポイント。
初期化パラメータの続きをみていく
bot: {
botPhoto: 'https://riversun.github.io/chatbot/bot_icon_operator.png',
humanPhoto: null,
widget: {
sendLabel: '送信',
placeHolder: '何か話しかけてみてください'
}
},
- bot
window: {
title: 'エコーボット',
infoUrl: 'https://github.com/riversun/chatux'
}
chatux.init(initParam);
chatux.start(true);
-
**chatux.init(param)**で、上の初期化パラメータを適用する
-
chatux.start(true)でチャットUIを有効化する。
引数にtrueを指定すると、チャットUIが自動的に表示される。
引数にfalseを指定するか無指定の場合は、画面右下のチャット起動ボタンを押すとチャットUIが起動する。
ここまでで、ざっくり、お手軽にチャットボットUIを作れることをみてきた。
今は、デモ用のサーバーを指定したが、次はサーバーを自作してみる。
チャット用のサーバーをつくる
次は、下図の右側に相当するチャットサーバーを作る
コマンドラインからサーバー用のnpmプロジェクトを準備する
mkdir chatserver
cd chatserver
npm init
(いろいろ聞かれるが、エンターを10回たたけばOK)
npm install express
これでnode環境でサーバーをつくる準備ができたので、いまつくった chatserver ディレクトリに server.jsというファイルを作って、以下のコードを書く。
const express = require('express');
const app = express();
const port = 8080;
// CORSを有効にする
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept');
next();
});
app.get('/chat', function (req, res) {
const userInputText = req.query.text;
const callback = req.query.callback;
const response = {output: []};
const msg = response.output;
msg.push({
type: 'text',
value: '「' + userInputText + '」ですね!'
});
if (callback) {
const responseText = callback + '(' + JSON.stringify(response) + ')';
res.set('Content-Type', 'application/javascript');
res.send(responseText);
} else {
res.json(response);
}
});
app.listen(port, () => {
console.log('チャットサーバーを開始しました ポート番号:' + port);
});
ソースを簡単に説明する
const express = require('express');
const app = express();
const port = 8080;
チャットサーバーは入力したテキストに応じてJSON応答を返せれば何でもOK。
ここではexpressを使う。
app.get('/chat', function (req, res) {
const userInputText = req.query.text;
const callback = req.query.callback;//jsonp対応
const response = {output: []};
const msg = response.output;
msg.push({
type: 'text',
value: '「' + userInputText + '」ですね!'
});
if (callback) {
const responseText = callback + '(' + JSON.stringify(response) + ')';
res.set('Content-Type', 'application/javascript');
res.send(responseText);
} else {
res.json(response);
}
});
ここで /chat?text=こんにちはのようにアクセスがあったときに以下のようなJSONを返すようにする。
{
"output":[
{
"type":"text",
"value":"「こんにちは」ですね!"
}
]
}
さて、サーバーができたので以下のコマンドでサーバーを起動する。
node server.js
チャットサーバーを開始しました ポート番号:8080
本節のソースコード一式
本節で説明したチャットサーバーのソースコード
https://github.com/riversun/chatux-examples-ja/tree/v1.0.0/step01/chatserver
さきほどのindex.html内のコードを以下のように修正して、チャットサーバーのURLをいま作ったサーバーのURLに変更する
●変更前
api: {
endpoint: 'https://script.google.com/macros/s/AKfycbzro2SWVx5lMKfbLu4cBt16xbqg4lT7xU5wfu4bbSQs-OMcFsQh/exec',
method: 'GET',
dataType: 'jsonp'
}
↓↓↓
●変更前後
api: {
endpoint: 'http://localhost:8080/chat',
method: 'GET',
dataType: 'json'
},
つまりindex.html全体は以下のようになる
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>エコーボット</title>
</head>
<body>
<script src="https://riversun.github.io/chatux/chatux.min.js"></script>
<script>
const chatux = new ChatUx();
//ChatUXの初期化パラメータ
const initParam =
{
renderMode: 'auto',
api: {
//echo chat server
endpoint: 'http://localhost:8080/chat',
method: 'GET',
dataType: 'jsonp'
},
bot: {
botPhoto: 'https://riversun.github.io/chatbot/bot_icon_operator.png',
humanPhoto: null,
widget: {
sendLabel: '送信',
placeHolder: '何か話しかけてみてください'
}
},
window: {
title: 'エコーボット',
infoUrl: 'https://github.com/riversun/chatux'
}
};
chatux.init(initParam);
chatux.start(true);
</script>
</body>
</html>
上のindex.htmlをブラウザで開いてみると、このとおりローカルで開いたチャットサーバーに応答している。
本節のソースコード一式
本節で説明したindex.htmlのソースコード
https://github.com/riversun/chatux-examples-ja/blob/v1.0.0/step01/chatclient/index.html
【ご参考】チャットサーバーを無料公開する
Google Apps Script(GAS) を使えば無料で上記チャットサーバー相当の機能を公開できる。
-
GASでWeb APIサーバーを公開する方法は以下の記事をご参照。
今から10分ではじめる Google Apps Script(GAS) で Web API公開 -
以下にGAS用のコードも掲載する。express版のコードと多少の違いはあるがJavaScriptが読める人なら特に苦労は無いはず。
function doGet(e) {
var userInputText = e.parameter.text;
var callback = e.parameter.callback;
var response = {output: []};
var msg = response.output;
msg.push({
type: 'text',
value: '「' + userInputText + '」ですね!'
});
var responseText = '';
if (callback) {
//JSONP
responseText = callback + '(' + JSON.stringify(response) + ')';
return send(ContentService.MimeType.JAVASCRIPT, responseText);
} else {
//JSON
return sendJson(response);
}
}
function send(mimeType, responseText) {
var textOut = ContentService.createTextOutput();
textOut.setMimeType(mimeType);
textOut.setContent(responseText);
return textOut;
}
function sendJson(response) {
var textOut = ContentService.createTextOutput();
var responseText = JSON.stringify(response);
textOut.setMimeType(ContentService.MimeType.JSON);
textOut.setContent(responseText);
return textOut;
}
本節のソースコード一式
本節で説明したGASによるチャットサーバーのソースコード
https://github.com/riversun/chatux-examples-ja/tree/v1.0.0/step01/chatserver4gas
チャットUIのいろんな表現に対応する
ここからは、チャットUIにボタンや画像を表示させてみる。
基本的にチャットUIはサーバーからのレスポンスに応じてレンダリングされるので、チャットサーバー側を変更する。
オプションボタンを表示
前出のチャットサーバーを編集して以下のようなオプションボタン(選択肢)を表示してみる
コードの全体像はこんな感じで、
const express = require('express');
const app = express();
const port = 8080;
// CORSを有効にする
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept');
next();
});
app.get('/chat', function (req, res) {
const userInputText = req.query.text;
const callback = req.query.callback;
const response = {output: []};
const msg = response.output;
if (userInputText == 'ボタン') {
msg.push({
type: 'text',
value: '好きな動物は?',
delayMs: 500 //表示ディレイ(ミリ秒)
});
//オプションボタンを作る
const opts = [];
opts.push({label: 'イヌ', value: '犬'});
opts.push({label: 'ネコ', value: '猫'});
opts.push({label: 'ウサギ', value: '兎'});
msg.push({type: 'option', options: opts});
} else {
msg.push({
type: 'text',
value: '「' + userInputText + '」ですね!'
});
}
if (callback) {
const responseText = callback + '(' + JSON.stringify(response) + ')';
res.set('Content-Type', 'application/javascript');
res.send(responseText);
} else {
res.json(response);
}
});
app.listen(port, () => {
console.log('チャットサーバーを開始しました ポート番号:' + port);
});
ポイントはここ
const response = {output: []};
const msg = response.output;
if (userInputText == 'ボタン') {
msg.push({
type: 'text',
value: '好きな動物は?',
delayMs: 500 //表示ディレイ(ミリ秒)
});
//オプションボタンを作る
const opts = [];
opts.push({label: 'イヌ', value: '犬'});
opts.push({label: 'ネコ', value: '猫'});
opts.push({label: 'ウサギ', value: '兎'});
msg.push({type: 'option', options: opts});
}
**type:'text'**として「好きな動物は?」のテキストを表示している
その次に、
**type:'option'**で、optionsにオプションボタンをコードのように設定する。
delayMs:500で表示の遅延時間(ミリ秒)を設定することができる。複数のメッセージ(たとえば、テキストとボタンと画像)を同時に出したいときは、それぞれに遅延時間を指定すればユーザーがメッセージを読むスピードにあわせて1件ずつ順番にメッセージを表示できる。
opts.push({label: 'イヌ', value: '犬'});
オプションボタンは何個でも設定可能。
オプションボタンがクリックされると、valueに指定された値がテキストを入力されたのと同じになる。
早速index.htmlを開いて動作を確認してみる。
if (userInputText == 'ボタン') {
としているので、
チャットが開いたら「ボタン」と入力する。すると、以下のとおりレンダリングされる。
画像を表示
次は画像を表示させる。
サーバーのコードに以下を追加する。
else if (userInputText == '画像') {
msg.push({
type: 'text',
value: '画像を表示します',
delayMs: 500
});
msg.push({
type: 'image',
value: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Kaiserpinguinjunges.jpg/800px-Kaiserpinguinjunges.jpg'
});
**type:'image'**とすると、画像を表示できる
**value:[画像のURL]**で表示したい画像を指定する
server.jsを更新してチャットサーバーを再起動したあと、index.htmlを開いて、「画像」と入力すると、以下のように画像を表示できる。
本節のソースコード一式
本節で説明したチャットUIの色々な表現に対応したチャットサーバーのソースコード
https://github.com/riversun/chatux-examples-ja/tree/v1.0.0/step02/chatserver
バンドルjsをつくって、チャットUI関連処理を1つのjsファイルにする
さて、いままではindex.htmlの中にChatUXモジュールを<script src="https://riversun.github.io/chatux/chatux.min.js"></script>
のようにscriptタグをリンクし、さらにチャットUIのコードも<script><script>
に書いてきたが、これをwebpackで1つのjsファイルにバンドルする。
さっそく、チャットUIのバンドルjsをつくるためのnpmプロジェクトを作る
mkdir chatclient
cd chatclient
npm init
(エンター10回でOK)
必要モジュールのインストール
まず、チャットUIのコアモジュールChatUxからインストール
npm install --save chatux
次は、モジュールをバンドルするためにwebpackをインストール
npm install --save-dev webpack webpack-cli webpack-dev-server
最後に、ES6をES5に変換するためにbabelをインストール
npm install --save-dev @babel/core @babel/preset-env babel-loader
これで必要なモジュールがインストールできた。
この状態で、package.jsonは以下のようになる
{
"name": "chatclient",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"chatux": "^1.1.0"
},
"devDependencies": {
"@babel/core": "^7.4.0",
"@babel/preset-env": "^7.4.2",
"babel-loader": "^8.0.5",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.2.1"
}
}
次に、srcディレクトリをつくって、そこにindex.jsをつくり、jsのソースコードを書く。
import {ChatUx} from 'chatux';
const chatux = new ChatUx();
const initParam =
{
renderMode: 'auto',
api: {
//echo chat server
endpoint: 'http://localhost:8080/chat',
method: 'GET',
dataType: 'json'
},
bot: {
botPhoto: 'https://riversun.github.io/chatbot/bot_icon_operator.png',
humanPhoto: null,
widget: {
sendLabel: '送信',
placeHolder: '何か話しかけてみてください'
}
},
window: {
title: '新エコーボット',
infoUrl: 'https://github.com/riversun/chatux'
}
};
chatux.init(initParam);
chatux.start(true);
ソースを書いたら、これをコンパイル(トランスパイル)してバンドルjsをつくるためにwebpackの設定をする。
webpack.config.jsをルートディレクトリにつくる。
ちなみに、いまディレクトリはこうなっている。
chatclient
├── src
│ └── index.js
├── node_modules
├── package.json
├── package-lock.json
└── webpack.config.js(いまからここを作業する)
webpack.config.jsは以下のとおり。
const path = require('path');
module.exports = (env, argv) => {
const conf = {
mode: 'development',
devServer: {
open: true,
openPage: 'index.html',
contentBase: path.join(__dirname, 'public'),
watchContentBase: true,
port: 3000,
disableHostCheck: true
},
entry: {chat: './src/index.js'},
output: {
path: path.join(__dirname, 'public'),
publicPath: '/',
filename: `[name].js`
},
module: {
rules: [{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: [{
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env',
{
'modules': 'false',
'useBuiltIns': 'usage',
"corejs": 3,
'targets': '> 0.25%, not dead'
}]]
}
}]
}]
}
};
return conf;
};
次にpackage.jsonにwebpackでindex.jsをコンパイルするための起動スクリプトを追加する
scripts以下にstart、start:web、build:webをそれぞれ追加する。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server",
"build:web": "webpack --config webpack.config.js --mode production"
},
startはデバッグ用途でwebpack-dev-serverを起動するため、
build:webはindex.jsをコンパイルして必要モジュールが入ったバンドルchat.jsを生成するためのコマンド
さて、最後にpublicディレクトリをつくりその下に、index.htmlを作る。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>新エコーボット</title>
</head>
<body>
<script src="chat.js"></script>
</body>
</html>
ここまでのディレクトリ構成は以下のとおり
chatclient
├── public
│ └── index.html
├── src
│ └── index.js
├── node_modules
├── package.json
├── package-lock.json
└── webpack.config.js
さきほどと同様、チャットサーバーをローカルに起動しておきつつ、いまつくったindex.htmlをwebpack-dev-serverでホストして実行する。
npm start
これでindex.htmlの中に<script src="chat.js"></script>
をリンクしただけで無事起動した
バンドルjsを生成したい場合は
npm run build:web
を実行すると、必要モジュールがすべてバンドルされたjsファイルchat.jsが生成される。
chatclient
├── public
│ ├── chat.js (←いま生成されたバンドル)
│ └── index.html
├── src
│ └── index.js
├── node_modules
├── package.json
├── package-lock.json
└── webpack.config.js
ここまでで、チャットサーバーの作り方、チャットUIのバンドルの作り方をみてきたので、これでscriptタグを1ついれるだけで既存のWebコンテンツをジャマしない形でチャットUIを実現できる。
本節のソースコード一式
本節で説明した1つのjsにバンドルするチャットUIのnpmプロジェクトソースコード
https://github.com/riversun/chatux-examples-ja/tree/master/step03/chatclient
カスタマイズと応用
チャットUIの見た目や挙動はカスタマイズ可能。またサーバー側を作り込めばチャットボットやチャットサービスを作成することが可能となる。
チャットUI側の初期化パラメータの設定例
初期化パラメータで、チャットUIのウィンドウの見た目や各種コールバックイベントのハンドリング関数を指定できる。
import {ChatUx} from 'chatux';
const chatux = new ChatUx();
//初期化パラメータ
const initParam = {
//auto:PCとスマホを自動判定、pc:強制的にPCモード、mobile:強制的にスマホモード
renderMode: 'auto',
//true:チャットUIが開いたら、チャット起動ボタンを消す(pcモードのみ有効)
buttonOffWhenOpenFrame: false,
bot: {
//チャットUI起動時に自動的にサーバーに送るテキスト
wakeupText: null,
//ボット側のアイコン画像URL
botPhoto: 'https://riversun.github.io/chatbot/bot_icon_operator.png',
//ユーザー側のアイコン画像URL
humanPhoto: null,
widget: {
//SENDボタンのラベル
sendLabel: '送信',
//テキストボックスのヒント
placeHolder: ''
}
},
api: {
//チャットサーバーのURL
endpoint: 'http://localhost:8080/chat',
//'GET'または'POST'
method: 'GET',
//'json'または'jsonp'
dataType: 'json',
errorResponse: {
output: [
//ネットワークエラー発生時のエラーメッセージ
{type: 'text', value: 'ネットワークエラーが発生しました'}
]
}
},
//PCモードの場合に表示される小窓(ウィンドウ)の設定
window: {
//ウィンドウのタイトル
title: '私のチャットボット',
//チャットウィンドウ左上のアイコンをクリックしたときにジャンプするURL
infoUrl: 'https://github.com/riversun/chatux',
size: {
width: 350,//ウィンドウの幅
height: 500,//ウィンドウの高さ
minWidth: 300,//ウィンドウの最小幅
minHeight: 300,//ウィンドウの最小高さ
titleHeight: 50//ウィンドウのタイトルバー高さ
},
appearance: {
//ウィンドウのボーダースタイル
border: {
shadow: '2px 2px 10px rgba(0, 0, 0, 0.5)',//影
width: 0,//ボーダーの幅
radius: 6//ウィンドウの角丸半径
},
//ウィンドウのタイトルバーのスタイル
titleBar: {
fontSize: 14,
color: 'white',
background: 'black',
leftMargin: 40,
height: 40,
buttonWidth: 36,
buttonHeight: 16,
buttonColor: 'white',
buttons: [
//閉じるボタン
{
//閉じるボタンのアイコン(fontawesome)
fa: 'fas fa-times',
name: 'hideButton',
visible: true //true:表示する
}
],
buttonsOnLeft: [
//左上のinforUrlボタン
{
fa: 'fas fa-comment-alt',//specify font awesome icon
name: 'info',
visible: true //true:表示する
}
],
},
}
},
//チャット起動ボタンの位置
wakeupButton: {
right: 20,
bottom: 20,
size: 60,
fontSize: 25//フォントサイズ
},
//イベントのコールバックメソッド
methods: {
onChatWindowCreate: (win) => {
//チャットUIが生成された時
},
onChatWindowPause: (win) => {
//チャットUIが閉じられた時
},
onChatWindowResume: (win) => {
//チャットUIが復帰した時
},
onUserInput: (userInputText) => {
//ユーザーがテキストを入力したとき
//(テキストをインターセプトする)
console.log('#onUserInput userInputText=' + userInputText);
if (userInputText === 'おしまい') {
//チャットUIを終了する
chatux.dispose();
//consumed=trueで返すと、テキストはサーバーには送信されない
const consumed = true;
return consumed;
}
},
onServerResponse: (response) => {
//チャットサーバーのレスポンスを受け取った時
//レンダリング前なのでresponseを編集するとレンダリング結果を変更できる
console.log('#onServerResponse response=' + JSON.stringify(response));
return response;
}
}
};
chatux.init(initParam);
//trueを指定すると、チャットUIを自動的に開く
chatux.start(true);
見た目、スタイリング
チャット起動ボタンやチャットUI内部はCSSでスタイリングが可能
上の例では、以下のようなCSSを指定している
.chatux-btn-chat {
color: #fff;
background-color: black;
border-color: black;
}
.chatux-btn-chat:hover {
background-color: black;
border-color: black;
}
.botui-container {
font-size: 14px;
background-color: #7193c1;
font-family: "Open Sans", sans-serif;
}
.botui-actions-text-input {
border: 0;
outline: none;
border-radius: 0;
padding: 5px 7px;
font-family: "Open Sans", sans-serif;
background-color: transparent;
color: white;
width: 70%;
border-bottom: 2px solid white;
}
CSSのコードはこちら
CSSによるスタイリングのより詳細な設定例
【チャットUIの外側】
https://github.com/riversun/chatux/blob/master/src/app.css
【チャットUIの内側(botUI)】
https://github.com/riversun/chatux/blob/master/src/botui-theme-riversun.css
本節のソースコード一式
本節で説明した見た目スタイリングをカスタムしたnpmプロジェクトのソースコード
(+サーバーとクライアントを1つのnpmプロジェクトに統合)
https://github.com/riversun/chatux-examples-ja/tree/master/step04/chatall
ChatUxを構成している要素技術
これまでみてきたチャットUIをお手軽に実現するChatUxモジュールでは以下のライブラリを内部で利用しているので興味があれば、以下リポジトリが参考になる
- チャットUI表示 https://github.com/botui/botui
- 小窓表示(PCモード時) https://github.com/riversun/JSFrame.js
チャットサーバー側のカスタムについて
- 今回はサーバー側は触り程度の説明だったが、セッション機能を利用すればステートフルなチャットボット、チャットサービスをつくることが可能だし、認証機能を入れれば、ユーザーにあったチャットコンテンツを提供することも可能になる。
- お試し程度であればさきほど紹介したGASも地味に便利
人工無脳からAIチャットサーバーへ
- 今回の例ではIF文をつかった原始的な対話をサンプルとして紹介した
- 手続き型の対話であれば Watson などを使ってテキスト→意図分類→対話応答生成という手順で設計すれば本格的な対話アプリは作れるし、WatsonつかわなくてもNLP系のライブラリは最近充実してきているので、それらを活用すればそれっぽいチャットボットを作ることも可能。
ご参考
Watsonをモチーフにして、対話アプリを解説した記事
クエリーパラメータやHTTPヘッダの付加
クライアントからチャットサーバー側に追加のクエリパラメータや、HTTPヘッダを送信する事も可能
HTTPヘッダの追加方法
クライアントからサーバーへの送信時にHTTPヘッダを追加するには以下のように、初期化時に、headersを設定する
chatux.init({
api: {
endpoint: 'http://localhost:8080/chat',
method: 'GET',
dataType: 'json',
headers:{
'Authorization':'Bearer ABCD123ABCD123ABCD123',
'X-Additional-Headers':'something_value'
}
}
});
初期化時ではなく、送信時にHTTPヘッダを追加することも可能
認証情報を付加したい場合などで活用できる
以下のようにする
onPrepareRequestは通信の直前に呼び出されるので、そこでhttpClient.headersに追加したいヘッダ情報を入れてやればOK
chatux.init({
api: {
endpoint: 'http://localhost:8080/chat',
method: 'GET',
dataType: 'json',
},
methods:{
onPrepareRequest: (httpClient) => {
httpClient.headers={};
httpClient.headers['Authorization'] = 'Bearer ABCD123ABCD123ABCD123';
httpClient.headers['X-Additional-Headers'] = 'something_value';
}
}
});
クエリパラメータ追加方法
現状は送信ボタンをおすと、指定したURLにGETまたはPOSTで**http://localhost:8080/chat?text=こんにちは**のように送信するが、**text**以外のクエリを追加することが可能。
固定的にクエリパラメータを設定するには初期化時に以下のようにparamsに設定すると
chatux.init({
api: {
endpoint: 'http://localhost:8080/chat',
method: 'GET',
dataType: 'json',
params:{
'param1':'value1',
'param2':'value2'
}
}
});
**http://localhost:8080/chat?text=こんにちは¶m1=value1¶m2=value2**のように送信される。
また、送信時にクエリを指定するには以下のように書くことも可能
chatux.init({
api: {
endpoint: 'http://localhost:8080/chat',
method: 'GET',
dataType: 'json',
},
methods:{
onPrepareRequest: (httpClient) => {
//intercept http request before sending and set query parameters
httpClient.params.param1 = 'value1';
httpClient.params.param2 = 'value2';
},
onFinishRequest: (httpClient) => {
//delete params after sending
delete httpClient.params.param1;
delete httpClient.params.param2;
}
}
});
onPrepareRequestは通信の直前に呼び出されるためhttpClient.paramsオブジェクト以下に追加したいクエリパラメータを付加すればOK
httpClient.paramsはチャットを通じて保持されるため、↓のように毎回の通信にparamsをのせたく無い場合はonFinishRequest(通信終了後に呼び出される)でparamsを毎回クリアしてあげればよい
onFinishRequest: (httpClient) => {
//delete params after sending
delete httpClient.params.param1;
delete httpClient.params.param2;
}
まとめ
- スマホもPCブラウザにも両対応したチャットUIの作り方を紹介しました
- チャットUIの実現のために 拙作ChatUX というモジュールと使い方を説明しました
- よりカスタムしたい場合は https://github.com/riversun/chatux のREADMEやソースが参考になるとおもいます
- もし、この記事がお役に立てたら https://github.com/riversun/chatux のほうにもスターを頂けると作者が喜びます★★★
長文お読みいただきありがとうございました。