Problem Description:
I am following a YouTube tutorial on how to build a chatbot using Python and JavaScript. The chatbot UI displays correctly, and the button to open the chatbox popup is working fine. However, when I type a message into the input field and click the send button, nothing happens, and the message doesn’t show up in the chatbox. I’m wondering why this is the case.
Code:
Here is the code for app.py (used to run the app):
from flask import Flask, render_template, request, jsonify
from chat import get_response
app = Flask(__name__)
@app.get("/")
def index_get():
return render_template("base.html")
@app.post("/predict")
def predict():
text = request.get_json().get("message")
# TO-DO: check if text is valid
response = get_response(text)
message = {"answer": response}
return jsonify(message)
if __name__ == "__main__":
app.run(debug=True, port=5001)
And here is the code for app.js (code for the chatbot itself):
class Chatbox {
constructor() {
this.args = {
openButton: document.querySelector(".chatbox__button"),
sendButton: document.querySelector(".send__button"),
};
this.state = false;
this.messages = [];
}
toggleState(chatBox) {
chatBox.classList.toggle("chatbox--active");
}
onSendButton(chatBox) {
var textField = chatBox.querySelector("input");
let text1 = textField.value;
if (text1 === "") {
return;
}
let msg1 = { name: "User", message: text1 };
this.messages.push(msg1);
fetch($SCRIPT_ROOT + "/predict", {
method: "POST",
body: JSON.stringify({ message: text1 }),
mode: "cors",
headers: {
"Content-Type": "application/json",
},
})
.then((r) => r.json())
.then((r) => {
let msg2 = { name: "Sam", message: r.answer };
this.messages.push(msg2);
this.updateChatText(chatBox);
textField.value = "";
})
.catch((error) => {
console.error("Error:", error);
this.updateChatText(chatBox);
textField.value = "";
});
}
updateChatText(chatBox) {
var html = "";
this.messages
.slice()
.reverse()
.forEach(function (item, index) {
if (item.name === "Sam") {
html +=
'<div class="messages__item messages__item--visitor">' +
item.message +
"</div>";
} else {
html +=
'<div class="messages__item messages__item--operator">' +
item.message +
"</div>";
}
});
const chatMessage = chatBox.querySelector(".chatbox__messages");
chatMessage.innerHTML = html;
}
display() {
const { openButton, sendButton } = this.args;
const chatBox = document.querySelector(".chatbox__support");
openButton.addEventListener("click", () => this.toggleState(chatBox));
sendButton.addEventListener("click", () => this.onSendButton(chatBox));
const inputNode = chatBox.querySelector("input");
inputNode.addEventListener("keyup", (event) => {
if (event.key === "Enter") {
this.onSendButton(chatBox);
}
});
}
}
const chatbox = new Chatbox();
chatbox.display();
Here is the HTML and CSS code for the chatbot in base.html:
<!DOCTYPE html>
<html lang="en">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<head>
<meta charset="UTF-8">
<title>Chatbot</title>
</head>
<body>
<div class="container">
<div class="chatbox">
<div class="chatbox__support">
<div class="chatbox__header">
<div class="chatbox__image--header">
<img src="https://img.icons8.com/color/48/000000/circled-user-female-skin-type-5--v1.png" alt="image">
</div>
<div class="chatbox__content--header">
<h4 class="chatbox__heading--header">Chat support</h4>
<p class="chatbox__description--header">Hi. My name is Sam. How can I help you?</p>
</div>
</div>
<div class="chatbox__messages">
<div></div>
</div>
<div class="chatbox__footer">
<input type="text" placeholder="Write a message...">
<button class="chatbox__send--footer send__button">Send</button>
</div>
</div>
<div class="chatbox__button">
<button><img src="{{ url_for('static', filename='images/chatbox-icon.svg') }}" /></button>
</div>
</div>
</div>
<script>
var $SCRIPT_ROOT = "{{ request.script_root|tojson }}";
</script>
<script type="text/javascript" src="{{ url_for('static', filename='app.js') }}"></script>
</body>
</html>
and here is style.css:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: "Nunito", sans-serif;
font-weight: 400;
font-size: 100%;
background: #f1f1f1;
}
*,
html {
--primaryGradient: linear-gradient(93.12deg, #581b98 0.52%, #9c1de7 100%);
--secondaryGradient: linear-gradient(
268.91deg,
#581b98 -2.14%,
#9c1de7 99.69%
);
--primaryBoxShadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
--secondaryBoxShadow: 0px -10px 15px rgba(0, 0, 0, 0.1);
--primary: #581b98;
}
/* CHATBOX
=============== */
.chatbox {
position: absolute;
bottom: 30px;
right: 30px;
}
/* CONTENT IS CLOSE */
.chatbox__support {
display: flex;
flex-direction: column;
background: #eee;
width: 300px;
height: 350px;
z-index: -123456;
opacity: 0;
transition: all 0.5s ease-in-out;
}
/* CONTENT ISOPEN */
.chatbox--active {
transform: translateY(-40px);
z-index: 123456;
opacity: 1;
}
/* BUTTON */
.chatbox__button {
text-align: right;
}
.send__button {
padding: 6px;
background: transparent;
border: none;
outline: none;
cursor: pointer;
}
/* HEADER */
.chatbox__header {
position: sticky;
top: 0;
background: orange;
}
/* MESSAGES */
.chatbox__messages {
margin-top: auto;
display: flex;
overflow-y: scroll;
flex-direction: column-reverse;
}
.messages__item {
background: orange;
max-width: 60.6%;
width: fit-content;
}
.messages__item--operator {
margin-left: auto;
}
.messages__item--visitor {
margin-right: auto;
}
/* FOOTER */
.chatbox__footer {
position: sticky;
bottom: 0;
}
.chatbox__support {
background: #f9f9f9;
height: 450px;
width: 350px;
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.1);
border-top-left-radius: 20px;
border-top-right-radius: 20px;
}
/* HEADER */
.chatbox__header {
background: var(--primaryGradient);
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 15px 20px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
box-shadow: var(--primaryBoxShadow);
}
.chatbox__image--header {
margin-right: 10px;
}
.chatbox__heading--header {
font-size: 1.2rem;
color: white;
}
.chatbox__description--header {
font-size: 0.9rem;
color: white;
}
/* Messages */
.chatbox__messages {
padding: 0 20px;
}
.messages__item {
margin-top: 10px;
background: #e0e0e0;
padding: 8px 12px;
max-width: 70%;
}
.messages__item--visitor,
.messages__item--typing {
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
.messages__item--operator {
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
background: var(--primary);
color: white;
}
/* FOOTER */
.chatbox__footer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 20px 20px;
background: var(--secondaryGradient);
box-shadow: var(--secondaryBoxShadow);
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
margin-top: 20px;
}
.chatbox__footer input {
width: 80%;
border: none;
padding: 10px 10px;
border-radius: 30px;
text-align: left;
}
.chatbox__send--footer {
color: white;
}
.chatbox__button button,
.chatbox__button button:focus,
.chatbox__button button:visited {
padding: 10px;
background: white;
border: none;
outline: none;
border-top-left-radius: 50px;
border-top-right-radius: 50px;
border-bottom-left-radius: 50px;
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
cursor: pointer;
}
Additional Context:
I have implemented a chatbot based on the tutorial, but when I type a message and click the send button, nothing happens. I have checked the code, and it seems that the onSendButton() function is not being triggered correctly. I expect the message to be sent to the server using the fetch() function and then added to the chatbox messages using the updateChatText() function.
I would appreciate any help in identifying why the messages are not displaying after clicking the send button. Thank you!