דלגו לתוכן

או התחילו מנקודה בטוחה: אינדקס הכלים המלא · מפת הטבלאות המרכזיות

מערכת חדשה — 14 יום חינם

getlead — לכידת ליד מהאתר

עודכן 30.08.2026
POST https://api.mbapps.co.il/functions/{appId}/getlead

יוצר שורה חדשה בטבלה Accounts עם IsAccount: false, כלומר ליד.

זו נקודת הקצה הנכונה כשהטופס לוכד איש קשר בלבד. אם הטופס צריך גם ליצור רשומה מקושרת (מכירה, פנייה, הרשמה לקורס), עברו ל‑web2table. לא בטוחים? טבלת ההחלטה.

Bash
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": "תל אביב" }'
JavaScript
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: 'תל אביב',
}),
});
Python
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
<?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, וכל שדה מותאם). ראו מיפוי שדות מטופס לסכימה.

סטטוס הגוף המשמעות
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 “זיהוי כפילויות — מה בדיוק קורה בשרת”
  1. הטלפון מנורמל: מסירים תווים שאינם ספרות, ו‑972… הופך ל‑0….
  2. השרת מריץ שאילתה על Accounts.PhoneNumber מול כל הווריאציות: 05XXXXXXXX, 9725XXXXXXX, +9725XXXXXXX, 05X-XXXXXXX, +972-5X-XXXXXXX (ומקבילותיהן לקווי נייח) — ב‑OR עם Accounts.Email == <האימייל>.
  3. כפילות לא חוסמת יצירה. תמיד נוצרת שורה חדשה:
    • נמצאה התאמה → הליד החדש מקבל את סטטוס “ליד כפול” (ברירת המחדל בתבנית: 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). קבצים מעלים בנפרד, מהשרת, אחרי שהרשומה נוצרה

<select> בטופס שולח טקסט; ה‑API רוצה objectId. לכן שולפים פעם אחת את טבלת ה‑lookup ומטמיעים מפה סטטית בקוד:

JavaScript
// נשלף פעם אחת מטבלת LeadSource — עדכנו כשמוסיפים מקור חדש
const SOURCE_MAP = {
'פייסבוק': 'vOZLqOWnQf',
'גוגל': 'fHG8Rgy8Hr',
'אתר אינטרנט': 'yOTdl4L99Q',
};

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

קוד מוכן — טופס בדף נחיתה

Section titled “קוד מוכן — טופס בדף נחיתה”
HTML
<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 — הטבלה חסומה לשאר השכבות):

Bash
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 } }'
JavaScript
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 },
}),
});
Python
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
<?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 הוא לא רק מתג — הוא גם ההגדרות של נקודת הקצה:

המפתח מה הוא עושה
AcceptWebLeads המתג עצמו
ValidatePhoneOrEmail מה שהופך את בדיקת התקינות לפעילה. כשהוא דלוק, השרת דוחה ב‑400 בקשה שבה גם הטלפון וגם האימייל אינם תקינים. תקין אחד מהם — הבקשה עוברת. הגבולות נמדדו: טלפון — מסירים תווים שאינם ספרות ואז 7–14 ספרות; אימייל — 6–80 תווים, מכיל @ וגם .
DefaultValues.Account ערכי ברירת מחדל שהשרת ממלא באיש הקשר שנוצר, כשהבקשה לא שלחה אותם. עובד רק ב‑web2table — ראו האזהרה למטה
JSON
{
"Name": "AcceptWebLeads",
"Value": {
"AcceptWebLeads": true,
"ValidatePhoneOrEmail": true,
"DefaultValues": { "Account": { "LeadSourceId": "yOTdl4L99Q" } }
}
}

הכללים של מיפוי שדות חלים גם על DefaultValues: Pointer כמזהה חשוף בן 10 תווים, בוליאני כמחרוזת.

נקודת הקצה לא מאמתת reCAPTCHA, Turnstile או מלכודות דבש. יש שתי דרכים:

  • מלכודת דבש: כמו בקוד למעלה. חינם, ללא חיכוך, מסננת בוטים פשוטים.
  • טוקן CAPTCHA אמיתי: מאמתים אותו בשרת שלכם ורק אז מעבירים ל‑getlead. ה‑secret של CAPTCHA לעולם לא יושב בדפדפן, ולכן שרת ביניים הוא התבנית המומלצת כשיש CAPTCHA. הפרדת האחריות המלאה: מודל האבטחה.
JavaScript
// 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 אחרי הצלחה בלבד