[warm]
צהריים טובים לכולם וברוכים הבאים לשיעור חמישי-שלוש על וֶוב-הוּקס. אם עד היום דיברנו בעיקר על איך אנחנו פונים למערכות אחרות כדי לבקש מידע, היום אנחנו הופכים את המשוואה. נלמד איך לגרום למערכות אחרות לפנות אלינו בזמן אמת, בדיוק כשקורה משהו מעניין. היכולת הזו, לקבל דאטה ב-push, היא אבן יסוד בארכיטקטורה מודרנית מבוססת אירועים, והיא קריטית במיוחד בעולם הבינה המלאכותית. כשאנחנו בונים סוכני AI או תהליכים אוטומטיים, אנחנו לא רוצים לבזבז משאבים על בדיקות חוזרות ונשנות. אנחנו רוצים שהמערכת שלנו תתעורר לפעולה בדיוק ברגע הנכון. לפני שנצלול, כדאי לחשוב אם נתקלתם במושג ווב-הוק בעבר, אולי בהקשר של סטרייפ, גיטהאב, או אפילו מערכות כמו Make ו-Zapier.

[מעבר שקף]

[calm]
בשיעור הקודם, צללנו לעומק של עבודה עם ממשקי תכנות של מודלי שפה גדולים. למדנו איך לבצע קריאות לקלוד, OpenAI וג'מיני. כל הפעולות שעשינו התבססו על עיקרון אחד: אנחנו יזמנו את התקשורת. האפליקציה שלנו הייתה הלקוח שפנה לשרת ושאל שאלות. המודל הזה נקרא 'Pull' או 'Polling', כלומר, אנחנו מושכים מידע מהשרת. זה מודל מצוין כשאנחנו צריכים תשובה לפי דרישה. אבל מה קורה כשהיוזמה צריכה להגיע מהצד השני? למשל, אם שלחנו משימה ארוכה למודל AI, כמו סיכום של מאתיים מסמכים, אנחנו לא רוצים לשאול כל שנייה 'סיימת כבר?'. זה לא יעיל, זה בזבזני וזה פשוט לא עובד טוב בסקייל גבוה. שאלה שכדאי לחשוב עליה היא, איפה עוד בחיים המקצועיים שלנו אנחנו נתקלים במצב שבו 'לשאול כל הזמן' זה פתרון גרוע.

[מעבר שקף]

[calm]
בואו נדבר על הבעיה עם Polling דרך אנלוגיה שכולנו מכירים. תחשבו שהזמנתם חבילה חשובה עם שליח. גישת ה-Polling אומרת שכל חמש דקות אתם מתקשרים למוקד ושואלים: 'מה הסטטוס?'. רוב השיחות שלכם יקבלו את אותה תשובה: 'עדיין אין שינוי'. אתם מבזבזים זמן ואנרגיה. מחקרים עדכניים של חברות כמו Zapier, עם תחזיות לשנת אלפיים עשרים וחמש, מראים שכקרוב לתשעים ותשעה אחוזים מבקשות ה-Polling הן 'ריקות' – הן לא מוצאות שום עדכון. זה בזבוז משאבים אדיר. עכשיו, תחשבו על גישת ה-Webhook. בגישה הזו, אתם נותנים לחברת השליחויות את מספר הטלפון שלכם ואומרים: 'תשלחו לי הודעה אוטומטית ברגע שהשליח קרוב'. אתם יכולים להמשיך ביום שלכם, והמערכת תיזום את התקשורת איתכם רק כשיש מידע רלוונטי. זה בדיוק מה ש-Webhook עושה. הוא הופך את התקשורת מ-'Pull' ל-'Push'.

[מעבר שקף]

