JavaScriptを使用して簡単なチャット!


自宅からの作業は、孤独感を得たか.行方不明の人間の社会的相互作用?まあそれは最終的に自分で良いチャットボットの代わりに世界に出るの話をすることをお勧めすることです.
私が「スクラッチ」または「バニラJS」から言うとき、私はちょうど私がどんな追加ライブラリまたはAPIも使用していないことを意味します.これは、任意の種類の人工知能や機械学習よりも多くのJSの基礎演習です.

しかし、私はまた、既存のブログ記事やYouTubeからこのコード/インスピレーションの多くを得た!それで、基本的に私はここで可能な限りオリジナルにしようとしています、しかし、あなたはとても長い間車輪を再発明するのを避けることができます.


ステップ1
最初のオフは簡単ですindex.html ファイル
<!DOCTYPE html>
<html>
<head>
<title>Chatbot</title>
<script type="text/javascript" src="index.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="main">
    <div><input id="input" type="text" placeholder="Say something..." autocomplete="off"/></div>
</div>
</body>
</html>
同様に単純styles.css ファイル
body { 
    color: #421; 
    font-weight: bold; 
    font-size: 18px; 
    font-family: "Courier New"; 
    background: rgb(200, 232, 241); 


}
body::after {
    content: "";
    background-image: url("bot.png");
    background-repeat: repeat-y; 
    opacity: 0.5;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    position: absolute;
    z-index: -1;   
  }
span { 
    color: rgb(36, 17, 119); 
} 
::-webkit-input-placeholder { 
    color: #711 
}
#main { 
    position: fixed; 
    top: 40%; 
    right: 200px; 
    width: 400px; 
    border: 0px solid #421; 
    padding: 40px; 
}
#main div { 
    margin: 10px; 
} 
#input { 
    border: 0; 
    padding: 5px; 
    border: 1px solid #421; 
}
はっきりしないHTML or CSS しかし、それは私がするためにここに来たものでありません!多分私はあなたの複雑なスタイリングを理解しようとすることなくカスタマイズすることができますので、これらの意図的に基本的なままにした.Here 背景を少し透明にするのに特に役立つと思ったヒントは、窓が凝縮されてテキストが表示されたら、私の背景イメージは少し暗かったからです.背景はbot.png Googleイメージで見つけたイメージ.あなたは何かを置き換えることができます!
取り替え可能

ステップ2
今すぐ楽しいもの!クリエイトア.js ファイル、いくつかの基本から始める.
//index.js

document.addEventListener("DOMContentLoaded", () => {
  document.querySelector("#input").addEventListener("keydown", function(e) {
    if (e.code === "Enter") {
        console.log("You clicked the form and pressed the enter button!")
    }
  });
});
のためのイベントリスナーをドキュメントに追加するDOMContentLoaded HTMLがロードされるまで、あなたのJSが走らないことを意味します.これはほとんど常に良い練習です.でEventListener を入力します.注意:我々はまた、選択する必要があります#input フォームの提出、または他の我々のイベントリスナーは、我々はEnterキーを押すたびに対応するだろう!
ここではいくつかの興味深い、推奨されない選択肢があります..keycode , .which , and keypress はすべて推奨されない.これらは、我々がただ気にかけるイベントリスナーを伝える方法だけですenter キー-それは私たちがメッセージを入力し、Enterキーを押すと、インスタントレンダリングの素晴らしい、動的効果を作るものです!私たちのボットの友人をメッセージングしながら';提出';ボタンのない退屈なクリック.もっと見るKeyboardEvent object , しかし、基本的には、このイベントリスナーの最新の、アクセス可能で普遍的なメソッドのように見えます.しかし、あなたはまだ何かを見るかもしれませんcode of 13 Enterキーを表す.
document.addEventListener("DOMContentLoaded", () => {
    const inputField = document.getElementById("input")
    inputField.addEventListener("keydown", function(e) {
        if (e.code === "Enter") {
            let input = inputField.value;
            inputField.value = "";
            output(input);
    }
  });
});
現在、我々はそれを過ぎて動いていますconsole.log() といくつかの重要な関数に.でもまず!我々が選ぶ通知.value に設定し、input . これは、フォームに入力したものです.我々は、別のコンログでこれを確認することができます!
    if (e.code === "Enter") {
      let input = inputField.value;
      console.log(`I typed '${input}'`)
    }

