// Webhook receiver for external integrations // Path: /webhook const handler = async (request) => { if (request.method === 'OPTIONS') { let response = new Response('') response.headers.set('Access-Control-Allow-Origin', '*') response.headers.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS') response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Webhook-Secret') return response } // GET request - return webhook info if (request.method === 'GET') { let response = new Response(JSON.stringify({ endpoint: '/webhook', method: 'POST', supported_sources: ['gitea', 'stripe', 'supabase', 'default'], usage: 'POST /webhook?source=gitea with JSON body' }, null, 2)) response.headers.set('Content-Type', 'application/json') response.headers.set('Access-Control-Allow-Origin', '*') return response } // POST request - receive and forward webhook if (request.method === 'POST') { try { const timestamp = new Date().toISOString() // Parse request body let payload const contentType = request.headers.get('content-type') || '' if (contentType.indexOf('application/json') !== -1) { payload = await request.json() } else { payload = await request.text() } // Get source from query params let source = 'default' const reqUrl = request.url || '' if (reqUrl.indexOf('?') !== -1) { const queryString = reqUrl.split('?')[1] if (queryString) { const params = queryString.split('&') for (let i = 0; i < params.length; i++) { const pair = params[i].split('=') if (pair[0] === 'source' && pair[1]) { source = decodeURIComponent(pair[1]) break } } } } // Forward to appropriate n8n workflow based on source const webhookMap = { 'gitea': 'https://n8n.mylder.io/webhook/gitea-event', 'stripe': 'https://n8n.mylder.io/webhook/stripe-event', 'supabase': 'https://n8n.mylder.io/webhook/supabase-event', 'default': 'https://n8n.mylder.io/webhook/generic-event' } const targetUrl = webhookMap[source] || webhookMap['default'] // Forward to n8n (fire and forget) fetch(targetUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ source: source, payload: payload, received_at: timestamp }) }) let response = new Response(JSON.stringify({ received: true, source: source, timestamp: timestamp })) response.headers.set('Content-Type', 'application/json') response.headers.set('Access-Control-Allow-Origin', '*') return response } catch (error) { let response = new Response(JSON.stringify({ received: false, error: error.message || 'Parse error' })) response.headers.set('Content-Type', 'application/json') response.headers.set('Access-Control-Allow-Origin', '*') return response } } // Method not allowed let response = new Response(JSON.stringify({ error: 'Method not allowed' })) response.headers.set('Content-Type', 'application/json') response.headers.set('Access-Control-Allow-Origin', '*') return response } addEventListener('fetch', event => { return event.respondWith(handler(event.request)) })