Files
thrilltrack-explorer/supabase/functions/notify-moderators-report/index.ts
2025-10-21 12:56:53 +00:00

174 lines
4.9 KiB
TypeScript

import { serve } from "https://deno.land/std@0.168.0/http/server.ts";
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";
import { startRequest, endRequest } from "../_shared/logger.ts";
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type, x-request-id',
};
interface NotificationPayload {
reportId: string;
reportType: string;
reportedEntityType: string;
reportedEntityId: string;
reporterName: string;
reason: string;
reportedAt: string;
entityPreview: string;
}
serve(async (req) => {
if (req.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
const tracking = startRequest('notify-moderators-report');
try {
const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
const supabase = createClient(supabaseUrl, supabaseServiceKey);
const payload: NotificationPayload = await req.json();
console.log('Processing report notification:', {
reportId: payload.reportId,
reportType: payload.reportType,
reportedEntityType: payload.reportedEntityType,
requestId: tracking.requestId
});
// Calculate relative time
const reportedAt = new Date(payload.reportedAt);
const now = new Date();
const diffMs = now.getTime() - reportedAt.getTime();
const diffMins = Math.floor(diffMs / 60000);
let relativeTime: string;
if (diffMins < 1) {
relativeTime = 'just now';
} else if (diffMins < 60) {
relativeTime = `${diffMins} minute${diffMins === 1 ? '' : 's'} ago`;
} else {
const diffHours = Math.floor(diffMins / 60);
relativeTime = `${diffHours} hour${diffHours === 1 ? '' : 's'} ago`;
}
// Determine priority based on report type and age
let priority: string;
const criticalTypes = ['harassment', 'offensive'];
const isUrgent = diffMins < 5;
if (criticalTypes.includes(payload.reportType) || isUrgent) {
priority = 'high';
} else if (diffMins < 30) {
priority = 'medium';
} else {
priority = 'low';
}
// Fetch the workflow ID for report alerts
const { data: template, error: templateError } = await supabase
.from('notification_templates')
.select('workflow_id')
.eq('workflow_id', 'report-alert')
.eq('is_active', true)
.maybeSingle();
if (templateError) {
console.error('Error fetching workflow:', templateError);
throw new Error(`Failed to fetch workflow: ${templateError.message}`);
}
if (!template) {
console.warn('No active report-alert workflow found');
return new Response(
JSON.stringify({
success: false,
error: 'No active report-alert workflow configured',
}),
{
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
status: 400,
}
);
}
// Build enhanced notification payload
const notificationPayload = {
reportId: payload.reportId,
reportType: payload.reportType,
reportedEntityType: payload.reportedEntityType,
reportedEntityId: payload.reportedEntityId,
reporterName: payload.reporterName,
reason: payload.reason,
entityPreview: payload.entityPreview,
reportedAt: payload.reportedAt,
relativeTime,
priority,
};
console.log('Triggering notification with payload:', notificationPayload);
// Invoke the trigger-notification function
const { data: result, error: notifyError } = await supabase.functions.invoke(
'trigger-notification',
{
body: {
workflowId: template.workflow_id,
topicKey: 'moderation-reports',
payload: notificationPayload,
},
}
);
if (notifyError) {
console.error('Error triggering notification:', notifyError);
throw notifyError;
}
console.log('Notification triggered successfully:', result);
endRequest(tracking, 200);
return new Response(
JSON.stringify({
success: true,
transactionId: result?.transactionId,
payload: notificationPayload,
requestId: tracking.requestId
}),
{
headers: {
...corsHeaders,
'Content-Type': 'application/json',
'X-Request-ID': tracking.requestId
},
status: 200,
}
);
} catch (error: any) {
console.error('Error in notify-moderators-report:', error);
endRequest(tracking, 500, error.message);
return new Response(
JSON.stringify({
success: false,
error: error.message,
requestId: tracking.requestId
}),
{
headers: {
...corsHeaders,
'Content-Type': 'application/json',
'X-Request-ID': tracking.requestId
},
status: 500,
}
);
}
});