クール!この部分の1つの最後のもの.value = "" 我々のフォームを提出後にクリアされます.することもできます.reset() HTMLFormElement , しかし、我々の入力フィールドが本当にAでないので、それはここで働きませんform タグ.

ステップ3:機能!
今は本当にこの男をボットにする機能のために.
function () {

//remove all characters except word characters, space, and digits
  let text = input.toLowerCase().replace(/[^\w\s\d]/gi, "");

// 'tell me a story' -> 'tell me story'
// 'i feel happy' -> 'happy'
  text = text
    .replace(/ a /g, " ")
    .replace(/i feel /g, "")
    .replace(/whats/g, "what is")
    .replace(/please /g, "")
    .replace(/ please/g, "");
}
何かの前に、私は入力フィールドにどんなユーザータイプでも取りたいです、そして、若干の基本でそれをもう少し標準にしたいですRegExp アクション.コメントで注意されるように、これらのメソッドは入力小文字のすべてを作り、マッチを難しくするどんな悪質な文字も削除して、ようなものを交換しますwhats up to what is up . ユーザが言うならwhat is going on , whats going on , or what's going on , 彼らはすべての同じようにボットの応答に、代わりに別のどうにかこれらの違いを説明する必要がリードします.
我々のテキスト入力がどのように見えるかについて良い考えを持っているので、可能なトリガー(ユーザテキスト)とレスポンス(BOTテキスト)を含むいくつかの簡単な配列を作ります.始めるには、グローバル変数で定義し、定義します.
const trigger = [
//0 
["hi", "hey", "hello"],
//1
["how are you", "how are things"],
//2
["what is going on", "what is up"],
//3
["happy", "good", "well", "fantastic", "cool"],
//4
["bad", "bored", "tired", "sad"],
//5
["tell me story", "tell me joke"],
//6
["thanks", "thank you"],
//7
["bye", "good bye", "goodbye"]
];

const reply = [
//0 
["Hello!", "Hi!", "Hey!", "Hi there!"], 
//1
[
    "Fine... how are you?",
    "Pretty well, how are you?",
    "Fantastic, how are you?"
  ],
//2
[
    "Nothing much",
    "Exciting things!"
  ],
//3
["Glad to hear it"],
//4
["Why?", "Cheer up buddy"],
//5
["What about?", "Once upon a time..."],
//6
["You're welcome", "No problem"],
//7
["Goodbye", "See you later"],
];

const alternative = [
  "Same",
  "Go on...",
  "Try again",
  "I'm listening...",
  "Bro..."
];
配列のそれぞれのインデックスに対するコメント、およびそれらがどのように並んでいるかを通知します.もし我々が「0」のようなトリガー[ 0 ]でオプションにマッチするユーザ入力を得るならば、BOTはその[ 0 ]のような[返信]からのオプションで応えますなど.代替配列はもちろん、最初の配列にマッチしないものに対してです.あなたが今まで使ってきたすべての基本的なchatbotの理由は、このサービスの種類は、顧客サービスのウェブサイトで言うように、そうです..限定.Aiは、まだ我々全員を殺しそうでありません!たった今、このボットは、この人と同じくらい知的です.

つまり、あなたが我々の定義された反応のうちの1つに該当する何かを言うならば、彼が何かを言う非常に高いチャンスがあります.

