Smart Work-Based Chatbot Assistant

Smart Work-Based Chatbot Assistant

Your AI-powered partner for productivity.

Hello! I am your smart assistant. How can I help you with your work today? Feel free to ask me about drafting emails, summarizing text, brainstorming ideas, or anything else.

${sanitizedMessage}

U
`; } else { // bot messageDiv.className = 'flex items-start gap-3'; // Simple markdown processing for lists and bold text let formattedMessage = sanitizedMessage.replace(/\*\*(.*?)\*\*/g, '$1'); // Bold formattedMessage = formattedMessage.replace(/^\* (.*$)/gm, '
  • $1
  • '); // List items formattedMessage = formattedMessage.replace(/(\.*\<\/li\>)/gs, '
      $1
    '); // Wrap lists messageDiv.innerHTML = `

    ${formattedMessage}

    `; } chatHistory.appendChild(messageDiv); chatHistory.scrollTop = chatHistory.scrollHeight; } /** * Shows or hides the bot's "thinking..." indicator. * @param {boolean} show - Whether to show or hide the indicator. */ function showThinkingIndicator(show) { let indicator = document.getElementById('thinking-indicator'); if (show) { if (!indicator) { indicator = document.createElement('div'); indicator.id = 'thinking-indicator'; indicator.className = 'flex items-start gap-3'; indicator.innerHTML = `

    Thinking...

    `; chatHistory.appendChild(indicator); chatHistory.scrollTop = chatHistory.scrollHeight; } } else { if (indicator) { indicator.remove(); } } } /** * Sends a message to the Gemini API and gets a response. * @param {string} userMessage - The user's message. */ async function getBotResponse(userMessage) { showThinkingIndicator(true); sendButton.disabled = true; // Add the new user message to the conversation history conversationHistory.push({ role: "user", parts: [{ text: userMessage }] }); const payload = { contents: conversationHistory, systemInstruction: systemPrompt }; const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`; try { const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) { throw new Error(`API request failed with status ${response.status}`); } const result = await response.json(); showThinkingIndicator(false); if (result.candidates && result.candidates.length > 0 && result.candidates[0].content && result.candidates[0].content.parts) { const botMessage = result.candidates[0].content.parts[0].text; addMessageToUI('bot', botMessage); // Add the bot's response to the conversation history conversationHistory.push({ role: "model", parts: [{ text: botMessage }] }); } else { addMessageToUI('bot', "I'm sorry, I couldn't generate a response. Please try again."); } } catch (error) { console.error("Error fetching bot response:", error); showThinkingIndicator(false); addMessageToUI('bot', "I'm having trouble connecting. Please check your connection and try again."); } finally { sendButton.disabled = false; } } /** * Handles the chat form submission. */ async function handleChatSubmit(e) { e.preventDefault(); const userMessage = messageInput.value.trim(); if (userMessage) { addMessageToUI('user', userMessage); messageInput.value = ''; await getBotResponse(userMessage); } } /** * Generates and downloads a PDF of the chat history. */ async function generatePdf() { const { jsPDF } = window.jspdf; if (conversationHistory.length === 0) { alert("The chat is empty. Nothing to export."); return; } downloadPdfBtn.disabled = true; try { const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); const page_width = pdf.internal.pageSize.getWidth(); const margin = 40; let cursor_y = margin; // Header pdf.setFontSize(18); pdf.setFont("helvetica", "bold"); pdf.text("Chatbot Conversation Transcript", page_width / 2, cursor_y, { align: 'center' }); cursor_y += 30; // Loop through conversation for (const entry of conversationHistory) { const isUser = entry.role === 'user'; const text = entry.parts[0].text; const speaker = isUser ? "You:" : "Assistant:"; const textLines = pdf.splitTextToSize(text, page_width - margin * 2 - 10); const requiredHeight = (textLines.length * 12) + 25; if (cursor_y + requiredHeight > pdf.internal.pageSize.getHeight() - margin) { pdf.addPage(); cursor_y = margin; } // Speaker Label pdf.setFontSize(10); pdf.setFont("helvetica", "bold"); pdf.setTextColor(isUser ? 59 : 100, isUser ? 130 : 116, isUser ? 246 : 139); // Blue for user, Slate for bot pdf.text(speaker, margin, cursor_y); cursor_y += 15; // Message Text pdf.setFontSize(11); pdf.setFont("helvetica", "normal"); pdf.setTextColor(51, 65, 85); pdf.text(textLines, margin, cursor_y); cursor_y += requiredHeight; }; // Footer const pageCount = pdf.internal.getNumberOfPages(); for (let i = 1; i <= pageCount; i++) { pdf.setPage(i); pdf.setFontSize(8); pdf.setTextColor(150); pdf.text(`Page ${i} of ${pageCount}`, page_width / 2, pdf.internal.pageSize.getHeight() - 20, { align: 'center' }); } pdf.save('Chat_Transcript.pdf'); } catch (error) { console.error("Error generating PDF:", error); alert("Could not generate PDF. Please try again."); } finally { downloadPdfBtn.disabled = false; } } // --- Initial Setup --- document.addEventListener('DOMContentLoaded', () => { chatForm.addEventListener('submit', handleChatSubmit); downloadPdfBtn.addEventListener('click', generatePdf); });
    Scroll to Top