Aggiungi notifiche e-mail al tuo sito di prenotazione con IA
Invia e-mail di conferma prenotazione e avvisi al titolare usando Supabase, Resend ed Edge Functions.
Roadmap e risorse
Nuovo qui? Parti prima da qui
Questa guida aggiorna il progetto del sito di prenotazione con IA con notifiche e-mail automatiche. Se non hai ancora costruito il sito di prenotazione, parti prima dalla guida principale.
Crea un sito di prenotazione con l'IA
Apri la guida principale
MAIN GUIDE
https://profitstudio.app/video/build-booking-website-ai
Configurare Resend per le e-mail di prenotazione
Crea e configura il tuo account Resend
Apri Resend
https://resend.com/
Crea un account Resend Genera una chiave API di Resend Copia e salva la chiave API in modo sicuro
IMPORTANTE
Mantieni privata la chiave API di Resend. Non aggiungerla mai al codice frontend e non condividerla pubblicamente.
Aggiungi e verifica il tuo dominio di invio
Aggiungi il dominio del tuo sito di prenotazione Seleziona la regione più vicina Copia i record DNS da Resend Aggiungi i record presso il tuo provider di dominio Torna su Resend e conferma che il dominio è verificato
La verifica DNS può richiedere qualche minuto o più, a seconda del tuo provider di dominio.
Creare la funzione e-mail di prenotazione
Crea la Edge Function per le e-mail di prenotazione
Apri Supabase
https://supabase.com/?utm_source=partner&utm_medium=social&utm_campaign=supasquad&dub_id=faVfKdcLWvKCbYNp
Apri il tuo progetto Supabase Apri Edge Functions Crea una nuova funzione con l'editor del browser Assegna alla funzione il nome `send-booking-email` Rimuovi il codice iniziale predefinito
Personalizza e aggiungi il codice della funzione
Inserisci l'e-mail del proprietario Inserisci il dominio Resend verificato Inserisci il nome dell'attività mittente Personalizza i modelli e-mail se necessario Copia e incolla il codice della funzione generato
Funzione e-mail di prenotazione
import { serve } from "https://deno.land/std/http/server.ts"; serve(async (req) => { try { const body = await req.json(); const record = body.record || {}; const resendKey = Deno.env.get("RESEND_API_KEY"); const supabaseUrl = Deno.env.get("SUPABASE_URL"); const supabaseServiceRoleKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY"); if (!resendKey) { return new Response( JSON.stringify({ error: "Missing RESEND_API_KEY secret" }), { status: 500, headers: { "Content-Type": "application/json" }, } ); } const ownerEmail = "YOUR_OWNER_EMAIL"; const customerEmail = record.email || ""; const customerName = record.full_name || record.name || "Customer"; const phone = record.phone || ""; const appointmentDate = record.appointment_date || record.date || ""; const startTime = record.start_time || record.time || ""; const endTime = record.end_time || ""; const notes = record.notes || ""; const status = record.status || "New"; let serviceName = record.service_name || record.service || record.service_title || ""; // If the appointment only has service_id, fetch the service name from the services table if (!serviceName && record.service_id && supabaseUrl && supabaseServiceRoleKey) { try { const serviceId = encodeURIComponent(record.service_id); const serviceResponse = await fetch( `${supabaseUrl}/rest/v1/services?id=eq.${serviceId}&select=name`, { method: "GET", headers: { apikey: supabaseServiceRoleKey, Authorization: `Bearer ${supabaseServiceRoleKey}`, "Content-Type": "application/json", }, } ); const serviceData = await serviceResponse.json(); if (Array.isArray(serviceData) && serviceData.length > 0) { serviceName = serviceData[0].name || ""; } } catch (_serviceError) { serviceName = ""; } } if (!serviceName) { serviceName = "Appointment"; } // 1) Email to business owner const ownerResponse = await fetch("https://api.resend.com/emails", { method: "POST", headers: { Authorization: `Bearer ${resendKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "Bookings <bookings@YOUR_DOMAIN_NAME>", to: [ownerEmail], subject: "OWNER_NOTIFICATION_SUBJECT", html: ` <h2>OWNER_NOTIFICATION_HEADING</h2> <p>OWNER_NOTIFICATION_INTRO</p> <p><b>Customer Name:</b> ${customerName}</p> <p><b>Email:</b> ${customerEmail}</p> <p><b>Phone:</b> ${phone}</p> <p><b>Service:</b> ${serviceName}</p> <p><b>Date:</b> ${appointmentDate}</p> <p><b>Start Time:</b> ${startTime}</p> <p><b>End Time:</b> ${endTime}</p> <p><b>Notes:</b> ${notes}</p> <p><b>Status:</b> ${status}</p> `, }), }); const ownerData = await ownerResponse.json(); // 2) Email to customer let customerData = null; if (customerEmail) { const customerResponse = await fetch("https://api.resend.com/emails", { method: "POST", headers: { Authorization: `Bearer ${resendKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "YOUR_BUSINESS_NAME <bookings@YOUR_DOMAIN_NAME>", to: [customerEmail], subject: "CUSTOMER_CONFIRMATION_SUBJECT", html: ` <h2>CUSTOMER_CONFIRMATION_HEADING</h2> <p>Hi ${customerName},</p> <p>CUSTOMER_CONFIRMATION_INTRO</p> <p><b>Service:</b> ${serviceName}</p> <p><b>Date:</b> ${appointmentDate}</p> <p><b>Start Time:</b> ${startTime}</p> <p><b>End Time:</b> ${endTime}</p> <p>If you need to make any changes, please contact us before your appointment.</p> <p>CUSTOMER_CONFIRMATION_CLOSING</p> `, }), }); customerData = await customerResponse.json(); } return new Response( JSON.stringify({ success: true, ownerEmailSent: ownerData, customerEmailSent: customerData, }), { headers: { "Content-Type": "application/json" }, } ); } catch (error) { return new Response( JSON.stringify({ success: false, error: String(error), }), { status: 500, headers: { "Content-Type": "application/json" }, } ); } });
E-mail del titolare
owner@example.com
Dominio verificato in Resend
yourdomain.com
Nome del business mittente
Clinica Dentistica Bright
Oggetto dell'e-mail al titolare
Intestazione dell'e-mail al titolare
Testo di introduzione dell'e-mail al titolare
Oggetto dell'e-mail al cliente
Intestazione dell'e-mail al cliente
Testo di introduzione dell'e-mail al cliente
Testo di chiusura dell'e-mail al cliente
Distribuisci e configura la funzione
Distribuisci la funzione Apri le impostazioni della funzione Disattiva `Verify JWT With Legacy Secret` Salva le modifiche Copia e conserva l'URL dell'endpoint della funzione per configurare il webhook
IMPORTANTE
Disattiva “Verify JWT With Legacy Secret” in modo che il Database Webhook possa richiamare la funzione.
Aggiungere la API key di Resend a Supabase
Aggiungi la chiave API di Resend come secret su Supabase
Apri Edge Function Secrets Crea un nuovo secret Imposta il nome su `RESEND_API_KEY` Incolla la chiave API di Resend Salva il secret
IMPORTANTE
Usa esattamente il nome del secret `RESEND_API_KEY`. Qualsiasi errore di battitura impedirà alla funzione di accedere a Resend.
Collegare le e-mail alle nuove prenotazioni
Crea il webhook per le e-mail di prenotazione
Attiva la funzione e-mail di prenotazione ogni volta che viene aggiunto un nuovo appuntamento.
Integrations Database Webhooks
Apri Database Webhooks Abilita Database Webhooks Crea un nuovo webhook Chiamalo `send-booking-email-webhook` Seleziona la tabella `public.appointments` Scegli `Insert` come evento Mantieni `HTTP Request` come tipo Usa `POST` come metodo della richiesta Incolla l'URL dell'endpoint della Edge Function Crea il webhook
Testare il sistema di e-mail di prenotazione
Testa l'intero flusso di e-mail di prenotazione
Testa l'intero flusso di prenotazione e conferma che entrambe le e-mail vengano recapitate correttamente.
Apri il sito di prenotazione online Invia un appuntamento di prova Conferma che la prenotazione sia salvata su Supabase Controlla l'e-mail di conferma al cliente Controlla l'e-mail di notifica al proprietario Verifica che i dettagli della prenotazione siano corretti in entrambe le e-mail Conferma che la prenotazione compaia nella dashboard di amministrazione