[calm, confident]
אז בואו נגדיר את זה רשמית. ווב-הוק, שלפעמים נקרא גם 'Reverse API' או 'HTTP Push API', הוא מנגנון שמאפשר לאפליקציה אחת לשלוח מידע לאפליקציה אחרת בזמן אמת, ברגע שאירוע מסוים מתרחש. במקום שהאפליקציה שלנו תפנה כל הזמן לאפליקציה אחרת ותשאל 'קרה משהו חדש?', אנחנו רושמים באפליקציה השנייה 'כתובת URL להודעות'. הכתובת הזו, שנקראת 'Webhook Endpoint', שייכת לאפליקציה שלנו. ברגע שאירוע מוגדר קורה, האפליקציה השנייה תיזום בעצמה בקשת HTTP POST לאותו URL שסיפקנו לה, ותשלח יחד איתה את כל המידע הרלוונטי על האירוע. האפליקציה שלנו פשוט 'מאזינה' לאותו Endpoint, וכשמגיעה בקשה – היא יודעת שהאירוע התרחש ויכולה לפעול בהתאם. חשוב להבין שבהתבסס על ההגדרה הזו, הצד השולח הוא זה שאחראי על מבנה המידע שנשלח.

[מעבר שקף]

[calm]
בואו נפרק בקשת ווב-הוק טיפוסית לגורמים. כמעט תמיד, מדובר בבקשת HTTP POST. למה POST? כי אנחנו שולחים מידע, יוצרים משאב חדש. הבקשה הזו מורכבת משלושה חלקים עיקריים. הראשון הוא שורת הבקשה, שמציינת את המתודה POST ואת הנתיב הספציפי שאנחנו נגדיר. השני הוא ה-Headers, תוויות המידע על הבקשה. הן מכילות מטא-דאטה חשוב, כמו סוג התוכן, והכי חשוב בהקשר שלנו, Header שקשור לאבטחה, שמאפשר לנו לוודא שהבקשה הגיעה מהמקור הנכון. החלק השלישי והאחרון הוא ה-Payload, כלומר גוף הבקשה. זה 'הבשר' של ה-Webhook, והוא מכיל את כל המידע על האירוע שהתרחש, לרוב בפורמט JSON. הסיבה שפורמט JSON כל כך נפוץ היא שהוא קריא לבני אדם, קל למכונות לפענח, ונתמך בכל שפות התכנות.

[מעבר שקף]

[calm]
תיאוריה זה נחמד, אבל אנחנו פה כדי לכתוב קוד. בואו נקים שרת מינימלי שמסוגל לקבל בקשות ווב-הוק. נשתמש ב-Flask, ספריית פייתון קלילה ומצוינת למשימה. נצטרך להתקין את Flask, לייבא את הספרייה, ליצור אובייקט app, ולהגדיר 'route' – זה ה-URL שהשרת שלנו יאזין לו, למשל נקודה-סלאש-ווב-הוק. נגדיר שה-route הזה מקבל רק בקשות מסוג POST, ונכתוב פונקציה שתופעל כשתגיע בקשה כזו. בתוך הפונקציה, ניגש למידע שהגיע, נדפיס אותו, ונחזיר תשובת מאתיים OK כדי לאותת לשולח שקיבלנו את ההודעה בהצלחה. החזרת סטטוס מאתיים היא קריטית. אם לא נחזיר תשובה מוצלחת, שירותים חיצוניים יניחו שההודעה לא הגיעה וינסו לשלוח אותה שוב ושוב.

[מעבר שקף]

[clear]
בואו נכתוב את הקוד יחד. אני אדביק כאן קוד בסיסי, ונעבור עליו שורה-שורה. ראשית, ניצור אובייקט אפליקציה של Flask. לאחר מכן, נגדיר את נקודת הקצה שלנו בנתיב 'webhook' שתקבל בקשות POST. בתוך הפונקציה המטפלת, נבדוק תחילה אם הבקשה מכילה JSON. אם כן, נשתמש בפונקציה request.get_json כדי לפענח את ה-Payload למילון פייתוני שאיתו נוכל לעבוד. כרגע, כל מה שאנחנו עושים זה להדפיס אותו לקונסול. בעולם האמיתי, כאן תיכנס הלוגיקה העסקית שלכם – עדכון CRM, שליחת אימייל, הפעלת מודל AI וכולי. לבסוף, אנחנו מחזירים תשובת JSON פשוטה עם סטטוס קוד מאתיים. אם היינו רוצים להתמודד עם ווב-הוק ספציפי מגיטהאב, היינו פשוט בודקים את הערכים בתוך ה-payload כדי להבין את סוג האירוע.

[מעבר שקף]

