getlead — לכידת ליד מהאתר
יוצר שורה חדשה בטבלה Accounts עם IsAccount: false, כלומר ליד.
זו נקודת הקצה הנכונה כשהטופס לוכד איש קשר בלבד. אם הטופס צריך גם ליצור רשומה מקושרת (מכירה, פנייה, הרשמה לקורס), עברו ל‑web2table. לא בטוחים? טבלת ההחלטה.
הכותרות והגוף
Section titled “הכותרות והגוף”curl -X POST "https://api.mbapps.co.il/functions/{appId}/getlead" \ -H "Content-Type: application/json" \ -H "X-Parse-Application-Id: {appId}" \ -d '{ "Name": "ישראל ישראלי", "PhoneNumber": "0501234567", "Email": "israel@example.co.il", "City": "תל אביב" }'const res = await fetch(`https://api.mbapps.co.il/functions/${appId}/getlead`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': appId, }, body: JSON.stringify({ Name: 'ישראל ישראלי', PhoneNumber: '0501234567', Email: 'israel@example.co.il', City: 'תל אביב', }),});import requests
res = requests.post( f"https://api.mbapps.co.il/functions/{appId}/getlead", headers={ "Content-Type": "application/json", "X-Parse-Application-Id": appId, }, json={ "Name": "ישראל ישראלי", "PhoneNumber": "0501234567", "Email": "israel@example.co.il", "City": "תל אביב", },)<?php$ch = curl_init();curl_setopt_array($ch, [ CURLOPT_URL => "https://api.mbapps.co.il/functions/{$appId}/getlead", CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "X-Parse-Application-Id: {$appId}", ], CURLOPT_POSTFIELDS => json_encode([ "Name" => "ישראל ישראלי", "PhoneNumber" => "0501234567", "Email" => "israel@example.co.il", "City" => "תל אביב", ], JSON_UNESCAPED_UNICODE),]);$response = curl_exec($ch);curl_close($ch);חובה: לפחות אחד מ‑PhoneNumber או Email.
שמות שדות: ללא קידומת — בדיוק כמו בסכימה של Accounts (Name, F_name, L_name, PhoneNumber, Email, Address, City, CompanyId, וכל שדה מותאם). ראו מיפוי שדות מטופס לסכימה.
תשובות
Section titled “תשובות”| סטטוס | הגוף | המשמעות |
|---|---|---|
200 |
{ "result": { "success": true, "leadId": "<objectId>" } } |
הליד נוצר |
400 |
{"error":"missing \"PhoneNumber\" or \"Email\""} |
חסרים PhoneNumber וגם Email, או ששניהם לא תקינים (כש‑ValidatePhoneOrEmail דלוק) |
400 |
{"error":"AcceptWebLeads is Disabled"} |
דגל ה‑Config כבוי — ראו דגלי Config |
400 |
{"error":"User function not found"} |
שם פונקציה שגוי — למשל השם הישן web2lead. הפונקציה נקראת getlead |
500 |
— | תקלת שרת |
שדות מוגנים — אל תשלחו אותם
Section titled “שדות מוגנים — אל תשלחו אותם”| השדה | מי קובע אותו |
|---|---|
IsAccount |
השרת — תמיד false |
fromWeb2lead |
השרת — תמיד true על ליד שנוצר מהפונקציה |
LeadStatusId |
מנגנון זיהוי הכפילויות (ניתן לעקוף עבור ליד חדש בלבד) |
objectId, createdAt, updatedAt, ACL, createdBy, updatedBy |
שדות מערכת |
זיהוי כפילויות — מה בדיוק קורה בשרת
Section titled “זיהוי כפילויות — מה בדיוק קורה בשרת”- הטלפון מנורמל: מסירים תווים שאינם ספרות, ו‑
972…הופך ל‑0…. - השרת מריץ שאילתה על
Accounts.PhoneNumberמול כל הווריאציות:05XXXXXXXX,9725XXXXXXX,+9725XXXXXXX,05X-XXXXXXX,+972-5X-XXXXXXX(ומקבילותיהן לקווי נייח) — ב‑OR עםAccounts.Email == <האימייל>. - כפילות לא חוסמת יצירה. תמיד נוצרת שורה חדשה:
- נמצאה התאמה → הליד החדש מקבל את סטטוס “ליד כפול” (ברירת המחדל בתבנית:
QYvLV9xHE1). - לא נמצאה → הוא מקבל את ה‑
LeadStatusIdשנשלח בבקשה, ואם לא נשלח, את סטטוס “ליד חדש” (ברירת המחדל:e9TwcETDGq).
- נמצאה התאמה → הליד החדש מקבל את סטטוס “ליד כפול” (ברירת המחדל בתבנית:
הפירוט המלא — נרמול הטלפון, כל הפורמטים שנסרקים, וההבדל מול web2table: זיהוי כפילויות — מה קורה בשרת.
טיפוסים — הפורמט של שכבת הטפסים
Section titled “טיפוסים — הפורמט של שכבת הטפסים”הטבלה הזו נמדדה בפועל על web2table, שמשתמשת באותה שכבת המרה:
| טיפוס בסכימה | מה שולחים | הערות מהאימות |
|---|---|---|
| String | מחרוזת | מחרוזת ריקה לא נשמרת — השדה כלל אינו נכתב |
| Number | מספר או מחרוזת מספרית | "1,500" ו‑"abc" נשמרים כ‑null, לא נזרקים |
| Boolean | true / false (בוליאני) — מומלץ. המחרוזת "true" / "false" מתקבלת ברוב השדות |
חריג: ב‑IsAccount מחרוזת מפילה את כל הבקשה ב‑400 (code 111, “expected Boolean but got String”) — רק בוליאני אמיתי עובד (באג web-forms-04). מספר (1 / 0) נדחה ב‑400 בכל שדה בוליאני |
| Date | מחרוזת ISO שטוחה מרופדת: "2026-06-10" |
גם ISO מלא וגם {"__type":"Date","iso":…} עובדים. "2026-6-1" (לא מרופד) מפיל את כל הבקשה ב‑400 (code 111). זהירות: "10/06/2026" מתקבל — אבל נקרא כ‑6 באוקטובר (חודש/יום אמריקאי). שלחו ISO בלבד |
| Pointer | מחרוזת objectId חשופה, 10 תווים: "vOZLqOWnQf" |
גם {"__type":"Pointer",…} עובד. אורך אחר מפיל את כל הבקשה ב‑400 (code 111). מחרוזת ריקה — 200 והשדה לא נכתב |
| בחירה מרובה | מערך של objectId חשופים | מערך אובייקטי Pointer נשמר כפי שנשלח — כלומר פוגם בנתונים בשקט |
| File | לא נתמך — אל תשלחו | מחרוזת URL → 400 (code 111) אבל איש הקשר כבר נוצר. אובייקט File → 400 (code 1) אחרי ~4 שניות, ובצד השרת נוצרו איש קשר ו‑5 שורות יעד כפולות (באג web-forms-10). קבצים מעלים בנפרד, מהשרת, אחרי שהרשומה נוצרה |
מיפוי שדה Pointer מטופס
Section titled “מיפוי שדה Pointer מטופס”<select> בטופס שולח טקסט; ה‑API רוצה objectId. לכן שולפים פעם אחת את טבלת ה‑lookup ומטמיעים מפה סטטית בקוד:
// נשלף פעם אחת מטבלת LeadSource — עדכנו כשמוסיפים מקור חדשconst SOURCE_MAP = { 'פייסבוק': 'vOZLqOWnQf', 'גוגל': 'fHG8Rgy8Hr', 'אתר אינטרנט': 'yOTdl4L99Q',};אם הערך שנבחר לא נמצא במפה, השמיטו את השדה מהגוף. אל תשלחו undefined ואל תשלחו מחרוזת ריקה.
קוד מוכן — טופס בדף נחיתה
Section titled “קוד מוכן — טופס בדף נחיתה”<form id="lead-form" novalidate> <input name="fullName" placeholder="שם מלא" /> <input name="phone" type="tel" placeholder="טלפון" required /> <input name="email" type="email" placeholder="אימייל" /> <input name="city" placeholder="עיר" /> <select name="source"> <option value="">איך הגעתם אלינו?</option> <option>פייסבוק</option> <option>גוגל</option> <option>אתר אינטרנט</option> </select>
<!-- מלכודת דבש: בוט ימלא אותה, אדם לא יראה אותה כלל --> <input name="company_website" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px" aria-hidden="true" />
<button type="submit">שליחה</button> <p class="form-msg" role="status" aria-live="polite"></p></form>
<script>const APP_ID = 'הדביקו-כאן-את-ה-Application-Id';
const SOURCE_MAP = { 'פייסבוק': 'vOZLqOWnQf', 'גוגל': 'fHG8Rgy8Hr', 'אתר אינטרנט': 'yOTdl4L99Q',};
const form = document.getElementById('lead-form');const msg = form.querySelector('.form-msg');
form.addEventListener('submit', async (e) => { e.preventDefault(); const f = Object.fromEntries(new FormData(form));
// מלכודת דבש מלאה → זה בוט. מציגים "הצלחה" ולא שולחים כלום. if (f.company_website) { msg.textContent = 'תודה! נחזור אליכם בהקדם.'; return; }
const data = { Name: f.fullName, PhoneNumber: f.phone, Email: f.email, City: f.city, LeadSourceId: SOURCE_MAP[f.source], // objectId חשוף, או undefined };
// ניקוי ערכים ריקים — כדי לא לשלוח מחרוזות ריקות למערכת Object.keys(data).forEach((k) => { if (!data[k]) delete data[k]; });
if (!data.PhoneNumber && !data.Email) { msg.textContent = 'נא למלא טלפון או אימייל'; return; }
const btn = form.querySelector('button'); btn.disabled = true;
try { const res = await fetch(`https://api.mbapps.co.il/functions/${APP_ID}/getlead`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APP_ID }, body: JSON.stringify(data), });
if (res.ok) { const body = await res.json(); // { result: { success: true, leadId: "..." } } window.dataLayer?.push({ event: 'form_submit', lead_id: body.result?.leadId }); window.location.href = '/thank-you/'; return; } // כל שגיאה עסקית חוזרת כ-400 — ההבחנה היא לפי הגוף, לא לפי הסטטוס const err = await res.json().catch(() => ({})); if (/Disabled/.test(err.error || '')) msg.textContent = 'קבלת פניות מהאתר אינה מופעלת כרגע'; else if (/missing/.test(err.error || '')) msg.textContent = 'נא למלא טלפון או אימייל תקינים'; else msg.textContent = 'אירעה שגיאה, נסו שוב'; } catch { msg.textContent = 'אין חיבור לרשת, נסו שוב'; } finally { btn.disabled = false; }});</script>הפעלה חד‑פעמית לכל מערכת
Section titled “הפעלה חד‑פעמית לכל מערכת”נקודת הקצה חסומה עד שמפעילים אותה. ההפעלה היא שורה בטבלת המערכת Config:
| שדה | ערך |
|---|---|
Name |
AcceptWebLeads (String) |
Value |
{ "AcceptWebLeads": true } (Object — שם הדגל חוזר בתוך האובייקט) |
הפונקציה קוראת את המפתח הפנימי. ערך בוליאני חשוף ("Value": true) לא ניתן אפילו לשמירה — Config.Value מוגדר Object בסכימה, ו‑REST מחזיר 400 code 111 כבר בכתיבה. שימו לב: המפתח הפנימי נבדק לפי truthiness — גם המחרוזת "false" נקראת כדלוק (מגבלה forms-a-01); כיבוי אמין הוא false בוליאני.
בממשק ה‑CRM אין עמוד Config (אומת — web-forms-07); העריכה נעשית דרך סביבת הפיתוח (סביבת פיתוח ← Databases ← המערכת ← Tables ← Config) או דרך REST.
דרך REST (דורש Master Key — הטבלה חסומה לשאר השכבות):
curl -X POST "https://api.mbapps.co.il/parse/classes/Config" \ -H "X-Parse-Application-Id: {appId}" \ -H "X-Parse-Master-Key: {masterKey}" \ -H "Content-Type: application/json" \ -d '{ "Name": "AcceptWebLeads", "Value": { "AcceptWebLeads": true } }'const res = await fetch("https://api.mbapps.co.il/parse/classes/Config", { method: 'POST', headers: { 'X-Parse-Application-Id': appId, 'X-Parse-Master-Key': masterKey, 'Content-Type': 'application/json', }, body: JSON.stringify({ Name: 'AcceptWebLeads', Value: { AcceptWebLeads: true }, }),});import requests
res = requests.post( "https://api.mbapps.co.il/parse/classes/Config", headers={ "X-Parse-Application-Id": appId, "X-Parse-Master-Key": masterKey, "Content-Type": "application/json", }, json={ "Name": "AcceptWebLeads", "Value": {"AcceptWebLeads": True}, },)<?php$ch = curl_init();curl_setopt_array($ch, [ CURLOPT_URL => "https://api.mbapps.co.il/parse/classes/Config", CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "X-Parse-Application-Id: {$appId}", "X-Parse-Master-Key: {$masterKey}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "Name" => "AcceptWebLeads", "Value" => ["AcceptWebLeads" => true], ]),]);$response = curl_exec($ch);curl_close($ch);החזיקו שורה אחת בלבד לכל דגל. הקוד לוקח query.first() ללא מיון, ובאימות (16 קריאות בשני סדרי יצירה) התברר שהשורה שנוצרה ראשונה היא שמנצחת תמיד — כלומר שורה ישנה עם false תמיד תשתק שורה חדשה עם true. ראו דגלי Config.
המסלול המלא בממשק, כולל צילום המקרים שבהם הדגל “נראה דלוק” ואינו — הפעלת קליטה מהאתר: דגלי Config.
מה עוד יושב בתוך Value
Section titled “מה עוד יושב בתוך Value”אובייקט ה‑Value הוא לא רק מתג — הוא גם ההגדרות של נקודת הקצה:
| המפתח | מה הוא עושה |
|---|---|
AcceptWebLeads |
המתג עצמו |
ValidatePhoneOrEmail |
מה שהופך את בדיקת התקינות לפעילה. כשהוא דלוק, השרת דוחה ב‑400 בקשה שבה גם הטלפון וגם האימייל אינם תקינים. תקין אחד מהם — הבקשה עוברת. הגבולות נמדדו: טלפון — מסירים תווים שאינם ספרות ואז 7–14 ספרות; אימייל — 6–80 תווים, מכיל @ וגם . |
DefaultValues.Account |
ערכי ברירת מחדל שהשרת ממלא באיש הקשר שנוצר, כשהבקשה לא שלחה אותם. עובד רק ב‑web2table — ראו האזהרה למטה |
{ "Name": "AcceptWebLeads", "Value": { "AcceptWebLeads": true, "ValidatePhoneOrEmail": true, "DefaultValues": { "Account": { "LeadSourceId": "yOTdl4L99Q" } } }}הכללים של מיפוי שדות חלים גם על DefaultValues: Pointer כמזהה חשוף בן 10 תווים, בוליאני כמחרוזת.
CAPTCHA ואנטי‑ספאם
Section titled “CAPTCHA ואנטי‑ספאם”נקודת הקצה לא מאמתת reCAPTCHA, Turnstile או מלכודות דבש. יש שתי דרכים:
- מלכודת דבש: כמו בקוד למעלה. חינם, ללא חיכוך, מסננת בוטים פשוטים.
- טוקן CAPTCHA אמיתי: מאמתים אותו בשרת שלכם ורק אז מעבירים ל‑
getlead. ה‑secret של CAPTCHA לעולם לא יושב בדפדפן, ולכן שרת ביניים הוא התבנית המומלצת כשיש CAPTCHA. הפרדת האחריות המלאה: מודל האבטחה.
// Cloudflare Worker / Express — שרת ביניים שמאמת Turnstile ואז מעביר הלאהexport async function onRequestPost({ request, env }) { const body = await request.json();
const verify = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ secret: env.TURNSTILE_SECRET, response: body.token }), }).then((r) => r.json());
if (!verify.success) return new Response('captcha failed', { status: 400 });
delete body.token; return fetch(`https://api.mbapps.co.il/functions/${env.APP_ID}/getlead`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': env.APP_ID }, body: JSON.stringify(body), });}רשימת בדיקה לפני עלייה לאוויר
Section titled “רשימת בדיקה לפני עלייה לאוויר”- נשלפה סכימת
Accountsוכל שדה בטופס אומת מולה - כל שדה Pointer קיבל מיפוי מטבלת ה‑lookup (ולא נשלח כטקסט חופשי)
- Pointer נשלח כמחרוזת objectId חשופה, לא כאובייקט
- בוליאנים כבוליאני אמיתי
true/false(מחרוזת עוברת ברוב השדות, אבל ב‑IsAccountמפילה את הבקשה; מספר נדחה תמיד) - תאריכים כ‑ISO שטוח מרופד (
2026-06-01, לא2026-6-1ולאdd/mm/yyyy) - אין שדה File בגוף — הוא מחזיר 400 ובכל זאת יוצר רשומות
- ערכים ריקים מוסרים מהגוף
- הדגל
AcceptWebLeadsדלוק — שורה אחת בלבד, והיא הישנה ביותר אם יש כפילות - הטיפול בשגיאה בממשק המשתמש מסתעף על גוף התשובה ולא על קוד הסטטוס (הכול חוזר כ‑400)
- יש מלכודת דבש או CAPTCHA דרך שרת ביניים
- אירוע המרה נשלח ל‑GTM/Analytics אחרי הצלחה בלבד
- web2table — כשצריך גם רשומה בטבלת יעד
- דגלי Config — ההפעלה, ולמה
… is Disabledהוא כמעט תמיד זה - מיפוי שדות · זיהוי כפילויות · מודל האבטחה
- הטמעה בפועל — WordPress, Wix, HTML ושרת ביניים
- אבחון תקלות בטפסים · שגיאות ופתרון תקלות
- דוגמאות קוד — PHP, Python, Node, C#