JavaScriptでチャットボットを作る

# JavaScriptで作ったチャットボット

## 今回作ったもの
[AIチャットボット（デモサイト）](https://mf3px.sakura.ne.jp/chatbot2/)

<p class="codepen" data-height="460" data-default-tab="html,result" data-slug-hash="WNpjJzM" data-user="masa_mf3" style="height: 460px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span><a href="https://codepen.io/masa_mf3/pen/WNpjJzM">AIチャットボット</a></span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## はじめに
簡易版で勉強したい方：
[簡易チャットボット（デモサイト）](http://mf3px.sakura.ne.jp/chatbot/)
→ [CodePen（コード）](https://codepen.io/masa_mf3/pen/VwYZQvp)

今回作るのは、質問応答やクイズ問題を出してくれるチャットボットです。
言語はHTML，CSS，JavaScriptです。
応用次第で、より複雑なものを作ることも、もちろん可能です！

## 機能一覧
- ロボットからの投稿
- **自分の発言の記憶**と、それを用いた返答
- 選択肢ボタン（&正解数の計算）
- ランダム投稿
- ロボットの考え中のアニメーション

## コードの説明（抜粋）
コードの全容はこちらをご参考ください。
[「AIチャットボット（Codepen）」](https://codepen.io/masa_mf3/pen/WNpjJzM)


### HTML
チャットの画面にある「ul」にJavaScriptで「li」を追加していく仕組みです。

```HTML:HTML
<!--メッセージが表示される画面-->
<div id= "chatbot-body">
    <ul id= "chatbot-ul"></ul>
</div>
    
<!--入力場所，送信ボタン-->
<form onsubmit= "return false">
    <input type= "text" placeholder= "テキストを入力">
    <input type= "submit" value= "送信">
</form>

```
### CSS
- 「ul」の子要素「li」に直接テキストを挿入してもいいですが、デザイン上、今回は **「li」の子要素「div」に文字を書いていきます**。（吹き出しテキストの「padding」，「line-height」，改行などが複雑になるのを防ぐため）
- ロボットの吹き出し「li」には「.chatbot-left」というクラスを当て左寄せに、自分の吹き出し「li」には「.chatbot-right」というクラスを当て右寄せにしています。

![JS_チャットボット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471258/90124851-d049-e630-bb4e-a3db474be4e7.png)

```CSS:CSS
/*チャット画面のスクロール設定*/
#chatbot-body {
    /*横向きのスクロール禁止*/
    overflow-x: hidden;
    /*縦向きのスクロール許可*/
    overflow-y: scroll;
    /*スマホでは指でスクロール*/
    -webkit-overflow-scrolling: touch;
}

/*ロボットの吹き出し*/
.chatbot-left{
    margin-left: 20px;
    border-radius: 0 9px 9px 9px;
}

/*自分の吹き出し*/
.chatbot-right{
    margin-right: 20px;
    text-align: left;
    border-radius: 9px 0 9px 9px;
}
```

### JavaScript
今回は、相手のメッセージは全て2秒遅れにします。

- ロボットが返信する度に、「robotCount」を1ずつ足していきます。この値がロボットが話す内容をまとめた「chatList」オブジェクトの数値に対応します。自分がテキストを入力し、送信ボタンを押した瞬間の「robotCount」の値に応じて、配列から次のメッセージを選び返信させます。
- 今回作った関数は、ロボットの投稿をする「robotOutput()」と、自分が送信ボタンを押したときの関数（無名関数）です。

```JavaScript:JavaScript
// ロボットからの投稿一覧のオブジェクト
// textには投稿文，continueは次も連続で投稿するかどうか，optionは普通の投稿or選択肢orランダム投稿など

const chatList = {
    1: {text: 'ようこそ「AI chat」へ！', continue: true, option: 'normal'},
    2: {text: '会話内容は管理者へ送信されませんので、ご安心ください。', continue: true, option: 'normal'},
    3: {text: {title: 'Q1', question: '何を知りたいですか？', choices: ['開発者について', '参考にしたチャットボット', 'Flutter デモアプリ', '島根県美郷町 HP']}, continue: false, option: 'choices', questionNextSupport: true} // questionNextSupportは、リンクなど次に質問に対する詳細を投稿するかどうか
    // 省略
};

// 投稿文を加工する関数（中に相手の名前などを挿入する際に用いる）
function textSpecial() {
    chatList[7].text = `こんにちは！${userData[1]}さん！`;
    chatList[12].text.qTrue = `正解！${userData[1]}さん、すごいですね！`;
    chatList[13].text = `${userData[1]}さん、ありがとうございました。今日はここで終了とさせていただきます。`; 
    chatList[16].text = `${userData[1]}さんの満足度は「${userData[4]}」，ご感想は「${userData[5]}」ですね！ありがとうございました。`;
}

// ユーザーの発言，回答内容を記憶する配列
let userData = [];

// ロボットが投稿をする度にカウントしていき、投稿を管理する
let robotCount = 0; // ロボットの投稿数

// ロボットの投稿
function robotOutput() {
    robotCount ++;
    // ulとliを作り、左寄せのスタイルを適用し投稿する
    const ul = document.getElementById('chatbot-ul');
    const li = document.createElement('li');
    li.classList.add('left');
    ul.appendChild(li);
}

// 最初にロボットから話しかける
robotOutput();

// 自分の投稿（送信ボタンを押した時）
chatSubmitBtn.addEventListener('click', () => {
    // 空行の場合送信不可
    if (!userText.value || !userText.value.match(/\S/g)) return false;
    userCount ++;
    // 投稿内容を後に活用するために、配列に保存しておく
    userData.push(userText.value); 
    // ulとliを作り、右寄せのスタイルを適用し投稿する
    const ul = document.getElementById('chatbot-ul');
    const li = document.createElement('li');
    li.classList.add('right');
    ul.appendChild(li);
}
```

## 最後に
いかがでしたでしょうか。チャットボットを作りたい。。しかし、どのサイトを調べても、ライブラリやサーバ，ChatUIなどを使った難しいものばかりでした。そんな中、ピュアなJavaScriptだけで作れないかと数日～1か月ほど試行錯誤し、ついに完成しました。

JavaScriptに関しては、比較的難易度が高いと思います。
最低限の機能は備えていますが、開発途中ですので今後もアップデートしていこうと思います。

今回作ったデモサイトは以下をご覧ください。
[AIチャットボット（デモサイト）](https://mf3px.sakura.ne.jp/chatbot2/)


## 参考文献
なし