import { serve } from "https://deno.land/std@0.190.0/http/server.ts"; import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4"; import { edgeLogger, startRequest, endRequest } from '../_shared/logger.ts'; const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type', }; interface EscalationRequest { submissionId: string; escalationReason: string; escalatedBy: string; } serve(async (req) => { const tracking = startRequest(); if (req.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders }); } try { const supabase = createClient( Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '' ); const { submissionId, escalationReason, escalatedBy }: EscalationRequest = await req.json(); edgeLogger.info('Processing escalation notification', { requestId: tracking.requestId, submissionId, escalatedBy, action: 'send_escalation' }); // Fetch submission details const { data: submission, error: submissionError } = await supabase .from('content_submissions') .select('*, profiles:user_id(username, display_name, id)') .eq('id', submissionId) .single(); if (submissionError || !submission) { throw new Error(`Failed to fetch submission: ${submissionError?.message || 'Not found'}`); } // Fetch escalator details const { data: escalator, error: escalatorError } = await supabase .from('profiles') .select('username, display_name') .eq('user_id', escalatedBy) .single(); if (escalatorError) { edgeLogger.error('Failed to fetch escalator profile', { requestId: tracking.requestId, error: escalatorError.message, escalatedBy }); } // Fetch submission items count const { count: itemsCount, error: countError } = await supabase .from('submission_items') .select('*', { count: 'exact', head: true }) .eq('submission_id', submissionId); if (countError) { edgeLogger.error('Failed to fetch items count', { requestId: tracking.requestId, error: countError.message, submissionId }); } // Prepare email content const escalatorName = escalator?.display_name || escalator?.username || 'Unknown User'; const submitterName = submission.profiles?.display_name || submission.profiles?.username || 'Unknown User'; const submissionType = submission.submission_type || 'Unknown'; const itemCount = itemsCount || 0; const emailSubject = `🚨 Submission Escalated: ${submissionType} - ID: ${submissionId.substring(0, 8)}`; const emailHtml = `

⚠️ Submission Escalated

Admin review required

Submission ID: ${submissionId}
Submission Type: ${submissionType}
Items Count: ${itemCount}
Submitted By: ${submitterName}
Escalated By: ${escalatorName}
📝 Escalation Reason:

${escalationReason}

Review Submission →
`; const emailText = ` SUBMISSION ESCALATED - Admin Review Required Submission ID: ${submissionId} Submission Type: ${submissionType} Items Count: ${itemCount} Submitted By: ${submitterName} Escalated By: ${escalatorName} Escalation Reason: ${escalationReason} Please review this submission in the admin panel. `; // Send email via ForwardEmail API const forwardEmailApiKey = Deno.env.get('FORWARDEMAIL_API_KEY'); const adminEmail = Deno.env.get('ADMIN_EMAIL_ADDRESS'); const fromEmail = Deno.env.get('FROM_EMAIL_ADDRESS'); if (!forwardEmailApiKey || !adminEmail || !fromEmail) { throw new Error('Email configuration is incomplete. Please check environment variables.'); } let emailResponse; try { emailResponse = await fetch('https://api.forwardemail.net/v1/emails', { method: 'POST', headers: { 'Authorization': 'Basic ' + btoa(forwardEmailApiKey + ':'), 'Content-Type': 'application/json', }, body: JSON.stringify({ from: fromEmail, to: adminEmail, subject: emailSubject, html: emailHtml, text: emailText, }), }); } catch (fetchError) { edgeLogger.error('Network error sending email', { requestId: tracking.requestId, error: fetchError.message }); throw new Error('Network error: Unable to reach email service'); } if (!emailResponse.ok) { let errorText; try { errorText = await emailResponse.text(); } catch (parseError) { errorText = 'Unable to parse error response'; } edgeLogger.error('ForwardEmail API error', { requestId: tracking.requestId, status: emailResponse.status, errorText }); throw new Error(`Failed to send email: ${emailResponse.status} - ${errorText}`); } let emailResult; try { emailResult = await emailResponse.json(); } catch (parseError) { edgeLogger.error('Failed to parse email API response', { requestId: tracking.requestId, error: parseError.message }); throw new Error('Invalid response from email service'); } edgeLogger.info('Email sent successfully', { requestId: tracking.requestId, emailId: emailResult.id }); // Update submission with notification status const { error: updateError } = await supabase .from('content_submissions') .update({ escalated: true, escalated_at: new Date().toISOString(), escalated_by: escalatedBy, escalation_reason: escalationReason }) .eq('id', submissionId); if (updateError) { edgeLogger.error('Failed to update submission escalation status', { requestId: tracking.requestId, error: updateError.message, submissionId }); } const duration = endRequest(tracking); edgeLogger.info('Escalation notification sent', { requestId: tracking.requestId, duration, emailId: emailResult.id, submissionId }); return new Response( JSON.stringify({ success: true, message: 'Escalation notification sent successfully', emailId: emailResult.id, requestId: tracking.requestId }), { headers: { ...corsHeaders, 'Content-Type': 'application/json', 'X-Request-ID': tracking.requestId } } ); } catch (error) { const duration = endRequest(tracking); edgeLogger.error('Error in send-escalation-notification', { requestId: tracking.requestId, duration, error: error instanceof Error ? error.message : 'Unknown error' }); return new Response( JSON.stringify({ error: error instanceof Error ? error.message : 'Unknown error occurred', details: 'Failed to send escalation notification', requestId: tracking.requestId }), { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json', 'X-Request-ID': tracking.requestId } } ); } });