FIX_CHATBOT_MOBILE_VIEW

This commit is contained in:
velz 2025-08-02 11:58:04 +05:30
parent 4933b1540c
commit aea9753da0
4 changed files with 642 additions and 66 deletions

View File

@ -8,6 +8,7 @@ use CodeIgniter\Router\RouteCollection;
*/
$routes->post('/chat', 'ChatbotControllerNew::index');
$routes->get('/widget', 'ChatbotControllerNew::widget');
$routes->get('/chatbottest', 'ChatbotControllerNew::chatbotest');
$routes->get('/chatbot', 'ChatbotControllerNew::chatbot');
$routes->get('/swagger', 'SwaggerController::index', ['filter' => 'authMVC']);

View File

@ -146,9 +146,14 @@ class ChatbotControllerNew extends BaseController
// }
public function chatbotest()
{
$this->loadLayout('chatbottest.php');
}
public function chatbot()
{
$this->loadLayout('chatbot.php');
echo view('chatbot.php');
}
public function widget()

View File

@ -4,81 +4,567 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Insurance ChatBot</title>
</head>
<style type="text/css">
</style>
<body>
<h1>Welcome to Insurance ChatBot </h1>
<h1>Loading...Please wait </h1>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script src='https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js'></script>
<script>
// var botmanWidget = {
// frameEndpoint: 'https://localhost/PHP828APPS/ruc/nhance/chat', // This should match your CI4 route
// introMessage: "Hi! I am your Insurance Bot. How can I assist you today?",
// placeholderText: "Type your message here...",
// title: "Insurance Bot",
// mainColor: "#5C6BC0",
// bubbleBackground: "#673AB7"
// };
var emp_name = 'Kumar';
var uid = Math.floor(100000 + Math.random() * 900000);
console.log('CURRENT_USER' + uid);
var botmanWidget = {
chatServer: `<?=base_url('chat')?>`, // Make sure this URL is correct
frameEndpoint: `<?=base_url('widget')?>`, // This should match your CI4
title: "Ask ILA",
introMessage: "",
bubbleBackground: "#007bff",
mainColor: "#007bff",
placeholderText: "Type your message here...",
aboutText: "Insurance Assistant ILA",
enableAttachments: false,
// Add extra parameters
parameters: {
employee_id: '12288', //PK of emp
session_id: "XYZ789", // token
origin: "mobile", // origin
emp_code:"HTL-007",
client_id:159,
client_branch_id:126
}
};
// Send a first load request when the chat widget opens
// window.addEventListener("load", function () {
// setTimeout(function () {
// fetch("https://localhost/PHP828APPS/ruc/nhance/chat", {
// method: "POST",
// headers: { "Content-Type": "application/json" },
// body: JSON.stringify({ first_load: "true", user_id: "12345" })
// });
// }, 2000); // Slight delay to ensure the widget is ready
// });
window.addEventListener("load", function () {
setTimeout(function () {
if (window.botmanWidget) {
botmanChatWidget.open();
setTimeout(function(){
botmanChatWidget.sayAsBot('Hi '+ (typeof emp_name !== "undefined" && emp_name !== null && emp_name !== "" ? emp_name : "Guest User") +',This is ILA your Insurance Assistant, plz choose the following options')
botmanChatWidget.whisper('Hi');
},3000);
}
}, 2000); // Delay to ensure widget is initialized
});
const queryParams = getQueryParams();
console.log(queryParams);
const isMobile = window.innerWidth <= 600;
const calcHeight = Math.floor(window.innerHeight * 0.6);
const calcWidth = isMobile
? (window.innerWidth)
: Math.min(400, window.innerWidth - 50);
var botmanWidget = {
// chatServer: 'https://venbait.in/nhance/chatbot/chat',
// frameEndpoint: 'https://venbait.in/nhance/chatbot/widget',
chatServer: 'https://localhost/PHP828APPS/ruc/nhance/chat',
frameEndpoint: 'https://localhost/PHP828APPS/ruc/nhance/widget',
title: "Ask ILA",
placeholderText: "Type your message here...",
aboutText: "Insurance Assistant ILA",
enableAttachments: false,
introMessage:'Welcome Kumar...! Say Hi...',
bubbleAvatarUrl:"https://botman.io/img/logo.png",
parameters: {
employee_id: queryParams['employee_id'],
session_id: "XYZ789",
origin: "mobile",
emp_code: queryParams['emp_code'],
client_id: 63,
client_branch_id: 32
}
};
// Also add scrolling when new messages arrive by observing the chat area
function setupMessageObserver() {
if (!currentIframe) {
console.log('No iframe available for message observer');
return;
}
try {
const doc = currentIframe.contentDocument || currentIframe.contentWindow.document;
if (!doc) {
console.log('Cannot access iframe document for message observer');
return;
}
const waitForChatArea = () => {
const chatArea = doc.querySelector("#messageArea .chat") ||
doc.querySelector("#messageArea ol.chat") ||
doc.querySelector("ol.chat");
if (chatArea) {
console.log('Chat area found, setting up mutation observer');
// Create observer instance
const observer = new MutationObserver((mutations) => {
// Check if any mutations added nodes
const hasNewMessages = mutations.some(mutation =>
mutation.addedNodes && mutation.addedNodes.length > 0
);
if (hasNewMessages) {
// Scroll to bottom when new messages arrive
setTimeout(() => {
scrollToBottom();
}, 100);
}
});
// Start observing the chat area for child list changes
observer.observe(chatArea, {
childList: true,
subtree: true
});
// Also scroll to bottom initially
setTimeout(() => {
scrollToBottom();
}, 500);
} else {
console.log('Chat area not found yet, retrying...');
setTimeout(waitForChatArea, 200);
}
};
waitForChatArea();
} catch (error) {
console.error('Error setting up message observer:', error);
}
}
// Improved CSS injection function with better timing and specificity
function injectCSS(frame) {
console.log('injectCSS called');
// Store the iframe reference for later use
currentIframe = frame;
try {
const doc = frame.contentDocument || frame.contentWindow.document;
if (!doc) {
console.error("Cannot access iframe document");
return;
}
// Wait for the document to be ready
const waitForElement = () => {
const messageArea = doc.querySelector("#messageArea");
const chatElement = doc.querySelector("#messageArea .chat");
if (messageArea && chatElement) {
console.log('Elements found, injecting CSS');
// Set initial height based on device
const initialHeight = isMobile ? 700 : 800; // Default to keyboard closed state
// Method 1: Create style element with high specificity
const style = doc.createElement("style");
style.id = 'dynamic-chat-height';
style.textContent = `
/* High specificity selectors */
#messageArea ol.chat,
#messageArea .chat,
ol.chat {
height: ${initialHeight}px !important;
max-height: ${initialHeight}px !important;
min-height: ${initialHeight}px !important;
transition: height 0.3s ease;
}
/* Additional styling to ensure proper display */
#messageArea {
height: auto !important;
}
`;
doc.head.appendChild(style);
// Method 2: Direct style application as backup
setTimeout(() => {
const chatElements = doc.querySelectorAll("#messageArea .chat, #messageArea ol.chat, ol.chat");
chatElements.forEach(element => {
if (element) {
element.style.setProperty("height", initialHeight + "px", "important");
element.style.setProperty("max-height", initialHeight + "px", "important");
element.style.setProperty("min-height", initialHeight + "px", "important");
element.style.setProperty("transition", "height 0.3s ease", "important");
console.log('Direct style applied to:', element);
}
});
// Update current height
currentChatHeight = initialHeight;
// Setup input focus listeners after CSS is applied
setTimeout(() => {
setupInputFocusListeners();
}, 500);
// setTimeout(() => {
// setupMessageObserver();
// }, 500);
}, 500);
} else {
console.log('Elements not found yet, retrying...');
setTimeout(waitForElement, 200);
}
};
// Start checking for elements
if (doc.readyState === 'complete') {
waitForElement();
} else {
doc.addEventListener('DOMContentLoaded', waitForElement);
// Fallback timeout
setTimeout(waitForElement, 1000);
}
} catch (error) {
console.error('Error injecting CSS:', error);
}
}
// Improved iframe detection with better timing
function waitForBotmanIframe(callback) {
console.log('waitForBotmanIframe');
const checkForIframe = () => {
const iframe = document.querySelector("#chatBotManFrame") ||
document.querySelector("iframe[src*='widget']") ||
document.querySelector("#botmanChatRoot iframe");
if (iframe) {
console.log('Iframe found:', iframe);
callback(iframe);
return true;
}
return false;
};
// Check immediately
if (checkForIframe()) return;
// Use MutationObserver as fallback
const container = document.querySelector("#botmanChatRoot") || document.body;
const observer = new MutationObserver((mutations, obs) => {
if (checkForIframe()) {
obs.disconnect();
}
});
observer.observe(container, {
childList: true,
subtree: true,
attributes: true
});
// Timeout fallback
setTimeout(() => {
observer.disconnect();
checkForIframe();
}, 5000);
}
// Enhanced CSS application for the main document
function applyBotManChatCSS() {
console.log('applyBotManChatCSS called');
const style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = `
/* Hide unwanted elements */
div[style*="background: rgb(64, 133, 145)"][style*="line-height: 30px"] {
display: none !important;
}
div[class*="desktop-closed-message-avatar"] {
display: none !important;
}
/* Iframe styling */
iframe#chatBotManFrame {
height: 100% !important;
width: 100% !important;
display: block;
}
/* Additional iframe selectors */
iframe[src*="widget"] {
height: 100% !important;
width: 100% !important;
}
`;
document.getElementsByTagName('head')[0].appendChild(style);
}
// Input focus-based height adjustment
let currentChatHeight = 800; // Default height
let isInputFocused = false;
let currentIframe = null;
function adjustChatHeight(height) {
console.log('Adjusting chat height to:', height);
currentChatHeight = height;
if (currentIframe) {
try {
const doc = currentIframe.contentDocument || currentIframe.contentWindow.document;
if (doc) {
// Update existing style
let styleElement = doc.querySelector('#dynamic-chat-height');
if (!styleElement) {
styleElement = doc.createElement('style');
styleElement.id = 'dynamic-chat-height';
doc.head.appendChild(styleElement);
}
styleElement.textContent = `
#messageArea ol.chat,
#messageArea .chat,
ol.chat {
height: ${height}px !important;
max-height: ${height}px !important;
min-height: ${height}px !important;
transition: height 0.3s ease;
}
`;
// Direct style application as backup
const chatElements = doc.querySelectorAll("#messageArea .chat, #messageArea ol.chat, ol.chat");
chatElements.forEach(element => {
if (element) {
element.style.setProperty("height", height + "px", "important");
element.style.setProperty("max-height", height + "px", "important");
element.style.setProperty("min-height", height + "px", "important");
}
});
console.log('Chat height adjusted successfully to:', height);
}
} catch (error) {
console.error('Error adjusting chat height:', error);
}
}
}
// Setup input focus/blur listeners for height adjustment
function setupInputFocusListeners() {
if (!currentIframe) {
console.log('No iframe available for input listeners');
return;
}
try {
const doc = currentIframe.contentDocument || currentIframe.contentWindow.document;
if (!doc) {
console.log('Cannot access iframe document for input listeners');
return;
}
// Function to find and attach listeners to the userText input
const attachInputListeners = () => {
const userTextInput = doc.querySelector('#userText');
if (userTextInput) {
console.log('Found userText input, attaching listeners');
// Remove existing listeners to prevent duplicates
userTextInput.removeEventListener('focus', handleInputFocus);
userTextInput.removeEventListener('blur', handleInputBlur);
// Add new listeners
userTextInput.addEventListener('focus', handleInputFocus);
userTextInput.addEventListener('blur', handleInputBlur);
console.log('Input focus/blur listeners attached successfully');
return true;
} else {
console.log('userText input not found, retrying...');
return false;
}
};
// Try to attach listeners immediately
if (!attachInputListeners()) {
// If input not found, set up a mutation observer to wait for it
const observer = new MutationObserver((mutations, obs) => {
if (attachInputListeners()) {
obs.disconnect();
}
});
observer.observe(doc.body, {
childList: true,
subtree: true
});
// Stop observing after 10 seconds
setTimeout(() => {
observer.disconnect();
console.log('Stopped observing for userText input');
}, 10000);
}
} catch (error) {
console.error('Error setting up input focus listeners:', error);
}
}
// Handle input focus event
function handleInputFocus(event) {
console.log('Input focused - userText field');
if (!isInputFocused && isMobile) {
// alert('focused');
isInputFocused = true;
// Adjust height when input is focused (keyboard likely open)
adjustChatHeight(400); // Smaller height when keyboard is open
scrollToBottom();
// Add scroll to bottom when input is focused
setTimeout(() => {
scrollToBottom();
}, 300); // Small delay to allow height adjustment to complete
}
}
// Handle input blur event
function handleInputBlur(event) {
console.log('Input blurred - userText field');
// alert('blurred');
if (isInputFocused && isMobile) {
isInputFocused = false;
// Small delay to ensure keyboard is fully closed
setTimeout(() => {
// Adjust height when input is blurred (keyboard likely closed)
adjustChatHeight(700); // Larger height when keyboard is closed
}, 300);
}
}
function scrollToBottom() {
if (!currentIframe) return;
try {
console.info('CALLED START: scrollToBottom');
const doc = currentIframe.contentDocument || currentIframe.contentWindow.document;
if (!doc) return;
const messageArea = doc.querySelector("#messageArea .chat") ||
doc.querySelector("#messageArea ol.chat") ||
doc.querySelector("ol.chat");
if (messageArea) {
// Scroll to bottom with smooth behavior
console.info('CALLED WORKING: scrollToBottom');
messageArea.scrollTo({
top: messageArea.scrollHeight,
behavior: 'smooth'
});
}
console.info('CALLED ENDs: scrollToBottom');
} catch (error) {
console.error('Error scrolling to bottom:', error);
}
}
function getQueryParams() {
const params = {};
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
for (const [key, value] of urlParams.entries()) {
params[key] = value;
}
return params;
}
// Main initialization
window.addEventListener("load", function () {
console.log('Page loaded, initializing bot');
setTimeout(function () {
if (window.botmanWidget) {
botmanChatWidget.open();
setTimeout(function(){
botmanChatWidget.sayAsBot('Hi ' + (typeof emp_name !== "undefined" && emp_name !== null && emp_name !== "" ? emp_name : "Guest User") + ', This is ILA your Insurance Assistant, plz choose the following options');
botmanChatWidget.whisper('Hi');
}, 1000);
applyBotManChatCSS();
// Multiple attempts to inject CSS with different timings
waitForBotmanIframe((chatFrame) => {
console.log('Iframe detected, attempting CSS injection');
// Immediate attempt
injectCSS(chatFrame);
// Delayed attempts for better reliability
setTimeout(() => injectCSS(chatFrame), 1000);
setTimeout(() => injectCSS(chatFrame), 2000);
setTimeout(() => injectCSS(chatFrame), 3000);
// Listen for iframe load events
chatFrame.addEventListener("load", () => {
console.log('Iframe loaded event triggered');
setTimeout(() => injectCSS(chatFrame), 100);
});
});
}
}, 1000);
});
// Additional fallback - try to inject CSS periodically and setup input listeners
setInterval(() => {
const iframe = document.querySelector("#chatBotManFrame") ||
document.querySelector("iframe[src*='widget']") ||
document.querySelector("#botmanChatRoot iframe");
if (iframe && !currentIframe) {
currentIframe = iframe;
console.log('Iframe reference updated via periodic check');
// Setup input listeners when iframe is found
setTimeout(() => setupInputFocusListeners(), 1000);
}
if (iframe && currentIframe) {
try {
const doc = iframe.contentDocument || iframe.contentWindow.document;
const chatElement = doc?.querySelector("#messageArea .chat");
if (chatElement) {
const expectedHeight = isMobile ? (isInputFocused ? 400 : 700) : 800;
const actualHeight = parseInt(chatElement.style.height);
if (actualHeight !== expectedHeight) {
console.log('Periodic CSS injection attempt - height mismatch');
adjustChatHeight(expectedHeight);
}
// Check if input listeners need to be setup
const userTextInput = doc.querySelector('#userText');
if (userTextInput && !userTextInput.hasAttribute('data-listeners-attached')) {
console.log('Input found without listeners, setting up...');
setupInputFocusListeners();
}
}
} catch (e) {
// Silently handle cross-origin errors
}
}
}, 3000);
// Debug function to manually test height changes
window.debugChatHeight = function(height) {
console.log('Manual height adjustment:', height);
adjustChatHeight(height);
};
// Debug function to check current state
window.debugInputState = function() {
console.log('Current state:', {
isMobile: isMobile,
isInputFocused: isInputFocused,
currentChatHeight: currentChatHeight,
currentIframe: !!currentIframe
});
if (currentIframe) {
try {
const doc = currentIframe.contentDocument || currentIframe.contentWindow.document;
const userTextInput = doc?.querySelector('#userText');
console.log('userText input found:', !!userTextInput);
if (userTextInput) {
console.log('Input is focused:', document.activeElement === userTextInput);
}
} catch (e) {
console.log('Cannot access iframe document');
}
}
};
// Debug function to manually setup input listeners
window.debugSetupInputListeners = function() {
console.log('Manually setting up input listeners');
setupInputFocusListeners();
};
</script>
<!-- <script src="https://cdn.jsdelivr.net/npm/botman-web-widget@latest"></script> -->
<!-- <script id="botmanWidget" src='https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/chat.js'></script> -->
<!-- <script src='https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js'></script> -->
<script src='https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js'></script>
</body>
</html>
</html>

