UNPKG

n8n-nodes-enhanced-chat

Version:

Enhanced Chat UI for n8n - Complete interactive chat solution with Enhanced Chat Trigger, Chat UI Renderer, HTML Renderer, and Callback Handler nodes. Features dynamic forms, media, WebRTC, and interactive workflows.

189 lines (175 loc) 6.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChatTestUtils = exports.sanitizeInput = exports.generateSessionId = void 0; function generateSessionId() { return 'sess_' + Math.random().toString(36).substr(2, 9); } exports.generateSessionId = generateSessionId; function sanitizeInput(input) { // Basic sanitization: escape < and > return input.replace(/</g, '&lt;').replace(/>/g, '&gt;'); } exports.sanitizeInput = sanitizeInput; class ChatTestUtils { static generateTestChatPopup(config) { const { webhookUrl, method, title, width, height } = config; return ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>${title}</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f5f5f5; } .container { max-width: 100%; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } .header { text-align: center; margin-bottom: 20px; } .test-button { background-color: #007bff; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; font-size: 16px; margin: 10px; } .test-button:hover { background-color: #0056b3; } .response-container { margin-top: 20px; padding: 15px; background-color: #f8f9fa; border-radius: 5px; border: 1px solid #dee2e6; } .loading { text-align: center; color: #666; font-style: italic; } .error { color: #dc3545; font-weight: bold; } .success { color: #28a745; font-weight: bold; } .webhook-info { background-color: #e9ecef; padding: 10px; border-radius: 5px; margin-bottom: 20px; font-family: monospace; font-size: 12px; } </style> </head> <body> <div class="container"> <div class="header"> <h1>${title}</h1> <p>Test your chat webhook functionality</p> </div> <div class="webhook-info"> <strong>Webhook URL:</strong> ${webhookUrl}<br> <strong>Method:</strong> ${method} </div> <div style="text-align: center;"> <button class="test-button" onclick="testWebhook()">Test Webhook</button> <button class="test-button" onclick="clearResponse()">Clear Response</button> </div> <div id="response-container" class="response-container" style="display: none;"> <h3>Response:</h3> <div id="response-content"></div> </div> </div> <script> async function testWebhook() { const responseContainer = document.getElementById('response-container'); const responseContent = document.getElementById('response-content'); responseContainer.style.display = 'block'; responseContent.innerHTML = '<div class="loading">Loading...</div>'; try { const options = { method: '${method}', headers: { 'Content-Type': 'application/json', } }; if ('${method}' === 'POST') { options.body = JSON.stringify({ testMessage: 'Test message from popup', timestamp: new Date().toISOString(), chatInput: 'Hello from Test Chat!', sessionId: 'test-session-' + Date.now() }); } const response = await fetch('${webhookUrl}', options); const data = await response.json(); if (response.ok) { responseContent.innerHTML = '<div class="success">✅ Success!</div>'; // Check if response contains HTML content if (data.html) { responseContent.innerHTML += '<div style="margin-top: 10px;">' + data.html + '</div>'; } else if (data.response && data.response.html) { responseContent.innerHTML += '<div style="margin-top: 10px;">' + data.response.html + '</div>'; } else { responseContent.innerHTML += '<pre style="background: #f8f9fa; padding: 10px; border-radius: 5px; margin-top: 10px; text-align: left;">' + JSON.stringify(data, null, 2) + '</pre>'; } } else { responseContent.innerHTML = '<div class="error">❌ Error: ' + response.status + ' - ' + response.statusText + '</div>'; } } catch (error) { responseContent.innerHTML = '<div class="error">❌ Error: ' + error.message + '</div>'; console.error('Test webhook error:', error); } } function clearResponse() { document.getElementById('response-container').style.display = 'none'; } // Auto-resize window if needed window.addEventListener('load', function() { const content = document.body.scrollHeight; if (content > ${height}) { window.resizeTo(${width}, Math.min(content + 100, screen.height - 100)); } }); // Focus on the window when it loads window.focus(); </script> </body> </html> `; } static openTestChatWindow(config) { const html = this.generateTestChatPopup(config); const blob = new Blob([html], { type: 'text/html' }); const url = URL.createObjectURL(blob); const popup = window.open(url, 'testChatWindow', `width=${config.width},height=${config.height},scrollbars=yes,resizable=yes`); // Clean up the blob URL after the window is closed if (popup) { popup.addEventListener('beforeunload', () => { URL.revokeObjectURL(url); }); } } } exports.ChatTestUtils = ChatTestUtils;