[calm]
אז יש לנו שרת קטן שרץ על המחשב שלנו, מאזין בכתובת לוקאלית. אבל יש בעיה גדולה: הכתובת הזו 'חיה' רק על המחשב שלנו. שירות חיצוני כמו סטרייפ, שרץ על שרתים בענן, לא יכול לשלוח בקשה ל-localhost שלי. כדי לפתור את זה בזמן פיתוח, אנחנו צריכים 'לחשוף' את השרת המקומי שלנו לאינטרנט הציבורי. אנחנו עושים את זה באמצעות כלי מנהור כמו ngrok. מה ש-ngrok עושה זה ליצור כתובת URL ציבורית ומאובטחת, שכל תעבורה שתגיע אליה תועבר ישירות לפורט הספציפי שאנחנו מריצים לוקאלית. חשוב להדגיש שגישת המנהור הזו לא מתאימה לסביבת Production. זו גישה לפיתוח ובדיקות בלבד. ב-Production, האפליקציה תרוץ על שרת אמיתי עם כתובת IP ציבורית קבועה.

[מעבר שקף]

[calm]
אוקיי, בואו נחבר את כל החלקים. יש לנו את שרת ה-Flask שלנו רץ על port חמשת-אלפים ואחת. עכשיו, בטרמינל נפרד, אני אריץ את ngrok. הפקודה פשוטה: ngrok http 5001. שימו לב מה קיבלנו. ngrok נתן לנו כתובת ציבורית. עכשיו, כל בקשה שתישלח לכתובת הזו, תגיע ישירות לאפליקציית ה-Flask שלנו. כדי לבדוק את זה, נשתמש בכלי כמו Postman. אני אעתיק את הכתובת, אוסיף את הנתיב 'webhook', אגדיר את הבקשה כ-POST, ואוסיף גוף JSON פשוט. ועכשיו תראו... בטרמינל שבו רצה אפליקציית ה-Flask שלנו, הודפס ה-Payload ששלחנו! קיבלנו את הנתונים בהצלחה. החזרנו מאתיים, וגם בחלון של ngrok אנחנו יכולים לראות את הבקשה שנכנסה והתשובה שיצאה.

[מעבר שקף]

[calm, confident]
הקמנו נקודת קצה ציבורית. זה אומר שכל אחד שיודע את הכתובת יכול לשלוח לנו בקשת POST, וזה מסוכן. אנחנו חייבים דרך לוודא שהבקשה הגיעה מהמקור האמין ולא ממתחזה. השיטה הסטנדרטית לעשות זאת היא אימות חתימה. התהליך עובד כך: כשאנחנו מגדירים את ה-Webhook, המערכת החיצונית מספקת לנו 'מפתח סודי' שאנו שומרים אצלנו. בכל פעם שהיא שולחת ווב-הוק, היא יוצרת חתימת HMAC באמצעות המפתח הסודי ושמה אותה ב-Header של הבקשה. כשהבקשה מגיעה אלינו, אנחנו עושים בדיוק את אותו חישוב עם המפתח הסודי שלנו. לבסוף, אנחנו משווים את החתימה שיצרנו לחתימה שהגיעה ב-Header. אם הן זהות – הבקשה אותנטית. אם לא – אנחנו זורקים אותה. זה מנגנון קריטי. לעולם אל תעבדו עם ווב-הוקס בפרודקשן בלי אימות חתימה.

[מעבר שקף]

[calm]
תיאוריה וקוד זה נהדר, אבל איפה זה פוגש אותנו ביום-יום? ווב-הוקס הם הדבק שמחבר המון מערכות בעסקים ישראליים. למשל, במסחר אלקטרוני, חנות Shopify מקבלת תשלום דרך משולם. ברגע שהתשלום מאושר, שירות התשלומים שולח ווב-הוק לחנות כדי לעדכן את סטטוס ההזמנה ולהפעיל את תהליך המשלוח. בתחום השיווק, משתמש ממלא טופס צור קשר באתר, והמערכת שולחת ווב-הוק ישירות ל-CRM ויוצרת איש קשר חדש אוטומטית. בתקשורת עם לקוחות דרך וואטסאפ, כשלקוח שולח הודעה, ספק השירות שולח ווב-הוק לשרת שלכם עם תוכן ההודעה, שיכול לנתב אותה לצ'אטבוט. ובתהליכי AI ארוכים, במקום לבדוק כל רגע אם תמלול הסתיים, השירות פשוט שולח ווב-הוק לכתובת שהגדרתם כשהוא מסיים.

