Füge E-Mail-Benachrichtigungen zu deiner KI-Buchungs-Website hinzu

Sende Buchungs-Bestätigungs-E-Mails und Benachrichtigungen an den Inhaber mit Supabase, Resend und Edge Functions.

Roadmap & Ressourcen

Neu hier? Starte zuerst hier

Diese Anleitung erweitert das KI-Buchungs-Website-Projekt um automatische E-Mail-Benachrichtigungen. Wenn du die Buchungs-Website noch nicht gebaut hast, beginne zuerst mit der Hauptanleitung.

Baue eine Buchungs-Website mit KI

Öffne die Hauptanleitung

MAIN GUIDE

https://profitstudio.app/video/build-booking-website-ai

Resend für Buchungs-E-Mails einrichten

Resend-Konto erstellen und konfigurieren

Öffne Resend

https://resend.com/

Resend-Konto erstellen Resend-API-Key generieren API-Key kopieren und sicher speichern

WICHTIG

Halte den Resend-API-Key geheim. Füge ihn niemals in Frontend-Code ein und teile ihn nicht öffentlich.

Sendedomain hinzufügen und verifizieren

Domain deiner Buchungswebsite hinzufügen Nächstgelegene Region auswählen DNS-Einträge aus Resend kopieren Einträge beim Domain-Anbieter hinzufügen Zu Resend zurückkehren und Verifizierung der Domain bestätigen

Die DNS-Verifizierung kann je nach Domain-Anbieter einige Minuten oder länger dauern.

Die Buchungs-E-Mail-Funktion erstellen

Edge Function für Buchungs-E-Mails erstellen

Öffne Supabase

https://supabase.com/?utm_source=partner&utm_medium=social&utm_campaign=supasquad&dub_id=faVfKdcLWvKCbYNp

Öffne dein Supabase-Projekt Öffne Edge Functions Erstelle eine neue Funktion mit dem Browser-Editor Benenne die Funktion `send-booking-email` Entferne den voreingestellten Startcode

Funktionscode anpassen und hinzufügen

E-Mail-Adresse des Inhabers eingeben Verifizierte Resend-Domain eingeben Name des sendenden Unternehmens eingeben E-Mail-Vorlagen bei Bedarf anpassen Generierten Funktionscode kopieren und einfügen

Buchungs-E-Mail-Funktion

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" }, } ); } });

Inhaber-E-Mail

owner@example.com

Verifizierte Resend-Domain

yourdomain.com

Geschäftsname des Absenders

Zahnklinik Bright

Betreff der Inhaber-E-Mail

Überschrift der Inhaber-E-Mail

Einleitungstext der Inhaber-E-Mail

Betreff der Kunden-E-Mail

Überschrift der Kunden-E-Mail

Einleitungstext der Kunden-E-Mail

Schlusstext der Kunden-E-Mail

Funktion deployen und konfigurieren

Deploye die Funktion Öffne die Funktionseinstellungen Deaktiviere `Verify JWT With Legacy Secret` Speichere die Änderungen Kopiere und sichere die Endpoint-URL der Funktion für die Webhook-Einrichtung

WICHTIG

Deaktiviere „Verify JWT With Legacy Secret“, damit der Database Webhook die Funktion aufrufen kann.

Den Resend-API-Key zu Supabase hinzufügen

Resend-API-Key als Supabase-Secret hinzufügen

Öffne Edge Function Secrets Erstelle ein neues Secret Setze den Namen auf `RESEND_API_KEY` Füge den Resend-API-Key ein Speichere das Secret

WICHTIG

Verwende exakt den Secret-Namen `RESEND_API_KEY`. Jeder Tippfehler verhindert, dass die Funktion auf Resend zugreifen kann.

E-Mails mit neuen Buchungen verbinden

Webhook für Buchungs-E-Mails erstellen

Löse die Buchungs-E-Mail-Funktion aus, sobald ein neuer Termin hinzugefügt wird.

Integrations Database Webhooks

Öffne Database Webhooks Aktiviere Database Webhooks Erstelle einen neuen Webhook Benenne ihn `send-booking-email-webhook` Wähle die Tabelle `public.appointments` Wähle `Insert` als Ereignis Behalte `HTTP Request` als Typ bei Verwende `POST` als Request-Methode Füge die Endpoint-URL der Edge Function ein Erstelle den Webhook

Das Buchungs-E-Mail-System testen

Kompletten Buchungs-E-Mail-Ablauf testen

Teste den kompletten Buchungsablauf und prüfe, ob beide E-Mails korrekt zugestellt werden.

Live-Buchungswebsite öffnen Testtermin absenden Bestätigen, dass die Buchung in Supabase gespeichert wurde Bestätigungs-E-Mail an den Kunden prüfen Benachrichtigungs-E-Mail an den Inhaber prüfen Prüfen, ob die Buchungsdaten in beiden E-Mails korrekt sind Bestätigen, dass die Buchung im Admin-Dashboard erscheint