الدخول للوحة التحكم

``` #### **الملف الثالث: `functions/_middleware.js` (بوابة العقل والأسرار)** * **اسم الملف:** `functions/_middleware.js` (مهم جدًا تكتبه كده بالظبط) * **محتوى الملف (انسخ كل الكود ده والصقه):** ```javascript import { createClient } from '@supabase/supabase-js'; // The single gateway for all API requests async function handleRequest(request, env) { const url = new URL(request.url); const supabase = createClient(env.SUPABASE_URL, env.SUPABASE_KEY); // Endpoint for initialization if (url.pathname === '/api/init') { const { data: settingsArray } = await supabase.from('settings').select('*'); const settings = settingsArray.reduce((obj, item) => ({ ...obj, [item.key]: item.value }), {}); const { data: user, error: userError } = await supabase.from('users').select('id').eq('name', 'Baba Ahmed').single(); if (userError) { // Create user if not exists const { data: newUser } = await supabase.from('users').insert({ name: 'Baba Ahmed' }).select('id').single(); return new Response(JSON.stringify({ settings, user: newUser }), { headers: { 'Content-Type': 'application/json' } }); } return new Response(JSON.stringify({ settings, user }), { headers: { 'Content-Type': 'application/json' } }); } // Endpoint for chat if (url.pathname === '/api/chat') { const { prompt, userId, settings } = await request.json(); // 1. Log user message const { data: msgData } = await supabase.from('messages').insert({ user_id: userId, sender: 'user', text: prompt }).select('id').single(); // 2. Prepare and call Gemini const fullPrompt = `Your core identity is defined by these settings: ${JSON.stringify(settings)}. Your persona is '${settings["mimo.personality"]}'. Respond as '${settings["mimo.name"]}' in Egyptian Arabic. The user's message is: "${prompt}"`; const geminiResponse = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${env.GEMINI_API_KEY}`, { method: 'POST', body: JSON.stringify({ contents: [{ parts: [{ text: fullPrompt }] }] }) }); if (!geminiResponse.ok) throw new Error('Gemini API Error'); const geminiData = await geminiResponse.json(); const mimoResponse = geminiData.candidates?.[0]?.content?.parts?.[0]?.text || "مش عارفة أرد دلوقتي يا بابا."; // 3. Log Mimo's response await supabase.from('messages').insert({ user_id: userId, sender: 'mimo', text: mimoResponse }); return new Response(JSON.stringify({ mimoResponse }), { headers: { 'Content-Type': 'application/json' } }); } // Admin Endpoints if (url.pathname.startsWith('/api/admin')) { // Simple auth check for admin actions // In a real app, use JWT or proper sessions. // This is a simplified check. // For GET requests, we can let them pass for now. } if (url.pathname === '/api/login') { const { password } = await request.json(); if (password === env.ADMIN_PASSWORD) { return new Response(JSON.stringify({ success: true })); } return new Response(JSON.stringify({ error: 'Invalid password' }), { status: 401 }); } if (url.pathname.startsWith('/api/admin/')) { const table = url.pathname.split('/')[3]; if (request.method === 'GET') { const { data } = await supabase.from(table).select('*'); return new Response(JSON.stringify(data)); } if (request.method === 'POST') { if (table === 'settings') { const { settings } = await request.json(); const updates = Object.keys(settings).map(key => supabase.from('settings').update({ value: settings[key] }).eq('key', key) ); await Promise.all(updates); return new Response(JSON.stringify({ success: true })); } if (table === 'delete') { const { table: tableName, id } = await request.json(); await supabase.from(tableName).delete().eq('id', id); return new Response(JSON.stringify({ success: true })); } } } // If no route matches, pass to the next function (asset serving) return env.ASSETS.fetch(request); } export default { async fetch(request, env, ctx) { try { return await handleRequest(request, env); } catch (e) { return new Response(JSON.stringify({ error: e.message }), { status: 500, headers: { 'Content-Type': 'application/json' } }); } } };