/** * Lokaler Reverse Proxy fΓΌr PTV Geocoding API * Umgeht CORS-Probleme bei der Entwicklung */ const http = require('http'); const https = require('https'); const url = require('url'); const PORT = 3000; const PTV_API_BASE = 'https://api.myptv.com'; // CORS Headers fΓΌr alle Responses const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Content-Type': 'application/json', }; const server = http.createServer((req, res) => { console.log(`πŸ“¨ ${req.method} ${req.url}`); // Health check endpoint if (req.url === '/health') { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('healthy'); return; } // Handle preflight requests if (req.method === 'OPTIONS') { res.writeHead(200, corsHeaders); res.end(); return; } // Nur GET Requests erlauben if (req.method !== 'GET') { res.writeHead(405, corsHeaders); res.end(JSON.stringify({ error: 'Method not allowed' })); return; } // Parse URL const parsedUrl = url.parse(req.url, true); const { lat, lon, apiKey } = parsedUrl.query; // Validierung if (!lat || !lon || !apiKey) { res.writeHead(400, corsHeaders); res.end(JSON.stringify({ error: 'Missing parameters: lat, lon, apiKey are required', })); return; } // PTV API URL erstellen const ptvUrl = `${PTV_API_BASE}/geocoding/v1/locations/by-position/${lat}/${lon}?language=de&apiKey=${apiKey}`; console.log(`πŸ”„ Weiterleitung an: ${ptvUrl.replace(apiKey, 'API_KEY_HIDDEN')}`); // Request an PTV API https.get(ptvUrl, (ptvRes) => { let data = ''; ptvRes.on('data', (chunk) => { data += chunk; }); ptvRes.on('end', () => { try { const jsonData = JSON.parse(data); // Erfolgreiche Response if (ptvRes.statusCode === 200) { console.log('βœ… PTV API Response erfolgreich'); // Adresse extrahieren if (jsonData.locations && jsonData.locations.length > 0) { const location = jsonData.locations[0]; if (location.address) { const address = location.address; const street = address.street || ''; const houseNumber = address.houseNumber || ''; const postalCode = address.postalCode || ''; const city = address.city || ''; const formattedAddress = `${street} ${houseNumber}, ${postalCode} ${city}`.trim(); const response = { success: true, location: formattedAddress, coordinates: { lat: parseFloat(lat), lon: parseFloat(lon), }, rawData: location, }; console.log(`πŸ“ Adresse: ${formattedAddress}`); res.writeHead(200, corsHeaders); res.end(JSON.stringify(response)); return; } } // Fallback auf Koordinaten const response = { success: true, location: `Lat: ${parseFloat(lat).toFixed(6)}, Lon: ${parseFloat(lon).toFixed(6)}`, coordinates: { lat: parseFloat(lat), lon: parseFloat(lon), }, }; res.writeHead(200, corsHeaders); res.end(JSON.stringify(response)); } else { // Fehler von PTV API console.log(`❌ PTV API Fehler: ${ptvRes.statusCode}`); res.writeHead(ptvRes.statusCode, corsHeaders); res.end(JSON.stringify({ success: false, error: `PTV API Error: ${ptvRes.statusCode}`, fallbackLocation: `Lat: ${parseFloat(lat).toFixed(6)}, Lon: ${parseFloat(lon).toFixed(6)}`, })); } } catch (error) { console.error('❌ JSON Parse Fehler:', error.message); res.writeHead(500, corsHeaders); res.end(JSON.stringify({ success: false, error: 'Failed to parse PTV API response', fallbackLocation: `Lat: ${parseFloat(lat).toFixed(6)}, Lon: ${parseFloat(lon).toFixed(6)}`, })); } }); }).on('error', (error) => { console.error('❌ Request Fehler:', error.message); res.writeHead(500, corsHeaders); res.end(JSON.stringify({ success: false, error: error.message, fallbackLocation: `Lat: ${parseFloat(lat).toFixed(6)}, Lon: ${parseFloat(lon).toFixed(6)}`, })); }); }); server.listen(PORT, () => { console.log('═══════════════════════════════════════════════════════'); console.log('πŸš€ Lokaler Reverse Proxy Server gestartet!'); console.log(`πŸ“‘ LΓ€uft auf: http://localhost:${PORT}`); console.log(''); console.log('πŸ“Œ Verwendung:'); console.log(` http://localhost:${PORT}/?lat=47.9385&lon=13.7629&apiKey=YOUR_KEY`); console.log(''); console.log('⚠️ Hinweis: Nur fΓΌr Entwicklung verwenden!'); console.log(' FΓΌr Produktion: Appwrite Function deployen'); console.log('═══════════════════════════════════════════════════════'); console.log(''); console.log('πŸ’‘ Zum Beenden: Strg+C drΓΌcken'); console.log(''); }); // Graceful shutdown process.on('SIGINT', () => { console.log('\n\nπŸ‘‹ Server wird beendet...'); server.close(() => { console.log('βœ… Server erfolgreich gestoppt'); process.exit(0); }); });