# קבלה ואימות של עדכוני Webhooks חתומים

מוסיפים כתובת HTTPS, בוחרים אירועי אנשי קשר וקמפיינים, שומרים סוד חתימה שמוצג פעם אחת בלבד ומטפלים באימות, בכפילויות, בניסיונות חוזרים ובהשבתת מסירה.

Canonical: https://docs.lead-knight.com/he/developers/webhooks/


## מה עושים עם Webhooks

Webhook שולח מלידנייט בקשת HTTPS מסוג POST לשרת שלכם כאשר איש קשר או מצב קמפיין משתנים, לפי האירועים שנבחרו. כך מעדכנים מערכת אחרת בלי לפנות שוב ושוב ל-API. זו התראה יוצאת, לא פקודה נכנסת, ולא צריך להכניס מפתח API לכתובת המקבלת.

השירות זמין כשה-API למפתחים מופעל. מנהלים אותו בהגדרות באמצעות החשבון המחובר, ולא באמצעות מפתח API. כל כתובת שייכת לחשבון שיצר אותה בסביבת עבודה אחת, ומקבלת רק מידע שהחשבון הזה רשאי לראות כרגע.

## לפני שמתחילים

- מכינים כתובת HTTPS ציבורית בפורט 443 או 8443, עם תעודת TLS תקינה. הכתובת אינה יכולה לכלול פרטי התחברות או מקטע עוגן, ואורכה מוגבל ל-2,048 תווים.
- מוודאים שכל כתובות ה-IP שאליהן שם המתחם מפנה הן ציבוריות. אפילו תוצאה פרטית אחת מונעת קבלה; הבדיקה נעשית גם לפני המסירה.
- מגדירים את השרת לשמור את גוף הבקשה המקורי לפני פענוח JSON ולקבל POST ללא הפניה לכתובת אחרת.
- מכינים מנהל סודות בשרת, שעון מסונכרן, אחסון עמיד למניעת כפילויות ותור לעיבוד ממושך.
- מתחברים לחשבון שישמש כבעל החיבור ובוחרים סביבת עבודה. תפקיד, מושב ונראות אנשי קשר עדיין נדרשים. לכל חשבון מותרות עד חמש כתובות פעילות ברמת ההגדרה בכל סביבת עבודה.

אם **Webhooks** אינו מופיע, ייתכן שהשירות עדיין לא מופעל בסביבת העבודה. כשה-API למפתחים מושבת, כתובות קיימות נשארות זמינות למחיקה; כרטיס ללא כתובות מוסתר. לא מפרסמים את סוד החתימה במאגר קוד, בכתובת בקשה, ביומנים או בצילומי מסך.

## מוסיפים כתובת לקבלת עדכונים

1. פותחים **הגדרות** ומאתרים **Webhooks** לצד **API למפתחים**. ב־**ה-Webhooks שלך** מופיעות הכתובות ששייכות לחשבון.
2. לוחצים על **הוספת Webhook** ובודקים את **סביבת עבודה** שמוצגת בחלון.
3. מזינים ב־**כתובת Webhook** את כתובת ה־HTTPS הסופית שמקבלת POST. לא משתמשים בדף כניסה או בכתובת שמפנה לנתיב אחר.
4. תחת **אירועים** בוחרים לפחות אחד מבין **איש קשר חדש**, **איש קשר עודכן** ו־**מצב קמפיין השתנה**. אפשר לבחור כמה אירועים לאותה כתובת.
5. לוחצים על **שמירה**. לאחר הצלחה מופיע חלון **סוד החתימה**. לוחצים על **העתקה** ושומרים את הסוד שמתחיל ב-`whsec_` במנהל הסודות בשרת. הוא מוצג פעם אחת בלבד.
6. אם ההעתקה נכשלת, מעתיקים ידנית מהשדה המסומן או מנסים שוב. לוחצים על **שמרתי את הסוד** רק לאחר השמירה. סגירה או יציאה מהעמוד מסירות את הסוד מהתצוגה.
7. מאתרים את הכתובת ב־**ה-Webhooks שלך**, ובודקים סביבת עבודה, תגי אירועים, מצב ו־**מסירה אחרונה**.
8. מגדירים אימות בשרת עם הסוד של הכתובת הזו ולוחצים על **שליחת אירוע בדיקה**. הצלחה יכולה להופיע כ־**נמסר (200)**; גם קודי 2xx אחרים מתקבלים. גוף הבדיקה הוא `webhook.test`, לא איש קשר חדש או שינוי קמפיין אמיתי.

