(function () {
// Create a style element for custom CSS
const style = document.createElement("style");
style.textContent = `
@keyframes thinking {
0%, 80%, 100% { opacity: 0; }
40% { opacity: 1; }
}
.thinking-dot {
width: 8px;
height: 8px;
background-color: #6b7280;
border-radius: 50%;
display: inline-block;
animation: thinking 1.4s infinite ease-in-out both;
}
.thinking-dot:nth-child(1) { animation-delay: -0.32s; }
.thinking-dot:nth-child(2) { animation-delay: -0.16s; }
#chat-interface {
font-family: Arial, sans-serif;
}
#chat-interface * {
box-sizing: border-box;
}
`;
document.head.appendChild(style);
// Load Tailwind CSS
const tailwindScript = document.createElement("script");
tailwindScript.src = "https://cdn.tailwindcss.com";
document.head.appendChild(tailwindScript);
// Load marked library for Markdown parsing
const markedScript = document.createElement("script");
markedScript.src = "https://cdn.jsdelivr.net/npm/marked/marked.min.js";
document.head.appendChild(markedScript);
let buttonTriggerStatus = false;
let threadId = "";
let accessToken = "";
// Wait for DOM content to be loaded
document.addEventListener("DOMContentLoaded", initChat);
async function initChat() {
createContactUsButton();
createRequestCallButton();
createChatButton();
setupEventListeners();
try {
const response = await fetch(
"https://fitness.sidyum.com/version-test/api/1.1/wf/get_access_token",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userId:
document.getElementById("info-from-bubble").dataset.userid,
}),
}
);
const res = await response.json();
accessToken = res.response.accessToken;
} catch (error) {
console.log(error);
alert("Please reload this webpage");
}
}
function createChatInterface() {
const container = document.createElement("div");
if (!container) return;
container.innerHTML = `
`;
document.body.appendChild(container);
}
function createFormInterface() {
const container = document.createElement("div");
if (!container) return;
container.innerHTML = `
`;
document.body.appendChild(container);
// Prevent click events on the form from closing the overlay
const salesForm = document.getElementById("salesForm");
salesForm.addEventListener("click", (event) => {
event.stopPropagation(); // Stop the event from reaching the formOverlay
});
salesForm.addEventListener("submit", handleSalesFormSubmit);
}
function addMessage(message, isUser = false) {
const chatMessages = document.getElementById("chatMessages");
const messageElement = document.createElement("div");
messageElement.className = isUser
? "bg-slate-300 self-end mr-3 max-w-[70%] relative w-fit py-2 px-3 mb-2 rounded-lg rounded-tr-[0]"
: "bg-cyan-500 ml-3 max-w-[70%] relative w-fit py-2 px-3 mb-2 rounded-lg rounded-tl-[0]";
messageElement.innerHTML = `
${marked.parse(
message
)}
`;
chatMessages.appendChild(messageElement);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
async function sendMessageToNova() {
const messageInput = document.getElementById("messageInput");
const message = messageInput.value.trim();
if (message) {
messageInput.value = "";
showThinkingAnimation();
addMessage(message, true);
const ans = await handleNovaAi(message);
if (ans.error == null) {
if (getChildCount("chatMessages") <= 2) {
threadId = ans.threadId;
}
addMessage(ans.response);
} else {
alert("An error occurred. Please try again later.");
messageInput.value = message;
}
hideThinkingAnimation();
}
}
async function handleNovaAi(message) {
const vectorId =
document.getElementById("info-from-bubble").dataset.vectorid;
if (vectorId) {
const aiName =
document.getElementById("info-from-bubble").dataset.ainame;
const businessName =
document.getElementById("info-from-bubble").dataset.businessname;
const businessNumber =
document.getElementById("info-from-bubble").dataset.businessnumber;
const userId =
document.getElementById("info-from-bubble").dataset.userid;
try {
const response = await fetch("https://ma0358.buildship.run/nova-ai", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
message,
threadId,
vector: vectorId,
businessName,
aiName,
businessNumber,
accessToken,
}),
});
return await response.json();
} catch (error) {
console.error("Error in handleNovaAi:", error);
return { error: "Failed to communicate with the server" };
}
}
return { error: "Vector ID not found" };
}
function createContactUsButton() {
const button = document.createElement("div");
button.innerHTML = "Contact Us";
button.id = "show-chat-call";
button.className =
"fixed bottom-5 right-5 bg-cyan-500 text-white px-4 py-2 rounded-full cursor-pointer z-50";
document.body.appendChild(button);
}
function createRequestCallButton() {
const button = document.createElement("div");
button.innerHTML = "Request a call";
button.id = "request-call-from-vapi";
button.className =
"fixed bottom-20 right-5 bg-cyan-500 text-white px-4 py-2 rounded-full cursor-pointer z-50 hidden";
document.body.appendChild(button);
}
function createChatButton() {
const button = document.createElement("div");
button.innerHTML = "Chat with Us";
button.id = "chat-box-opened";
button.className =
"fixed bottom-36 right-5 bg-cyan-500 text-white px-4 py-2 rounded-full cursor-pointer z-50 hidden";
document.body.appendChild(button);
}
function setupEventListeners() {
document
.getElementById("show-chat-call")
.addEventListener("click", toggleButtons);
document
.getElementById("chat-box-opened")
.addEventListener("click", showChatInterface);
document
.getElementById("request-call-from-vapi")
.addEventListener("click", showFormInterface);
}
function toggleButtons() {
buttonTriggerStatus = !buttonTriggerStatus;
document
.getElementById("request-call-from-vapi")
.classList.toggle("hidden");
document.getElementById("chat-box-opened").classList.toggle("hidden");
}
async function showChatInterface() {
createChatInterface();
hideButtons();
showThinkingAnimation();
const ans = await handleNovaAi("Hello");
if (ans.error == null) {
threadId = ans.threadId;
addMessage(ans.response);
}
hideThinkingAnimation();
}
function showFormInterface() {
createFormInterface();
hideButtons();
}
function hideButtons() {
document.getElementById("request-call-from-vapi").classList.add("hidden");
document.getElementById("chat-box-opened").classList.add("hidden");
document.getElementById("show-chat-call").classList.add("hidden");
}
function hideChatInterface() {
const chatInterface = document.getElementById("chat-interface");
if (chatInterface) chatInterface.remove();
document.getElementById("show-chat-call").classList.remove("hidden");
threadId = "";
}
function hideFormInterface() {
const formOverlay = document.getElementById("formOverlay");
if (formOverlay) formOverlay.remove();
document.getElementById("show-chat-call").classList.remove("hidden");
}
async function handleSalesFormSubmit(e) {
e.preventDefault();
const name = document.getElementById("nameInput").value.trim();
const number = document.getElementById("numberInput").value.trim();
const email = document.getElementById("emailInput").value.trim();
if (name && number && email) {
const fieldsData = JSON.parse(
document
.getElementById("info-from-bubble")
.dataset.fieldsid.replace(/'/g, '"')
);
const aiName =
document.getElementById("info-from-bubble").dataset.ainame;
const businessName =
document.getElementById("info-from-bubble").dataset.businessname;
const businessNumber =
document.getElementById("info-from-bubble").dataset.businessnumber;
const userId =
document.getElementById("info-from-bubble").dataset.userid;
try {
const response = await fetch("https://ma0358.buildship.run/luna-ai", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name,
phone: number,
fields: fieldsData,
businessName,
businessNumber,
aiName,
email,
userId,
accessToken,
}),
});
const result = await response.json();
if (result) {
console.log(result);
alert("Call has been scheduled");
hideFormInterface();
}
} catch (error) {
console.error("Error in handleSalesFormSubmit:", error);
alert("An error occurred. Please try again later.");
}
} else {
alert("Please fill in all fields");
}
}
function getChildCount(elementId) {
const element = document.getElementById(elementId);
return element ? element.children.length : 0;
}
function showThinkingAnimation() {
document.getElementById("thinkingAnimation").classList.remove("hidden");
document.getElementById("sendButton").disabled = true;
document.getElementById("sendButton").style.cursor = "not-allowed";
document.getElementById("sendButton").classList.remove("bg-cyan-500");
document.getElementById("sendButton").classList.add("bg-cyan-400");
}
function hideThinkingAnimation() {
document.getElementById("thinkingAnimation").classList.add("hidden");
document.getElementById("sendButton").disabled = false;
document.getElementById("sendButton").style.cursor = "pointer";
document.getElementById("sendButton").classList.add("bg-cyan-500");
document.getElementById("sendButton").classList.remove("bg-cyan-400");
}
// Expose necessary functions to global scope
window.hideChatInterface = hideChatInterface;
window.hideFormInterface = hideFormInterface;
window.sendMessageToNova = sendMessageToNova;
})();