Programació de les funcionalitats bàsiques en el BackEnd i FrontEnd

Per la creació del FrontEnd hem utilitzat un codi d’HTML amb l’ajuda de la IA Gemini.

Justificació:

En el mateix codi d’html està totes les justificacions del perquè en cada funció.

!DOCTYPE html>
<html lang="ca">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chatbot LAN Party</title>
    <style>
        :root { 
            --accent-color: #ffffff; 
            --dark-bg: #1a1a1a; 
            --text-dark: #000000;
        }

        /* Botó flotant */
        #chat-launcher {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 60px;
            height: 60px;
            background: var(--accent-color);
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            box-shadow: 0 4px 15px rgba(0,0,0,0.3);
            z-index: 1001;
            font-size: 30px;
            transition: transform 0.3s ease;
        }

        #chat-launcher:hover { transform: scale(1.1); }

        /* Contenidor del xat */
        #chat-container { 
            position: fixed; 
            bottom: 90px; 
            right: 20px; 
            width: 350px; 
            height: 500px; 
            background: var(--dark-bg); 
            border-radius: 15px; 
            box-shadow: 0 5px 25px rgba(0,0,0,0.5); 
            display: none; 
            flex-direction: column; 
            font-family: sans-serif; 
            border: 1px solid #333; 
            overflow: hidden; 
            z-index: 1000; 
        }

        #chat-header { 
            background: var(--accent-color); 
            color: var(--text-dark); 
            padding: 15px; 
            font-weight: bold; 
            text-align: center; 
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        #close-chat { cursor: pointer; font-size: 20px; padding: 0 5px; }

        #chat-box { flex: 1; padding: 15px; overflow-y: auto; color: white; display: flex; flex-direction: column; gap: 10px; }
        
        .message { max-width: 80%; padding: 10px; border-radius: 10px; font-size: 14px; line-height: 1.4; word-wrap: break-word; }
        .bot-msg { background: #333; align-self: flex-start; border-bottom-left-radius: 2px; }
        .user-msg { background: var(--accent-color); color: var(--text-dark); align-self: flex-end; border-bottom-right-radius: 2px; }

        #chat-input-area { display: flex; padding: 10px; background: #222; }
        #user-input { flex: 1; padding: 10px; border: none; border-radius: 5px; outline: none; }
        
        #send-btn { 
            background: var(--accent-color); 
            color: var(--text-dark);
            border: none; 
            padding: 10px 15px; 
            margin-left: 5px; 
            border-radius: 5px; 
            cursor: pointer; 
            font-weight: bold; 
        }

        /* Indicador de càrrega */
        .typing { font-style: italic; font-size: 12px; color: #888; margin-bottom: 10px; }
    </style>
</head>
<body>

<div id="chat-launcher" onclick="toggleChat()">🕹️</div>

<div id="chat-container">
    <div id="chat-header">
        <span>Assistent IA LAN Party</span>
        <span id="close-chat" onclick="toggleChat()">×</span>
    </div>
    <div id="chat-box">
        <div class="message bot-msg">Hola! Soc l'assistent intel·ligent. Pregunta'm el que vulguis sobre la LAN Party de Castellbisbal!</div>
    </div>
    <div id="chat-input-area">
        <input type="text" id="user-input" placeholder="Escriu aquí...">
        <button id="send-btn" onclick="handleSend()">></button>
    </div>
</div>

<script>
    // --- IMPORTANT: Aquí poses l'URL que et doni Ngrok al Colab ---
    const NGROK_URL = "https://nonexternally-squarable-suk.ngrok-free.dev"; 

    const chatContainer = document.getElementById('chat-container');
    const chatBox = document.getElementById('chat-box');
    const userInput = document.getElementById('user-input');

    function toggleChat() {
        chatContainer.style.display = (chatContainer.style.display === 'flex') ? 'none' : 'flex';
    }

    function addMessage(text, sender) {
        const msgDiv = document.createElement('div');
        msgDiv.classList.add('message', sender === 'user' ? 'user-msg' : 'bot-msg');
        msgDiv.innerText = text;
        chatBox.appendChild(msgDiv);
        chatBox.scrollTop = chatBox.scrollHeight;
    }

    async function handleSend() {
        const text = userInput.value.trim();
        if (!text) return;

        // Afegim el missatge de l'usuari a la pantalla
        addMessage(text, 'user');
        userInput.value = "";

        // Mostrem un petit indicador de que la IA està pensant
        const loadingDiv = document.createElement('div');
        loadingDiv.className = 'typing';
        loadingDiv.innerText = "L'assistent està escrivint...";
        chatBox.appendChild(loadingDiv);
        chatBox.scrollTop = chatBox.scrollHeight;

        try {
            // Cridem al Backend de Google Colab
            const response = await fetch(`${NGROK_URL}/chat`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ message: text })
            });

            const data = await response.json();
            
            // Eliminem l'indicador de càrrega i posem la resposta de Gemini
            chatBox.removeChild(loadingDiv);
            addMessage(data.reply, 'bot');

        } catch (error) {
            chatBox.removeChild(loadingDiv);
            addMessage("Error de connexió. Revisa si el servidor Colab està actiu.", 'bot');
            console.error("Error:", error);
        }
    }

    userInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') handleSend(); });
</script>

</body>
</html>

Gestió de Dades Estructurades (JSON)

Aquí es veu com faig que la llibreria Flask demani (creï) un document JSON.

from flask import Flask, request, jsonify

Arxiu el qual demana el codi més endavant en aquesta part:

    try:
        user_input = request.json.get("message")
        response = chat.send_message(user_input)
        return jsonify({"reply": response.text})
    except Exception as e:
        return jsonify({"reply": f"Error: {str(e)}"}), 500

L’Endpoint de Flask i el retorn de dades (Python)

Això es troba al teu fitxer de Colab. És la part que “escolta” les preguntes i “retorna” les respostes.

  • L’Endpoint: Es defineix amb @app.route('/ask', methods=['POST']). És la “porta” d’entrada.
  • El retorn de dades: Es fa amb: 
    try:
        user_input = request.json.get("message")
        response = chat.send_message(user_input)
        return jsonify({"reply": response.text})
    except Exception as e:
        return jsonify({"reply": f"Error: {str(e)}"}), 500
 --- SERVIDOR FLASK ---
app = Flask(__name__)
CORS(app)

@app.route('/chat', methods=['POST'])
def get_chat_response():
    try:
        user_input = request.json.get("message")
        response = chat.send_message(user_input)
        return jsonify({"reply": response.text})
    except Exception as e:
        return jsonify({"reply": f"Error: {str(e)}"}), 500

El Túnel de ngrok (Python)

Això es troba al final del teu codi de Colab. És el que permet que la teva web de Google Sites (que està a internet) pugui “parlar” amb el teu ordinador (que és privat).

# --- NGROK ---
ngrok.kill()
ngrok.set_auth_token(NGROK_TOKEN)
public_url = ngrok.connect(5000).public_url
print(f"\n🚀 BACKEND ACTIU!")
print(f"🔗 URL per al teu HTML: {public_url}")

app.run(port=5000)