אם לא ברור שהיצירה הושלמה או שהסוד לא נשמר, לוחצים על **רענון הרשימה**, מוחקים כתובת חדשה שהסוד שלה אבד ומוסיפים מחדש. לא שולחים יצירה אוטומטית נוספת, כי הבקשה הראשונה אולי הצליחה. אי אפשר להציג שוב את הסוד; החלפה שלו מחייבת מחיקה ויצירה מחדש.

## בוחרים אירועים ומבינים את המידע

כל גוף כולל `type`,‏ `timestamp` בתאריך ושעה לפי ISO ו-`data`. הכותרת `webhook-timestamp` היא חותמת זמן נפרדת בשניות Unix, המשמשת לאימות ניסיון המסירה. המבנים המלאים נמצאים ב[מפרט ה-API](https://docs.lead-knight.com/he/developers/api-reference/) ובחלק `webhooks` של [מסמך OpenAPI](https://api.lead-knight.com/developer-api/openapi.json).

| האירוע בהגדרות | `type` בגוף | מתי נשלח ומה הוא כולל |
| --- | --- | --- |
| **איש קשר חדש** | `contact.created` | יצירת איש קשר ב-CRM, כולל העברת חבר קהל לאנשי הקשר. `data.contact` משתמש במבנה הבטוח של אנשי הקשר ב-API. |
| **איש קשר עודכן** | `contact.updated` | שינוי שם, אימייל, טלפון, בעלות, שלב, סיבת אובדן, סכום או מטבע עסקה, תגיות או ערכים מותאמים. `data.contact` משקף את המצב בזמן הכנת המסירה. |
| **מצב קמפיין השתנה** | `campaign.status_changed` | שינוי מצב מחושב של קמפיין. `data.campaign` הוא סיכום קמפיין ו-`data.previousStatus` הוא המצב הקודם. הבדיקה נעשית בערך פעם בדקה, ולכן מצב קצר יותר עלול לא להופיע. |
| **שליחת אירוע בדיקה** | `webhook.test` | בדיקה ידנית עם `data.test` בערך true. היא לא מוכיחה שפרטי איש הקשר גלויים לבעל החיבור. |

כמה שינויים סמוכים באיש קשר יכולים להיכלל בהתראה אחת. זה אינו יומן בלתי משתנה של כל עריכה. מידע מוגבל לנראות העדכנית של בעל החיבור; קטגוריות פרטיות שכבר אינן נגישות לא נשלחות. אנשי קשר שנמחקו או מוזגו לא יוצרים גוף מסירה של איש קשר. חברות, תפקיד, מושב וגישה לקטגוריות נבדקים שוב לפני המסירה, גם בניסיון חוזר.

מצב קמפיין אינו אישור מסירה מרשת חברתית. לא מסמנים שהודעה נמסרה או שפוסט פורסם רק בגלל אירוע של שינוי מצב.

## מאמתים כל בקשה לפני שמשתמשים בנתונים

המסירה פועלת לפי [Standard Webhooks](https://www.standardwebhooks.com/). משתמשים בסוד החתימה של הכתובת, ולא במפתח API.

| כותרת | משמעות |
| --- | --- |
| `webhook-id` | מזהה מסירה ייחודי. אותו מזהה וגוף נשמרים בניסיונות חוזרים. |
| `webhook-timestamp` | זמן הניסיון המסוים בשניות Unix. |
| `webhook-signature` | חתימה עם גרסה, `v1,` ולאחריה HMAC-SHA256 בקידוד base64. |

1. קוראים את הגוף המקורי בדיוק כפי שהתקבל. לא מפענחים ומרכיבים JSON מחדש לפני האימות: שינוי רווחים, קידוד או תווים משנה את החתימה.
2. דורשים מזהה מסירה, חותמת זמן מספרית תקינה וחתימה עם גרסה. דוחים חותמת שסוטה ביותר מחמש דקות מהשעון בשרת; לא מבלבלים בין שניות למילישניות.
3. מסירים את הקידומת `whsec_` מהסוד השמור ומפענחים את ההמשך מ-base64 לקבלת מפתח HMAC. לא משתמשים בטקסט המלא של הסוד בתור המפתח.
4. מרכיבים את הקלט לחתימה כך: `&lt;webhook-id>.&lt;webhook-timestamp>.&lt;raw body>`, עם נקודות בין שלושת החלקים, ערכי הכותרות המקוריים וגוף הבקשה ללא שינוי.
5. מחשבים HMAC-SHA256 עם המפתח שפוענח ומקודדים את התוצאה ב-base64. משווים לערך בחתימת `v1,` בזמן קבוע. אם הכותרת מכילה כמה מועמדים מופרדים ברווחים, מקבלים רק מועמד נתמך שתואם באמת.
6. דוחים בקשות לא מאומתות או ישנות לפני שינוי מידע עסקי. לא מדלגים על אימות רק כדי לקבל הצלחה בבדיקת המסירה.
7. אחרי אימות, שומרים `webhook-id` באחסון מתמשך למשך 30 יום למניעת כפילות. למסירה שכבר התקבלה מחזירים תשובת הצלחה בלי לבצע שוב את הפעולות הנלוות לאירוע.
8. מפענחים ומאמתים את האירוע, שומרים אותו או מכניסים לתור בטוח ומחזירים 2xx בתוך עשר שניות. עיבוד ממושך מתבצע לאחר האישור, עם התאוששות עמידה בצד המקבל כדי לא לאבד עבודה שכבר אושרה.

לכל ניסיון חוזר יש זמן וחתימה חדשים, אבל אותו מזהה ואותו גוף. לכן חותמת הזמן בתוך הגוף עשויה להיות ישנה יותר מהניסיון; את בדיקת חמש הדקות מבצעים מול הכותרת של הניסיון, לא מול גיל האירוע.

## כללי מסירה והתאוששות

- המסירה היא לפחות פעם אחת. תשובה יכולה ללכת לאיבוד אחרי שהשרת טיפל בבקשה, ולכן נדרשת מניעת כפילויות גם כשהשרת בדרך כלל מצליח.
- אין הבטחת סדר בין אנשי קשר. משתמשים במצב שבגוף האירוע ולא מניחים שסדר הגעה כללי זהה לסדר השינויים.
- מחזירים 2xx בתוך עשר שניות. אין מעקב אחר הפניות; 3xx, קודים שאינם מציינים הצלחה, כשלי חיבור או TLS וחריגות מזמן התגובה נחשבים לכישלון.
- לאחר הכישלונות הבאים ממתינים דקה, חמש דקות, 15 דקות, שעה, שלוש שעות, שש שעות ו-12 שעות. בסך הכול יש שמונה ניסיונות, כולל הראשון, לאורך כ-22.5 שעות בתוספת זמני טיפול.
- כתובת שמופעלת אך ניסיון המסירה האחרון שלה נכשל מציגה **נכשל**. אחרי הכישלון האחרון היא עוברת ל־**מושבת**, ונשלח אימייל לבעל החיבור.
- מתקנים את השרת לפני **הפעלה**. ההפעלה מאפסת את מצב הכשל, אך אינה משחזרת מסירות שננטשו או שינויים שהוחמצו בזמן ההשבתה. לפי הצורך משלימים את המצב הנוכחי דרך [ה-API למפתחים](https://docs.lead-knight.com/he/developers/developer-api/).
- מחיקת איש קשר באופן מוחלט מסירה מסירות ממתינות. אי אפשר להחזיר בקשה שכבר נשלחה לשרת המקבל.

## משביתים, מוחקים או מחליפים כתובת

1. מאתרים את הכתובת ב־**ה-Webhooks שלך**. **השבתה** עוצרת מסירה בלי למחוק את ההגדרה, והמצב משתנה ל־**מושבת**.
2. לוחצים על **הפעלה** רק לאחר שהשרת וההרשאות מוכנים. השבתה והפעלה אינן שירות לשחזור היסטוריית אירועים.
3. להסרה קבועה לוחצים על **מחיקה**, קוראים את **למחוק את ה-Webhook?** ומאשרים עם **מחיקה**. **ביטול** משאיר את הכתובת. מחיקה אינה הפיכה.
4. לשינוי כתובת השרת, לבחירת אירועים דרך תהליך היצירה הזמין או להחלפת סוד שאבד, מוסיפים כתובת חלופית ומסירים את הישנה. בכרטיס הנוכחי אין טופס עריכה של כתובת או אירועים קיימים. מתחשבים במגבלת חמש הכתובות ובאפשרות לחפיפה בין החיבורים בלי להחיל עדכון פעמיים.
5. אם תוצאת ניהול אינה ברורה, לוחצים על **רענון הרשימה** ובודקים מצב לפני שחוזרים על הפעולה.

## אם משהו לא עובד

| מה רואים | סיבה אפשרית | מה עושים |
| --- | --- | --- |
| הודעת כתובת לא תקינה | HTTP, פורט אסור, פרטי התחברות, עוגן או אורך חריג. | משתמשים בכתובת HTTPS סופית בפורט 443 או 8443, ללא פרטי התחברות ועוגן, עד 2,048 תווים. |
| סירוב בגלל כתובת לא ציבורית | DNS מחזיר כתובת פרטית, שמורה או לא ציבורית. | מתקנים את כל תוצאות ה-DNS; שרת פנימי או localhost אינם מתאימים. |
| חסרה בחירת אירועים | נדרש לפחות אירוע אחד. | בוחרים תחת **אירועים** לפני **שמירה**. |
| הגעתם למגבלת חמש כתובות | מספר ההגדרות שלא נמחקו לחשבון ולסביבה הגיע לתקרה. | מוחקים כתובת שאינה נחוצה לפני הוספה. |
| **נמסר (200)** בלי עדכונים אמיתיים | הבדיקה מאמתת תעבורה, לא אירועים נבחרים או נראות של רשומה. | בודקים תגי אירועים, שינויים בפועל, סביבת עבודה והרשאות בעל החיבור. |
| החתימה אינה תואמת | סוד של כתובת אחרת או שינוי גוף בידי שכבת ביניים. | שומרים את הבתים המקוריים, מפענחים את הסוד אחרי `whsec_` ומשתמשים בשלושת החלקים המדויקים. |
| חותמת הזמן נדחית | סטיית שעון או פירוש שניות כמילישניות. | מסנכרנים את השעון ובודקים `webhook-timestamp` בשניות. |
| חריגה מזמן התגובה | לא התקבלה תשובה בתוך עשר שניות. | מאמתים, שומרים בתור עמיד ומאשרים מהר; מעבירים עיבוד ממושך אל מחוץ לבקשה. |
| כשל TLS, חיבור או הפניה | שרת לא נגיש, תעודה לא תקינה או כתובת שמפנה. | מתקנים גישה ותעודה, משתמשים בכתובת הסופית ושולחים אירוע בדיקה. |
| **מושבת** אחרי כישלונות חוזרים | כל ניסיונות המסירה נכשלו. | מתקנים, בודקים ולוחצים על **הפעלה**; משלימים מידע שהוחמץ בנפרד. |
| הסוד אבד או שהיצירה לא ברורה | הסוד החד־פעמי כבר לא מוצג. | מרעננים, מוחקים את ההגדרה ומוסיפים מחדש; לא מנחשים סוד ולא מחפשים אותו ביומנים. |

## מדריכים קשורים

- [סקירת כלי המפתחים](https://docs.lead-knight.com/he/developers/overview/)
- [מפתחות API והתאוששות](https://docs.lead-knight.com/he/developers/developer-api/)
- [אנשי קשר ו-CRM](https://docs.lead-knight.com/he/contacts/overview/)
- [קמפיינים](https://docs.lead-knight.com/he/campaigns/overview/)
- [מפרט ה-API](https://docs.lead-knight.com/he/developers/api-reference/)
- [מסמך OpenAPI החי](https://api.lead-knight.com/developer-api/openapi.json)