これらの配列を実際に比較する関数を追加しました.
function compare(triggerArray, replyArray, text) {
  let item;
  for (let x = 0; x < triggerArray.length; x++) {
    for (let y = 0; y < replyArray.length; y++) {
      if (triggerArray[x][y] == text) {
        items = replyArray[x];
        item = items[Math.floor(Math.random() * items.length)];
      }
    }
  }
  return item;
}
そして、この関数を元のものに戻してください.
function output(input) {
  let product;
  let text = input.toLowerCase().replace(/[^\w\s\d]/gi, "");
  text = text
    .replace(/ a /g, " ")
    .replace(/i feel /g, "")
    .replace(/whats/g, "what is")
    .replace(/please /g, "")
    .replace(/ please/g, "");

//compare arrays
//then search keyword
//then random alternative

  if (compare(trigger, reply, text)) {
    product = compare(trigger, reply, text);
  } else if (text.match(/robot/gi)) {
    product = robot[Math.floor(Math.random() * robot.length)];
  } else {
    product = alternative[Math.floor(Math.random() * alternative.length)];
  }

  //update DOM
  addChat(input, product);
}
私はここでボットの応答にユーザー入力をマッチングするための別のオプションを追加しました.これは、より多くの柔軟性をユーザー入力ではなく、応答の特異性を追加します.ここで私はelse if for text.match(/robot/gi) - これは、ユーザーが任意の場所に単語ロボットで何かを入力した場合、別の“ロボット関連”配列からの応答を保証します.
const robot = ["How do you do, fellow human", "I am not a bot"];

これを抽象的にダイナミックな検索機能の別の種類に想像することができます.それとも、複数のelse ifcase and switch .

最後のステップは、我々のメッセージが実際に表示されるようにDOMを更新することです!これを行う簡単な方法は、新しいメッセージを入力するたびに更新されるユーザーとボットテキストの単一の要素を持っていることです.
document.addEventListener("DOMContentLoaded", () => {
...
    if (e.code === "Enter") {
        let input = document.getElementById("input").value;
        document.getElementById("user").innerHTML = input;
        output(input);    
     }
  });
});
それからfunction output() :
function output(input) {
    let product;
    let text = (input.toLowerCase()).replace(/[^\w\s\d]/gi, "");
...
    document.getElementById("chatbot").innerHTML = product;
    speak(product);

    //clear input value
    document.getElementById("input").value = "";
}
または、ユーザーとボットフィールドが毎回更新され、メッセージのスレッドを作成するようにすることができます.私はそれらすべてをページにしたかったので、私の現在の機能はそうです.
function addChat(input, product) {
  const mainDiv = document.getElementById("main");
  let userDiv = document.createElement("div");
  userDiv.id = "user";
  userDiv.innerHTML = `You: <span id="user-response">${input}</span>`;
  mainDiv.appendChild(userDiv);

  let botDiv = document.createElement("div");
  botDiv.id = "bot";
  botDiv.innerHTML = `Chatbot: <span id="bot-response">${product}</span>`;
  mainDiv.appendChild(botDiv);
  speak(product);
}
このDOM操作を実現するには、さまざまな方法があります..innerHTML.innerText 良いものです..append.appendChild ここではほぼ同じ目的を満たすが、後に異なる用途を持つことができる.そして、私はこの男にレールバックエンドを追加するには、私は追加するのが好きだった.dataset 各メッセージの属性.また、スレッドが十分に長くなるとスクロールする能力がないようです.もう一度、私は初心者です、そして、このポストは意見より多くのJS論理についてです!

アナザーファイナルノート.
私はAPIを使用するつもりはないと言いました、しかし、私がこの使用された音声をテキストにしようとしている間、私が見つけた例のうちの1つ、そして、それのためにしなければならないすべては以下を加えることです
function speak(string) {
  const u = new SpeechSynthesisUtterance();
  allVoices = speechSynthesis.getVoices();
  u.voice = allVoices.filter(voice => voice.name === "Alex")[0];
  u.text = string;
  u.lang = "en-US";
  u.volume = 1; //0-1 interval
  u.rate = 1;
  u.pitch = 1; //0-2 interval
  speechSynthesis.speak(u);
}
私は実際にここで異なる音声名を指定する方法を全く理解できませんでした、しかし、ウェブスピーチAPIドキュメントを調べることは面白かったです、そして、私は変更を推薦することができます.pitch to 2 人類を引き継ぐことができる音をする本当に恐ろしい声のために.

更なる読書
  • Using the Web Speech API

  • Simple chatbot example with more APIs
  • My full code
  • Bot Demo