أضف إشعارات البريد الإلكتروني إلى موقع الحجوزات الذكي
أرسل رسائل تأكيد الحجز وتنبيهات المالك باستخدام Supabase وResend وEdge Functions.
خارطة الطريق والموارد
جديد هنا؟ ابدأ من هنا أولًا
يُرقّي هذا الدليل مشروع موقع الحجوزات الذكي بإشعارات بريد إلكتروني تلقائية. إذا لم تكن قد بنيت موقع الحجوزات بعد، فابدأ بالدليل الرئيسي أولًا.
ابنِ موقع حجوزات بالذكاء الاصطناعي
افتح الدليل الرئيسي
MAIN GUIDE
https://profitstudio.app/video/build-booking-website-ai
أعد Resend لرسائل بريد الحجوزات
أنشئ حساب Resend واضبط إعداداته
افتح Resend
https://resend.com/
أنشئ حساب Resend ولّد مفتاح Resend API انسخ المفتاح واحفظه في مكان آمن
مهم
احتفظ بمفتاح Resend API سريًا. لا تضعه أبدًا في كود الواجهة الأمامية ولا تشاركه علنًا.
أضف نطاق الإرسال وتحقق منه
أضف نطاق موقع الحجز الخاص بك اختر أقرب منطقة انسخ سجلات DNS من Resend أضف السجلات لدى مزود النطاق ارجع إلى Resend وتأكد من التحقق من النطاق
قد يستغرق التحقق من DNS بضع دقائق أو أكثر حسب مزود النطاق الذي تستخدمه.
أنشئ دالة بريد الحجوزات
أنشئ Edge Function الخاصة ببريد الحجز
افتح Supabase
https://supabase.com/?utm_source=partner&utm_medium=social&utm_campaign=supasquad&dub_id=faVfKdcLWvKCbYNp
افتح مشروع Supabase الخاص بك افتح Edge Functions أنشئ دالة جديدة باستخدام محرر المتصفح سمِّ الدالة `send-booking-email` احذف الكود الافتراضي المبدئي
خصّص كود الدالة وأضفه
أدخل البريد الإلكتروني للمالك أدخل نطاق Resend الذي تم التحقق منه أدخل اسم النشاط التجاري المرسِل خصّص قوالب البريد الإلكتروني عند الحاجة انسخ كود الدالة الناتج والصقه
دالة بريد الحجوزات
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" }, } ); } });
بريد المالك
owner@example.com
نطاق Resend موثّق
yourdomain.com
اسم العمل المرسل
عيادة برايت لطب الأسنان
موضوع بريد المالك
عنوان بريد المالك
نص مقدمة بريد المالك
موضوع بريد الزبون
عنوان بريد الزبون
نص مقدمة بريد الزبون
نص خاتمة بريد الزبون
انشر الدالة واضبط إعداداتها
انشر الدالة افتح إعدادات الدالة عطّل `Verify JWT With Legacy Secret` احفظ التغييرات انسخ رابط endpoint الخاص بالدالة واحفظه لإعداد Webhook
مهم
عطّل خيار “Verify JWT With Legacy Secret” حتى يتمكن Database Webhook من استدعاء الدالة.
أضف مفتاح Resend API إلى Supabase
أضف مفتاح Resend API كسر في Supabase
افتح Edge Function Secrets أنشئ سرًا جديدًا اضبط الاسم على `RESEND_API_KEY` الصق مفتاح Resend API احفظ السر
مهم
استخدم اسم السر بالضبط `RESEND_API_KEY`. أي خطأ إملائي سيمنع الدالة من الوصول إلى Resend.
اربط البريد الإلكتروني بالحجوزات الجديدة
أنشئ Webhook الخاص ببريد الحجز
شغّل دالة بريد الحجز في كل مرة يُضاف فيها موعد جديد.
Integrations Database Webhooks
افتح Database Webhooks فعّل Database Webhooks أنشئ webhook جديدًا سمِّه `send-booking-email-webhook` اختر جدول `public.appointments` اختر `Insert` كحدث أبقِ النوع على `HTTP Request` استخدم `POST` كطريقة للطلب الصق رابط endpoint الخاص بـ Edge Function أنشئ الـ webhook
اختبر نظام بريد الحجوزات
اختبر مسار بريد الحجز بالكامل
اختبر مسار الحجز بالكامل وتأكد من وصول كلا البريدين بشكل صحيح.
افتح موقع الحجز المباشر أرسل موعدًا تجريبيًا تأكد من حفظ الحجز في Supabase تحقق من بريد التأكيد المرسل إلى العميل تحقق من بريد الإشعار المرسل إلى المالك تأكد من صحة تفاصيل الحجز في كلا البريدين تأكد من ظهور الحجز في لوحة تحكم المشرف