84
app/Views/chatbottest.php Normal file
View File

@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Insurance ChatBot</title>
</head>
<style type="text/css">
</style>
<body>
<h1>Welcome to Insurance ChatBot </h1>
<script>
// var botmanWidget = {
// frameEndpoint: 'https://localhost/PHP828APPS/ruc/nhance/chat', // This should match your CI4 route
// introMessage: "Hi! I am your Insurance Bot. How can I assist you today?",
// placeholderText: "Type your message here...",
// title: "Insurance Bot",
// mainColor: "#5C6BC0",
// bubbleBackground: "#673AB7"
// };
var emp_name = 'Kumar';
var uid = Math.floor(100000 + Math.random() * 900000);
console.log('CURRENT_USER' + uid);
var botmanWidget = {
chatServer: `<?=base_url('chat')?>`, // Make sure this URL is correct
frameEndpoint: `<?=base_url('widget')?>`, // This should match your CI4
title: "Ask ILA",
introMessage: "",
bubbleBackground: "#007bff",
mainColor: "#007bff",
placeholderText: "Type your message here...",
aboutText: "Insurance Assistant ILA",
enableAttachments: false,
// Add extra parameters
parameters: {
employee_id: '12288', //PK of emp
session_id: "XYZ789", // token
origin: "mobile", // origin
emp_code:"HTL-007",
client_id:159,
client_branch_id:126
}
};
// Send a first load request when the chat widget opens
// window.addEventListener("load", function () {
// setTimeout(function () {
// fetch("https://localhost/PHP828APPS/ruc/nhance/chat", {
// method: "POST",
// headers: { "Content-Type": "application/json" },
// body: JSON.stringify({ first_load: "true", user_id: "12345" })
// });
// }, 2000); // Slight delay to ensure the widget is ready
// });
window.addEventListener("load", function () {
setTimeout(function () {
if (window.botmanWidget) {
botmanChatWidget.open();
setTimeout(function(){
botmanChatWidget.sayAsBot('Hi '+ (typeof emp_name !== "undefined" && emp_name !== null && emp_name !== "" ? emp_name : "Guest User") +',This is ILA your Insurance Assistant, plz choose the following options')
botmanChatWidget.whisper('Hi');
},3000);
}
}, 2000); // Delay to ensure widget is initialized
});
</script>
<!-- <script src="https://cdn.jsdelivr.net/npm/botman-web-widget@latest"></script> -->
<!-- <script id="botmanWidget" src='https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/chat.js'></script> -->
<!-- <script src='https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js'></script> -->
<script src='https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js'></script>
</body>
</html>