[מעבר שקף]

[calm]
עד עכשיו דיברנו בעיקר על קבלת ווב-הוקס. אבל המערכות שאנחנו בונים יכולות וצריכות גם לשלוח ווב-הוקס. זה נקרא Outgoing Webhook. למה שנרצה לעשות את זה? תחשבו על סוכן AI שבניתם. הוא סיים לבצע משימה מורכבת. איך המשתמש ידע שהיא מוכנה? במקום שהמשתמש ירענן את הדף, הסוכן שלכם יכול, כפעולה אחרונה, לשלוח בקשת POST ל-Webhook שהוגדר מראש. ה-Webhook הזה יכול להיות מחובר לערוץ סלאק כדי לשלוח הודעה, או לממשק המשתמש כדי להציג התראה. היכולת לשלוח ווב-הוקס הופכת את המערכת שלנו למקור אירועים עבור מערכות אחרות. כדי לשלוח ווב-הוק, כל מה שאנחנו צריכים לעשות בפייתון זה להשתמש בספרייה כמו 'requests' כדי לבצע בקשת POST.

[מעבר שקף]

[calm]
לא תמיד נצטרך לכתוב קוד בפייתון כדי לעבוד עם ווב-הוקס. פלטפורמות אוטומציה כמו Make.com ו-n8n בנויות סביב הרעיון הזה. בפלטפורמות האלה, אחד הטריגרים הנפוצים ביותר הוא 'Webhook'. כשאתם בוחרים בו, המערכת מייצרת עבורכם URL ייחודי. כל מה שאתם צריכים לעשות זה להדביק את ה-URL הזה במערכת השולחת. מרגע זה, כל פעם שהאירוע יקרה, ה-Webhook ישלח, והתרחיש שלכם בפלטפורמה יתחיל לרוץ. אתם יכולים לקחת את המידע מה-Payload ולבצע שרשרת של פעולות בלי לכתוב שורת קוד אחת. זה שימושי מאוד לפרוטוטייפינג מהיר, לאוטומציות פנימיות, ולאנשים בצוות שהם לא מפתחים. מובן שיש פה פשרה בין מהירות הפיתוח לבין גמישות ושליטה מלאה.

[מעבר שקף]

[clear]
בואו נסכם את מה שלמדנו היום. עברנו מפרדיגמת 'Pull' שבה אנחנו שואלים, לפרדיגמת 'Push' שבה המידע מגיע אלינו. ראשית, הבנו את ההבדל: Polling הוא בזבזני ולא יעיל, בעוד ווב-הוקס הם תגובתיים, חסכוניים ועובדים בזמן אמת. שנית, פירקנו את המבנה ולמדנו ש-Webhook הוא בקשת HTTP POST עם Headers ו-Payload בפורמט JSON. שלישית, בנינו בעצמנו נקודת קצה עם Flask וחשפנו אותה לעולם עם ngrok. רביעית, דיברנו על אבטחה והדגשנו את החשיבות הקריטית של אימות חתימה. ולבסוף, ראינו יישומים מהעולם האמיתי. היכולת לעבוד עם ווב-הוקס היא כלי סופר-עוצמתי בארגז הכלים שלכם כמהנדסי AI.

[מעבר שקף]

[warm]
היום ראינו שוב ושוב את המילה JSON. דיברנו על זה שזה הפורמט הסטנדרטי להעברת מידע ב-Payloads של ווב-הוקס ובתקשורת API באופן כללי. בשיעור הבא, חמישי-ארבע, אנחנו נצלול לעומק הפורמט הזה. נלמד איך לקרוא קבצי JSON, איך לייצר אותם, ואיך לבצע עליהם מניפולציות מורכבות בפייתון. זה אולי נשמע בסיסי, אבל שליטה טובה בעבודה עם JSON היא הכרחית לכל מי שעוסק באינטגרציות טכניות ובעבודה עם APIs, ובמיוחד כשאנחנו צריכים להכין מידע למודלי AI או לפענח את התשובות שלהם. ועכשיו, אני אשמח לענות על כל שאלה שיש לכם. תודה רבה על ההקשבה.