User Tools

Site Tools


wiki:ai:emotional_support_bot

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

wiki:ai:emotional_support_bot [2025/07/21 04:34] – created ymurugesanwiki:ai:emotional_support_bot [2025/07/21 04:37] (current) ymurugesan
Line 319: Line 319:
 </code> </code>
  
 +
 +src/index.html
 +
 +<code>
 +
 +<!DOCTYPE html>
 +<html lang="en">
 +<head>
 +    <meta charset="UTF-8">
 +    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 +    <title>Sentiment Support Bot</title>
 +    <style>
 +        * {
 +            margin: 0;
 +            padding: 0;
 +            box-sizing: border-box;
 +        }
 +
 +        body {
 +            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
 +            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 +            min-height: 100vh;
 +            display: flex;
 +            align-items: center;
 +            justify-content: center;
 +            padding: 20px;
 +        }
 +
 +        .container {
 +            background: rgba(255, 255, 255, 0.95);
 +            backdrop-filter: blur(10px);
 +            border-radius: 20px;
 +            padding: 30px;
 +            max-width: 600px;
 +            width: 100%;
 +            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
 +        }
 +
 +        .header {
 +            text-align: center;
 +            margin-bottom: 30px;
 +        }
 +
 +        .header h1 {
 +            color: #333;
 +            font-size: 2.5em;
 +            font-weight: 700;
 +            margin-bottom: 10px;
 +        }
 +
 +        .header p {
 +            color: #666;
 +            font-size: 1.1em;
 +        }
 +
 +        .chat-container {
 +            background: #f8f9fa;
 +            border-radius: 15px;
 +            padding: 20px;
 +            margin-bottom: 20px;
 +            min-height: 300px;
 +            max-height: 400px;
 +            overflow-y: auto;
 +        }
 +
 +        .message {
 +            margin-bottom: 15px;
 +            padding: 15px;
 +            border-radius: 12px;
 +            max-width: 80%;
 +            word-wrap: break-word;
 +            animation: fadeIn 0.3s ease-in;
 +        }
 +
 +        .user-message {
 +            background: #007bff;
 +            color: white;
 +            margin-left: auto;
 +            text-align: right;
 +        }
 +
 +        .bot-message {
 +            background: white;
 +            color: #333;
 +            border: 1px solid #e0e0e0;
 +            margin-right: auto;
 +        }
 +
 +        .sentiment-indicator {
 +            display: inline-block;
 +            padding: 4px 8px;
 +            border-radius: 20px;
 +            font-size: 0.8em;
 +            font-weight: 600;
 +            margin-bottom: 8px;
 +        }
 +
 +        .sentiment-positive { background: #d4edda; color: #155724; }
 +        .sentiment-negative { background: #f8d7da; color: #721c24; }
 +        .sentiment-neutral { background: #e2e3e5; color: #383d41; }
 +
 +        .input-container {
 +            display: flex;
 +            gap: 10px;
 +            margin-bottom: 20px;
 +        }
 +
 +        .input-field {
 +            flex: 1;
 +            padding: 15px;
 +            border: 2px solid #e0e0e0;
 +            border-radius: 12px;
 +            font-size: 1em;
 +            outline: none;
 +            transition: border-color 0.3s ease;
 +        }
 +
 +        .input-field:focus {
 +            border-color: #007bff;
 +        }
 +
 +        .send-button {
 +            background: linear-gradient(45deg, #007bff, #0056b3);
 +            color: white;
 +            border: none;
 +            padding: 15px 25px;
 +            border-radius: 12px;
 +            font-size: 1em;
 +            font-weight: 600;
 +            cursor: pointer;
 +            transition: transform 0.2s ease, box-shadow 0.2s ease;
 +        }
 +
 +        .send-button:hover {
 +            transform: translateY(-2px);
 +            box-shadow: 0 10px 20px rgba(0, 123, 255, 0.3);
 +        }
 +
 +        .send-button:disabled {
 +            background: #ccc;
 +            cursor: not-allowed;
 +            transform: none;
 +            box-shadow: none;
 +        }
 +
 +
 +
 +        .loading {
 +            display: none;
 +            text-align: center;
 +            color: #666;
 +            font-style: italic;
 +        }
 +
 +        .error {
 +            color: #dc3545;
 +            background: #f8d7da;
 +            padding: 10px;
 +            border-radius: 8px;
 +            margin-bottom: 15px;
 +        }
 +
 +        @keyframes fadeIn {
 +            from { opacity: 0; transform: translateY(10px); }
 +            to { opacity: 1; transform: translateY(0); }
 +        }
 +
 +        @media (max-width: 600px) {
 +            .input-container {
 +                flex-direction: column;
 +            }
 +        }
 +    </style>
 +</head>
 +<body>
 +    <div class="container">
 +        <div class="header">
 +            <h1>💬 Sentiment Support Bot</h1>
 +            <p>AI-powered emotional support with sentiment analysis</p>
 +        </div>
 +
 +
 +
 +        <div class="chat-container" id="chatContainer">
 +            <div class="message bot-message">
 +                <div class="sentiment-indicator sentiment-positive">Positive</div>
 +                Hello! I'm here to provide emotional support. Please share what's on your mind, and I'll analyze your sentiment and respond accordingly.
 +            </div>
 +        </div>
 +
 +        <div class="loading" id="loading">Analyzing sentiment and generating response...</div>
 +        <div class="error" id="error" style="display: none;"></div>
 +
 +        <div class="input-container">
 +            <input type="text" id="userInput" class="input-field" placeholder="Share your thoughts or feelings..." onkeypress="handleKeyPress(event)">
 +            <button onclick="sendMessage()" class="send-button" id="sendButton">Send</button>
 +        </div>
 +    </div>
 +
 +    <script>
 +        class SentimentSupportBot {
 +            constructor() {
 +                this.chatContainer = document.getElementById('chatContainer');
 +                this.userInput = document.getElementById('userInput');
 +                this.sendButton = document.getElementById('sendButton');
 +                this.loading = document.getElementById('loading');
 +                this.error = document.getElementById('error');
 +                this.conversationHistory = [];
 +            }
 +
 +            async analyzeSentiment(text) {
 +                const response = await fetch('/api/analyze-sentiment', {
 +                    method: 'POST',
 +                    headers: {
 +                        'Content-Type': 'application/json'
 +                    },
 +                    body: JSON.stringify({ text })
 +                });
 +
 +                if (!response.ok) {
 +                    throw new Error(`Sentiment analysis failed: ${response.status}`);
 +                }
 +
 +                const data = await response.json();
 +                return data;
 +            }
 +
 +            async generateSupportResponse(userMessage, sentiment) {
 +                const messages = [
 +                    ...this.conversationHistory,
 +                    { role: 'user', content: userMessage }
 +                ];
 +
 +                const response = await fetch('/api/generate-response', {
 +                    method: 'POST',
 +                    headers: {
 +                        'Content-Type': 'application/json'
 +                    },
 +                    body: JSON.stringify({
 +                        messages,
 +                        sentiment
 +                    })
 +                });
 +
 +                if (!response.ok) {
 +                    throw new Error(`Response generation failed: ${response.status}`);
 +                }
 +
 +                const data = await response.json();
 +                return data.content;
 +            }
 +
 +            getSystemPrompt(sentiment) {
 +                const sentimentLabel = sentiment.sentiment;
 +                const confidence = sentiment.confidenceScores;
 +
 +                let prompt = `You are an empathetic AI support assistant. The user's message has been analyzed with sentiment: ${sentimentLabel} (positive: ${confidence.positive.toFixed(2)}, neutral: ${confidence.neutral.toFixed(2)}, negative: ${confidence.negative.toFixed(2)}).
 +
 +Based on this sentiment analysis, provide appropriate emotional support:
 +
 +`;
 +
 +                if (sentimentLabel === 'positive') {
 +                    prompt += `- The user seems to be feeling good. Acknowledge their positive emotions and encourage them to continue.
 +- Be supportive and celebratory while staying genuine.
 +- Ask follow-up questions to understand what's going well.`;
 +                } else if (sentimentLabel === 'negative') {
 +                    prompt += `- The user seems to be struggling or feeling down. Provide compassionate support.
 +- Validate their feelings and offer comfort.
 +- Suggest coping strategies or gentle encouragement.
 +- Be careful not to dismiss their concerns.`;
 +                } else {
 +                    prompt += `- The user's sentiment is neutral. Provide balanced support.
 +- Try to understand more about their situation.
 +- Offer helpful guidance without making assumptions.`;
 +                }
 +
 +                prompt += `\n\nKeep responses concise (2-3 sentences), warm, and genuinely supportive. Focus on being helpful rather than clinical.`;
 +
 +                return prompt;
 +            }
 +
 +            addMessage(content, isUser = false, sentiment = null) {
 +                const messageDiv = document.createElement('div');
 +                messageDiv.className = `message ${isUser ? 'user-message' : 'bot-message'}`;
 +                
 +                if (!isUser && sentiment) {
 +                    const sentimentIndicator = document.createElement('div');
 +                    sentimentIndicator.className = `sentiment-indicator sentiment-${sentiment.sentiment}`;
 +                    sentimentIndicator.textContent = sentiment.sentiment.charAt(0).toUpperCase() + sentiment.sentiment.slice(1);
 +                    messageDiv.appendChild(sentimentIndicator);
 +                }
 +                
 +                const contentDiv = document.createElement('div');
 +                contentDiv.textContent = content;
 +                messageDiv.appendChild(contentDiv);
 +                
 +                this.chatContainer.appendChild(messageDiv);
 +                this.chatContainer.scrollTop = this.chatContainer.scrollHeight;
 +            }
 +
 +            showError(message) {
 +                this.error.textContent = message;
 +                this.error.style.display = 'block';
 +                setTimeout(() => {
 +                    this.error.style.display = 'none';
 +                }, 5000);
 +            }
 +
 +            setLoading(isLoading) {
 +                this.loading.style.display = isLoading ? 'block' : 'none';
 +                this.sendButton.disabled = isLoading;
 +                this.userInput.disabled = isLoading;
 +            }
 +
 +            async sendMessage() {
 +                const message = this.userInput.value.trim();
 +                if (!message) return;
 +
 +                this.addMessage(message, true);
 +                this.userInput.value = '';
 +                this.setLoading(true);
 +
 +                try {
 +                    // Analyze sentiment
 +                    const sentimentResult = await this.analyzeSentiment(message);
 +                    
 +                    // Generate response
 +                    const supportResponse = await this.generateSupportResponse(message, sentimentResult);
 +                    
 +                    // Add to conversation history
 +                    this.conversationHistory.push(
 +                        { role: 'user', content: message },
 +                        { role: 'assistant', content: supportResponse }
 +                    );
 +                    
 +                    // Keep only last 10 messages for context
 +                    if (this.conversationHistory.length > 10) {
 +                        this.conversationHistory = this.conversationHistory.slice(-10);
 +                    }
 +                    
 +                    this.addMessage(supportResponse, false, sentimentResult);
 +                    
 +                } catch (error) {
 +                    this.showError(error.message);
 +                } finally {
 +                    this.setLoading(false);
 +                }
 +            }
 +        }
 +
 +        // Initialize the bot
 +        const bot = new SentimentSupportBot();
 +
 +        // Global functions for HTML events
 +        function sendMessage() {
 +            bot.sendMessage();
 +        }
 +
 +        function handleKeyPress(event) {
 +            if (event.key === 'Enter') {
 +                sendMessage();
 +            }
 +        }
 +
 +        // Focus on input when page loads
 +        document.addEventListener('DOMContentLoaded', function() {
 +            document.getElementById('userInput').focus();
 +        });
 +    </script>
 +</body>
 +</html>
 +
 +</code>
 +
 +
 +staticwebapp.config.json
 +
 +<code>
 +
 +{
 +  "routes": [
 +    {
 +      "route": "/api/*",
 +      "methods": ["GET", "POST", "PUT", "DELETE"],
 +      "allowedRoles": ["anonymous"]
 +    },
 +    {
 +      "route": "/*",
 +      "serve": "/index.html",
 +      "statusCode": 200
 +    }
 +  ],
 +  "navigationFallback": {
 +    "rewrite": "/index.html"
 +  },
 +  "mimeTypes": {
 +    ".json": "application/json"
 +  },
 +  "defaultHeaders": {
 +    "content-security-policy": "default-src 'self' 'unsafe-inline' https:",
 +    "x-frame-options": "DENY",
 +    "x-content-type-options": "nosniff"
 +  }
 +}
 +</code>
 +
 +
 +
 +Key points to note:
 +1. do not use function.json for Azure functions v4
 +2. check the build and deploy step to verify function is created.
  
wiki/ai/emotional_support_bot.1753072480.txt.gz · Last modified: by ymurugesan