resend e fcm

This commit is contained in:
2026-05-30 12:26:53 +02:00
parent bd81173559
commit 727eaac3d9

View File

@@ -8,24 +8,21 @@ const corsHeaders = {
}
serve(async (req) => {
// Gestione CORS per sicurezza
if (req.method === 'OPTIONS') {
return new Response('ok', { headers: corsHeaders })
}
try {
// 1. Inizializziamo il client Supabase con i poteri di Service Role (per scavalcare le RLS)
// 1. Client Supabase (Service Role)
const supabaseClient = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
)
// 2. Recuperiamo la chiave di Firebase dai Secrets
// 2. Setup Firebase (Push)
const firebaseSecret = Deno.env.get('FIREBASE_SERVICE_ACCOUNT')
if (!firebaseSecret) throw new Error('Missing FIREBASE_SERVICE_ACCOUNT secret')
const credentials = JSON.parse(firebaseSecret)
// 3. Prepariamo l'autenticazione OAuth2 per Firebase HTTP v1
const jwtClient = new JWT({
email: credentials.client_email,
key: credentials.private_key,
@@ -34,36 +31,45 @@ serve(async (req) => {
const tokens = await jwtClient.getAccessToken()
const fcmAccessToken = tokens.token
// 4. Selezioniamo i reminder da inviare (trigger_at passato e non ancora inviati)
// 3. Setup Resend (Email)
const resendApiKey = Deno.env.get('RESEND_API_KEY')
if (!resendApiKey) throw new Error('Missing RESEND_API_KEY secret')
// 4. Recupero Promemoria (TUTTI i canali, non ancora inviati)
const { data: reminders, error: fetchError } = await supabaseClient
.from('task_reminders')
.select('id, task_id, staff_id, channel, tasks(title, description)')
.eq('channel', 'push')
.select(`
id, task_id, staff_id, channel,
tasks(title, description),
staff_members(email, first_name)
`)
.eq('is_sent', false)
.lte('trigger_at', new Date().toISOString())
if (fetchError) throw fetchError
if (!reminders || reminders.length === 0) {
return new Response(JSON.stringify({ message: 'Nessun promemoria push da inviare.' }), {
return new Response(JSON.stringify({ message: 'Nessun promemoria da inviare.' }), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
status: 200,
})
}
// 5. Ciclo sui promemoria per raccogliere i token ed inviare
// 5. Smistamento ed Invio
for (const reminder of reminders) {
const taskTitle = reminder.tasks?.title || 'Nuovo Task!';
const taskBody = reminder.tasks?.description || 'Hai un task da completare.';
const taskBody = reminder.tasks?.description || 'Hai un task in scadenza.';
const staffEmail = reminder.staff_members?.email;
const staffName = reminder.staff_members?.first_name || 'Staff';
// Preleviamo tutti i dispositivi registrati per questo specifico membro dello staff
if (reminder.channel === 'push') {
// --- LOGICA PUSH ---
const { data: devices } = await supabaseClient
.from('staff_devices')
.select('fcm_token')
.eq('staff_id', reminder.staff_id)
if (devices && devices.length > 0) {
// Spediamo la notifica a OGNI dispositivo associato all'utente
for (const device of devices) {
try {
await fetch(
@@ -77,25 +83,42 @@ serve(async (req) => {
body: JSON.stringify({
message: {
token: device.fcm_token,
notification: {
title: taskTitle,
body: taskBody,
},
data: {
click_action: 'FLUTTER_NOTIFICATION_CLICK',
taskId: reminder.task_id, // Fondamentale per far scattare il Deep Link all'apertura!
},
notification: { title: taskTitle, body: taskBody },
data: { click_action: 'FLUTTER_NOTIFICATION_CLICK', taskId: reminder.task_id },
},
}),
}
)
} catch (pushErr) {
console.error(`Errore invio push al token ${device.fcm_token}:`, pushErr)
} catch (err) {
console.error(`Errore FCM token ${device.fcm_token}:`, err)
}
}
}
} else if (reminder.channel === 'email' && staffEmail) {
// --- LOGICA EMAIL (RESEND) ---
try {
await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${resendApiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'FLUX Reminders <onboarding@resend.dev>', // Sostituirai con la tua email verificata in futuro
to: staffEmail,
subject: `Promemoria: ${taskTitle}`,
html: `<p>Ciao ${staffName},</p>
<p>Questo è un promemoria per il task: <strong>${taskTitle}</strong>.</p>
<p>Dettagli: ${taskBody}</p>
<p><br>Il team FLUX</p>`,
}),
})
} catch (err) {
console.error(`Errore invio Email a ${staffEmail}:`, err)
}
}
// 6. Segnamo il reminder come inviato per non riprocessarlo al prossimo giro
// 6. Segna come inviato
await supabaseClient
.from('task_reminders')
.update({ is_sent: true, updated_at: new Date().toISOString() })