מערכת תיאום פגישות עם קלוד קוד (Claude Code): יומן, זום ווואטסאפ
בנינו מערכת תיאום פגישות מלאה בעזרת Claude Code: לקוח קונה שעות, בוחר מועד מהיומן האמיתי, מקבל זום ומייל — והכל אוטומטי. כך תעשו את זה בעצמכם, שלב אחרי שלב.
הידעת?
את כל המערכת שמתוארת במדריך — תשלומים, יומן, זום, וואטסאפ, מיילים ותזכורות — בנינו עם Claude Code ביום עבודה אחד, בלי אף שורת קוד ידנית.
רצינו שלקוחות יוכלו לקנות שיעור פרטי, לבחור מועד פנוי מהיומן האמיתי שלנו, ולקבל אוטומטית פגישת Zoom, מייל אישור והתראת וואטסאפ — בלי Calendly ובלי מזכירה. בנינו את זה עם Claude Code (קלוד קוד) ביום עבודה אחד, וזה רץ היום בפרודקשן. במדריך הזה נפרק בדיוק איך — כולל כל החיבורים: Google Calendar, Zoom, green-api (וואטסאפ), Resend (מיילים) והמלכודות שנפלנו בהן, כדי שאתם לא תיפלו.
מה המערכת עושה (הזרימה המלאה)
- הלקוח קונה שעות בעמוד מכירה (אצלנו: שעה, שעתיים או יותר) — סליקה + חשבונית אוטומטית.
- הוא מקבל לינק תיאום אישי במייל (ובוואטסאפ) — בלי הרשמה ובלי סיסמה.
- בלינק מחכה בורר משבצות שמציג רק זמנים שאתם באמת פנויים בהם — מסונכרן ליומן גוגל בזמן אמת.
- ברגע הבחירה: נוצרת פגישת Zoom ייחודית, נקבע אירוע ביומן, הלקוח מקבל מייל עם הקישור (ורואה אותו גם על המסך), ואתם מקבלים וואטסאפ + מייל.
- יום לפני הפגישה — תזכורת אוטומטית ללקוח עם קישור הזום.
הכל בנוי על Next.js + Supabase Storage (בלי טבלאות, בלי מיגרציות — קובצי JSON בבאקט), בדיוק כמו שעשינו במערכת הניוזלטר שלנו.
הארכיטקטורה: "קרדיט" במקום חשבון משתמש
ההחלטה הכי חשובה במערכת: אין חשבונות משתמשים. כל רכישה יוצרת "קרדיט" — קובץ JSON עם טוקן ייחודי:
{
"token": "9625677b-b238-...",
"customer": { "name": "...", "email": "...", "phone": "..." },
"hoursTotal": 2,
"hoursUsed": 0,
"amountPaidIls": 826
}
הטוקן עצמו הוא לינק התיאום: /book/<token>. הלקוח יכול לפצל את השעות לכמה מפגשים — כל תיאום מוריד מהיתרה. פשוט, בטוח (הטוקן אקראי וארוך), ובלי ניהול סיסמאות. חשוב: עמוד התיאום מסומן noindex כדי שגוגל לא יאנדקס לינקים אישיים.
חיבור 1: יומן גוגל — עם Service Account (לא OAuth!)
זו המלכודת הראשונה שנפלנו בה: ניסינו OAuth רגיל וגילינו ש-client מסוג "Desktop" לא תומך ב-redirect לאתר. הפתרון הנכון ליומן של אדם אחד: Service Account.
- ב-Google Cloud Console יוצרים Service Account ומורידים מפתח JSON.
- משתפים את היומן עם כתובת ה-Service Account (בהגדרות היומן → "שיתוף עם אנשים ספציפיים" → הרשאת "לבצע שינויים").
- את ה-JSON שמים במשתנה סביבה, וחותמים JWT (אלגוריתם RS256) כדי לקבל access token — בלי שום ספרייה חיצונית, עם
node:cryptoבלבד.
את הזמנים התפוסים מושכים מ-FreeBusy API — שאילתה אחת שמחזירה את כל הבלוקים התפוסים בטווח:
const busy = await fetch("https://www.googleapis.com/calendar/v3/freeBusy", {
method: "POST",
headers: { authorization: `Bearer ${token}` },
body: JSON.stringify({ timeMin, timeMax, items: [{ id: CALENDAR_ID }] }),
});
⚠️ מלכודת: Service Account לא יכול להזמין משתתפים חיצוניים לאירוע (בלי הרשאות ארגוניות מיוחדות). הפתרון: יוצרים את האירוע בלי משתתפים, שמים את קישור הזום בתיאור האירוע, ושולחים ללקוח מייל נפרד.
חיבור 2: חישוב המשבצות הפנויות
הלב של המערכת — פונקציה שמקבלת את הזמנים התפוסים + חוקי הזמינות שלכם, ומחזירה משבצות פנויות. חוקי הזמינות נשמרים כקונפיג שאפשר לערוך מפאנל הניהול:
{
days: [0, 1, 2, 3, 4], // א׳-ה׳ (0 = ראשון)
startHour: 11, endHour: 16, // הפגישה חייבת להסתיים עד 16:00
bufferMinutes: 15, // ריווח סביב פגישות קיימות
minNoticeHours: 24, // אי אפשר לקבוע לעוד שעה
maxDaysAhead: 30,
timezone: "Asia/Jerusalem"
}
טיפ קריטי לחישוב שעון ישראל בלי ספריות: ממירים "שעת קיר" ל-UTC דרך Intl.DateTimeFormat (טריק ה-offset). ועוד אחד: בזמן התיאום עצמו בודקים שוב מול היומן שהמשבצת עדיין פנויה — אחרת שני לקוחות יתפסו את אותה שעה (מחזירים "המשבצת נתפסה — בחרו מועד אחר").
חיבור 3: Zoom — פגישה ייחודית לכל תיאום
לא קישור זום קבוע — פגישה חדשה לכל תיאום, עם חדר המתנה. עושים את זה עם אפליקציית Server-to-Server OAuth (בלי מסכי אישור):
- ב-Zoom Marketplace יוצרים אפליקציית Server-to-Server OAuth ומפעילים אותה.
- מוסיפים לה את ההרשאה
meeting:write:meeting:admin. - מקבלים token עם
grant_type=account_credentialsו-Basic Auth של ה-Client ID+Secret. - יוצרים פגישה:
POST /v2/users/me/meetingsעם נושא, מועד, משך ואזור זמן — ומקבליםjoin_urlייחודי.
⚠️ עיקרון עמידות: אם Zoom לא זמין רגעית — התיאום לא נכשל. בנינו שרשרת נפילה: פגישה ייחודית → קישור זום קבוע מהסביבה → בלי קישור (משלימים ידנית). תשלום ותיאום לעולם לא נופלים בגלל שירות צד-שלישי.
חיבור 4: וואטסאפ עם green-api
green-api מחבר מספר וואטסאפ רגיל ל-API בשתי שורות. סורקים QR פעם אחת, ומקבלים Instance ID + Token. שליחה:
await fetch(`https://api.green-api.com/waInstance${ID}/sendMessage/${TOKEN}`, {
method: "POST",
body: JSON.stringify({ chatId: "9725XXXXXXXX@c.us", message: "🎓 רכישה חדשה!" }),
});
אצלנו וואטסאפ משמש לשניים: התראות לבעל העסק (כל רכישה ותיאום מגיעים לנייד תוך שניות) והודעות ללקוח — למשל להקפיץ את לינק התיאום למי שקנה ולא קבע.
חיבור 5: מיילים עם Resend + תזכורות
כל המיילים (לינק תיאום, אישור מועד עם קישור זום, תזכורת יום-לפני) נשלחים עם Resend — HTML פשוט עם dir="rtl". שני לקחים חשובים מהפרודקשן:
- התראות לעולם לא מפילות את הזרימה. כל שליחת מייל עטופה ב-try/catch. אם המייל נכשל — הרכישה והתיאום עדיין מצליחים.
- אל תסמכו על ערוץ אחד. כשמכסת המיילים החודשית שלנו נגמרה, המיילים נכשלו בשקט — ולקוחה אמיתית לא קיבלה את לינק התיאום. מה שהציל: קישור הזום מוצג גם על המסך אחרי התיאום, נשמר גם ביומן, וההתראות לבעל העסק רצות גם בוואטסאפ. יתירות = עמידות.
התזכורות רצות כ-cron יומי (מוגדר ב-vercel.json): סורק את התיאומים של מחר שעוד לא קיבלו תזכורת, שולח מייל עם קישור הזום, ומסמן reminded.
קיצור דרך: ערכת ההקמה המוכנה
רוצים לדלג על גילוי כל המלכודות מאפס? ארזנו את כל המערכת לערכת Skill מוכנה ל-Claude Code — מעתיקים ל-.claude/skills/, מבקשים מקלוד לבנות, והוא כבר יודע את כל הארכיטקטורה, החיבורים והמלכודות. כוללת גם את קבצי הקוד האמיתיים (חישוב משבצות, יומן, זום, וואטסאפ), מדריך התקנה ו-.env.example. הפרטים בהמשך העמוד ⬇
איך בונים את כל זה עם Claude Code בפועל
זה החלק שהכי חשוב להבין: לא כתבנו את הקוד — כיוונו את קלוד קוד. ככה זה נראה:
- מתחילים מתכנון בשפה חופשית: "אני רוצה שיוכלו לקנות שעות שיעור, לבחור מועד מהיומן שלי, לקבל זום ומייל, ושאני אקבל וואטסאפ". קלוד שואל שאלות הבהרה (כמה לחלק? איזה שעות?) ובונה תוכנית.
- נותנים לו את המפתחות בבטחה: משתני סביבה, לא בקוד. קלוד מגדיר אותם ב-Vercel דרך ה-CLI.
- הוא בונה חיבור-חיבור ומאמת כל אחד בנפרד: קריאת יומן אמיתית, יצירת פגישת זום אמיתית, שליחת וואטסאפ אמיתית — לפני שמחברים הכל.
- בדיקת קצה-לקצה אמיתית: רכישת בדיקה בכרטיס, תיאום אמיתי, ווידוא שכל ההתראות הגיעו.
- ומתקנים את מה שנשבר — כולל באגים אמיתיים שנתפסו אצלנו: בדיקת הרשאות אסינכרונית בלי await (חור אבטחה!), והרשאות Zoom מסוג לא נכון.
רוצים ללמוד לעבוד ככה? זה בדיוק מה שאנחנו מלמדים בסדנת Claude Code לארגונים ובשיעורים פרטיים — בונים על המשימות האמיתיות שלכם.
טעויות נפוצות (נפלנו — שתחסכו)
- OAuth במקום Service Account ליומן של אדם אחד — סיבוך מיותר שגם נשבר.
- לשכוח לשתף את היומן עם כתובת ה-Service Account — הכל מוגדר נכון ושום דבר לא עובד.
- לסמוך על מייל בלבד למסירת קישור הזום — מכסה שנגמרת שוברת את המסירה בשקט.
- לא לאמת מחדש את המשבצת בזמן התיאום — race condition שמכפיל תיאומים.
- await חסר בבדיקת התחברות —
verifySessionאסינכרוני; בלעדיו כל בקשה "מחוברת".
שורה תחתונה
מערכת תיאום פגישות מלאה — סליקה, יומן מסונכרן, זום ייחודי, וואטסאפ, מיילים ותזכורות — היא כבר לא פרויקט של חודשים או מנוי חודשי לכל החיים. עם Claude Code והמדריך הזה, זה יום עבודה. אפשר לראות את התוצאה חיה אצלנו: תיאום שיעור פרטי.
רוצים שנבנה לכם כזו, או שנלמד את הצוות שלכם לבנות בעצמו? דברו איתנו או קפצו לסדנת קלוד קוד.