😎
jsのみのchatbotを作りました。 全文
質問内容に応じたbooleanが存在し、回答に応じて、booleanをtrue,flaseする。
yes,noに応じて、質問内容を変化させられる。しなくてもいい。
const questions = [
{
id: 'q0',
text: '新しいチャットを始めますか (yes/no)',
next: (answer) => answer ? 'q1' : evaluateAnswers()
},
{
id: 'q1',
text: 'それは鉄道ですか (yes/no)',
next: (answer) => answer ? 'q2' : evaluateAnswers()
},
{
id: 'q2',
text: '東京の駅ですか? (yes/no)',
next: (answer) => evaluateAnswers()
}
];
最終的に十分な質問が終わったら、判定用関数に通し、結果を出力する。
function evaluateAnswers() {
const q1 = answers['q1'];
const q2 = answers['q2'];
//追加可能
if (!q1 || !q2) {
return 'result1'; //
}
return 'result2';
}
この柔軟性の高い条件分岐が自分の工夫ポイントです。
また、URLを入れることが多いと予測されるので、URLを文書内に入れた場合は、それをURL変換する機構を追加した。
別タブでURLを開くので、セキュリティリスクが存在します。
別窓から攻撃される可能性があるということで、
「 aタグ _blank セキュリティ」で検索してください。
一応、
link.target = '_blank';
link.rel = 'noopener noreferrer'; // セキュリティ対策
とはしてあります。
この前ちょうど、quitaの記事で、URLを改変されていたのがあったので、結構やられるリスクはあるのかなと感じています。気を付けてください。
以下全文
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.chat-container {
width: 300px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.chat-log {
height: 300px;
padding: 10px;
overflow-y: auto;
border-bottom: 1px solid #ddd;
}
#user-input {
width: 100%;
padding: 10px;
border: none;
outline: none;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="chat-container">
<div id="chat-log" class="chat-log"></div>
<input type="text" id="user-input" placeholder="ここに答えを書いてください" onkeypress="handleKeyPress(event)">
</div>
<script>
const chatLog = document.getElementById('chat-log');
const userInput = document.getElementById('user-input');
let answers = {};
let currentQuestion = null;
const questions = [
{
id: 'q0',
text: '新しいチャットを始めますか (yes/no)',
next: (answer) => answer ? 'q1' : evaluateAnswers()
},
{
id: 'q1',
text: 'それは鉄道ですか (yes/no)',
next: (answer) => answer ? 'q2' : evaluateAnswers()
},
{
id: 'q2',
text: '東京の駅ですか? (yes/no)',
next: (answer) => evaluateAnswers()
}
];
const results = {
result1: 'すみませんが、お応えできるものがありません',
result2: '東京の駅情報は下記になります。 https://www.jreast.co.jp/map/pdf/map_tokyo.pdf '
};
function displayQuestion(questionId) {
const question = questions.find(q => q.id === questionId);
if (question) {
currentQuestion = question;
appendMessage('bot', question.text);
} else {
const result = results[questionId];
if (result) {
appendMessage('bot', result);
}
answers = {};//条件の初期化
displayQuestion('q0');//初期化したときにする質問。お好きなものを
}
}
/*
function appendMessage(sender, message) {
const messageElement = document.createElement('div');
messageElement.classList.add('message', sender);
messageElement.textContent = message;
chatLog.appendChild(messageElement);
chatLog.scrollTop = chatLog.scrollHeight;
}*/
function appendMessage(sender, message) {
const messageElement = document.createElement('div');
messageElement.classList.add('message', sender);
// URLを検出する正規表現(http/httpsから始まり空白までの文字列)
const urlRegex = /(https?:\/\/[^\s]+)/g;
// メッセージをテキストとURLに分割して処理
const parts = message.split(urlRegex);
parts.forEach((part, index) => {
// 奇数番目の要素がURLにマッチした部分
if (index % 2 === 1) {
const link = document.createElement('a');
link.href = part;
link.textContent = part;
link.target = '_blank';
link.rel = 'noopener noreferrer'; // セキュリティ対策
messageElement.appendChild(link);
} else {
// 通常のテキストはテキストノードとして追加
messageElement.appendChild(document.createTextNode(part));
}
});
chatLog.appendChild(messageElement);
chatLog.scrollTop = chatLog.scrollHeight;
}
function handleKeyPress(event) {
if (event.key === 'Enter') {
const userAnswer = userInput.value.trim().toLowerCase();
if (userAnswer === 'yes' || userAnswer === 'no') {
const answer = userAnswer === 'yes';
answers[currentQuestion.id] = answer;
userInput.value = '';
const nextStep = currentQuestion.next(answer);
if (nextStep) {
displayQuestion(nextStep);
} else {
appendMessage('bot', '質問する内容がなくなりました。');
}
} else {
appendMessage('bot', 'yesかnoで答えてください');
}
}
}
function evaluateAnswers() {
const q1 = answers['q1'];
const q2 = answers['q2'];
//追加可能
if (!q1 || !q2) {
return 'result1'; //
}
return 'result2';
}
// Start the chatbot with the first question
displayQuestion('q1');//最初にする質問
</script>
</body>
</html>
Discussion