web2table — יצירת רשומה מקושרת
יוצר שורה בכל טבלת יעד (Sales, Cases, Orders, טבלה מותאמת) וגם איש קשר ב‑Accounts, אם הוא עדיין לא קיים. איש קשר קיים נמצא ומקושר, לא משוכפל.
גוף הבקשה
Section titled “גוף הבקשה”{ "table": "Sales", "phone": "0501234567", "email": "israel@example.co.il", "account_Name": "ישראל ישראלי", "account_City": "תל אביב", "table_Name": "פנייה מדף נחיתה", "table_Total": 1500, "table_Comment": "הגיע מדף הנחיתה"}חובה: table, שם המחלקה המדויק, וגם phone.
שלוש קבוצות שמות השדות
Section titled “שלוש קבוצות שמות השדות”לכל קבוצה קידומת משלה, ולא מערבבים.
| הקבוצה | קידומת | דוגמאות | מה השרת עושה |
|---|---|---|---|
| מפתחות איתור | אין | phone, phone2, email, email2, idnum, table |
מזינים את זיהוי הכפילויות. באיש קשר חדש: phone→PhoneNumber, email→Email, idnum→CompanyId |
שדות Accounts |
account_ |
account_Name, account_F_name, account_City, account_CompanyId |
מוחלים רק כשנוצר איש קשר חדש |
| שדות טבלת היעד | table_ |
table_Name, table_Total, table_Comment |
מוחלים על השורה החדשה, אחרי אימות מול הסכימה |
| תוספות ברמה העליונה | אין | Name, CampaignName, PageName, isExistsAccountCheck |
ראו “שדות שנקבעים אוטומטית” |
מפתחות האיתור במלואם
Section titled “מפתחות האיתור במלואם”חמישה, כולם בלי קידומת.
| המפתח | מה הוא עושה בחיפוש | מה הוא ממלא באיש קשר חדש |
|---|---|---|
phone |
✔ חובה. נסרק בחמישה פורמטים שמורים בלבד (הרשימה) | Accounts.PhoneNumber |
phone2 |
מפתח משני — נסרק גם הוא | כלום — ראו למטה |
email |
השוואת שוויון, ב‑OR מול הטלפון | Accounts.Email |
email2 |
מפתח משני | כלום — ראו למטה |
idnum |
ח.פ. / ת.ז. — השוואה מדויקת, בלי נרמול | Accounts.CompanyId |
שדות שנקבעים אוטומטית בשורה החדשה
Section titled “שדות שנקבעים אוטומטית בשורה החדשה”| השדה | הערך |
|---|---|
AccountId |
Pointer לאיש הקשר שנמצא או נוצר |
IsFirst |
true לאיש קשר חדש; false רק כשאיש הקשר היה קיים וגם נשלח isExistsAccountCheck: true |
Name |
ה‑Name מהבקשה; אחרת "פניה ראשונה" (חדש) או "פניה חוזרת" (חוזר + isExistsAccountCheck) |
CampaignName / PageName |
הערך מהבקשה; אחרת "MainLandingPage" |
PhoneNumber, Email |
מועתקים מאיש הקשר |
AccountNotExist |
true — תמיד, ראו למטה |
זיהוי כפילויות
Section titled “זיהוי כפילויות”אותה שאילתה רב‑פורמטית של getlead: כל וריאציות הטלפון ב‑OR עם האימייל, ובנוסף CompanyId מ‑idnum והמפתחות המשניים phone2 / email2. הפירוט המלא.
תשובות
Section titled “תשובות”| סטטוס | הגוף |
|---|---|
200 |
{ "success": true, "accountId": "<objectId>", "Id": "<objectId של שורת היעד>" } |
400 |
missing "phone" · missing "table" in request body · missing "PhoneNumber" or "Email" (ולידציה) · AcceptWebToTable is Disabled |
400 |
{"code":103,"message":"Class X does not exist."} — שם מחלקה שאינו קיים |
400 |
{"code":111,"message":"schema mismatch for …"} — טיפוס שגוי: Pointer באורך לא נכון, תאריך לא מרופד ("2026-6-1"), מחרוזת ב‑account_IsAccount, מספר בשדה בוליאני, מחרוזת URL בשדה File. שורת היעד לא נוצרת; מה קורה לאיש הקשר תלוי בקבוצת השדה (ראו למטה) |
400 |
{"code":1} — אובייקט File של קובץ שלא הועלה. חוזר אחרי כ‑5 שניות, ובצד השרת נוצרו איש קשר ו‑5 שורות יעד כפולות. קובץ שהועלה קודם (POST /parse/files/<name>) נשמר תקין — 200 ושורה אחת |
400 |
{} (גוף ריק) — table או phone שאינם מחרוזת, למשל מספר |
500 |
תקלת שרת |
שני מקרי שימוש
Section titled “שני מקרי שימוש”הרשמה לקורס
Section titled “הרשמה לקורס”const APP_ID = 'הדביקו-כאן';
const COURSE_MAP = { 'קורס יסודות CRM': 'aB3dEf9HiJ', 'סדנת אוטומציות': 'kLm4NoP7Qr',};
async function submitRegistration(f) { const data = { table: 'CourseRegistrations', // שם המחלקה המדויק phone: f.phone, // חובה, בלי קידומת email: f.email, idnum: f.idNumber, // → Accounts.CompanyId על איש קשר חדש
account_F_name: f.firstName, account_L_name: f.lastName, account_City: f.city,
table_CourseId: COURSE_MAP[f.course], // objectId חשוף table_StartDate: f.startDate, // ISO שטוח: "2026-09-01" table_Comment: f.notes, PageName: 'course-landing-2026', isExistsAccountCheck: true, // כדי ש-IsFirst יהיה אמין };
Object.keys(data).forEach((k) => { if (data[k] == null || data[k] === '') delete data[k]; });
const res = await fetch(`https://api.mbapps.co.il/functions/${APP_ID}/web2table`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APP_ID }, body: JSON.stringify(data), });
const body = await res.json().catch(() => ({})); if (!res.ok) { // כל שגיאה עסקית חוזרת כ-400 — ההבחנה היא לפי הגוף const e = body.error || body.message || ''; if (/Disabled/.test(e)) throw new Error('AcceptWebToTable כבוי במערכת'); if (/missing/.test(e)) throw new Error('חסר טלפון או שם טבלה'); throw new Error('שגיאת שרת: ' + e); } return body; // { success, accountId, Id }}לקוח (ולא ליד) + בחירה מרובה
Section titled “לקוח (ולא ליד) + בחירה מרובה”const data = { table: 'Orders', phone: '0501234567', account_Name: 'חברת דוגמה בע"מ', account_IsAccount: true, // בוליאני אמיתי! → נוצר כלקוח, לא כליד account_CompanyId: '514999999', table_Total: '2400', table_array_tags_Pointer_Tags: ['GGZUYqBjqT', 'io3Z6YsMcG'],};שדות בחירה מרובה (array_*_Pointer_*) מקבלים מערך של אובייקטי Pointer ({"__type":"Pointer","className":…,"objectId":…}) עם קידומת הקבוצה — הפורמט שה‑CRM עצמו שומר. מערך של מזהים חשופים נשמר, אבל מוצג בכרטיס כצ’יפים ריקים.
הפעלה — דגל נפרד משל עצמו
Section titled “הפעלה — דגל נפרד משל עצמו”| שדה | ערך |
|---|---|
Name |
AcceptWebToTable |
Value |
{ "AcceptWebToTable": true } |
מה עוד יושב בתוך Value
Section titled “מה עוד יושב בתוך Value”| המפתח | מה הוא עושה |
|---|---|
AcceptWebToTable |
המתג עצמו |
ValidatePhoneOrEmail |
אכיפה בצד השרת: 400 missing "PhoneNumber" or "Email" כשגם הטלפון (מסירים תווים שאינם ספרות, ואז 7–14 ספרות) וגם האימייל (6–80 תווים, מכיל @ ו‑.) אינם תקינים |
DefaultValues.Account |
ערכי ברירת מחדל לאיש הקשר שנוצר |
DefaultValues.Table |
ערכי ברירת מחדל לשורה שנוצרת בטבלת היעד, למשל סטטוס פתיחה או דגל “הגיע מהאתר”, בלי לחשוף מזהים בקוד הדף |
{ "Name": "AcceptWebToTable", "Value": { "AcceptWebToTable": true, "ValidatePhoneOrEmail": true, "DefaultValues": { "Account": { "LeadSourceId": "yOTdl4L99Q" }, "Table": { "SaleStatusId": "zrP1MSVBoq", "IsWeb": "true" } } }}שני כללים על DefaultValues: מוחלות רק על שדות שהבקשה לא שלחה, וערך שנשלח בגוף מנצח; וכפופות לטיפוסים של שכבת הטפסים, Pointer כמזהה חשוף בן 10 תווים ותאריך ISO שטוח (מיפוי שדות).
מודל האבטחה — שלוש עובדות שקובעות ארכיטקטורה
Section titled “מודל האבטחה — שלוש עובדות שקובעות ארכיטקטורה”- כתיבה אנונימית ישירה ל‑REST חסומה ב‑CAPTCHA, ופתיחת CLP לא עוזרת.
POST /parse/classes/<Table>עם Application Id בלבד נדחה עםcode 119, גם אחריcreate: {"*": true}. שער ה‑CAPTCHA יושב לפני בדיקת ההרשאות. web2tableרץ בהרשאות מוגברות ועוקף CLP. גם כשה‑CLP של טבלת היעד סגור לחלוטין ({}לכל פעולה) הפונקציה יוצרת שורה ומחזירה 200. השאירו אותו סגור, פתיחתו היא חשיפה נטו.web2tableהוא create‑only.objectIdאוtable_objectIdלא פונים לשורה קיימת: מזהה חדש חוזר בתשובה, וכל קריאה מוסיפה שורה.
“עדכון מקישור ציבורי” נבנה כטבלת קליטה + טריגר השלכה, לא כעדכון ישיר: מודל האבטחה של כתיבה אנונימית.
רשימת בדיקה
Section titled “רשימת בדיקה”-
tableהוא שם המחלקה המדויק, לא התווית בעברית -
phoneנשלח, בלי קידומת - נשלפו סכימות
Accountsוגם טבלת היעד, וכל שדה אומת - Pointer בודד כמחרוזת של 10 תווים בדיוק, מערך Pointer כאובייקטים, תאריכים ISO מרופד, קובץ רק אחרי העלאה
-
account_IsAccount, אם נדרש, נשלח כבוליאני -
SaleStatusIdנקבע דרךDefaultValues.Table -
isExistsAccountCheck: trueאםIsFirstמשמעותי לדיווח -
AcceptWebToTableדלוק, שורה אחת בלבד - טיפול השגיאות מסתעף על גוף התשובה
- ה‑CLP של טבלת היעד נשאר סגור
- תיעדתם שכל קריאה מוסיפה שורה
- getlead — כשצריך רק איש קשר
- דגלי Config —
AcceptWebToTable, וכללי השורה היחידה - מיפוי שדות · זיהוי כפילויות · מודל האבטחה
- הטמעה בפועל — WordPress, Wix, HTML ושרת ביניים
- אבחון תקלות בטפסים · שגיאות ופתרון תקלות
- דוגמאות קוד — PHP, Python, Node, C#