דלגו לתוכן

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

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

סקילים — אוטומציה

עודכן 10.10.2026

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

הסקיל איפה זה רץ האם זה אוכף
myb-p-trigger-setup שרת כן — גם על כתיבות API
myb-p-form-rules דפדפן, בטופס לא — כתיבת API עוקפת לגמרי
myb-p-sla-configuration שרת (טריגרים) + הגדרות כן — אבל רק אחרי שבנו את הטריגרים
myb-p-chatbots MyChat — בכל שיחה נכנסת לא — מנהל שיחה, לא אוכף כתיבות

טריגר מפוצל לשני חלקים, ולכן לשני כלים:

TRIGGER (מתי) ACTIONS (מה) — אחת או יותר
├── type: data change / scheduled ├── email
├── events: create / update ├── sms
├── criterias: תנאים ├── whatsapp-message
├── onSetFields: שדות מנוטרים ├── create-object
└── oneachupdate: חוזר? ├── update-object
├── notification
├── http (webhook)
├── server-side-code
└── ai-webhook

Set-Trigger יוצר את הראש ומחזיר מזהה; Set-Trigger-Action נקרא פעם אחת לכל פעולה.

המזהה בתשובה: ב‑data change התשובה היא סכימת הטבלה כולה, והמזהה ב‑triggers[].._id (10 תווים, מחפשים לפי name); ב‑scheduled התשובה היא {"value":"<24-hex>"}.

הפרמטר טיפוס חובה המשמעות
tableName String ✔ הטבלה שעליה הטריגר יושב
type Enum ✔ data change · scheduled
active Boolean ✔ חובה גם ביצירה
name String שם תיאורי. בעברית — מומלץ
_id String קיים ⇒ עדכון; נעדר ⇒ יצירה
events Array ל‑data change ["create"] · ["update"] · שניהם
onSetFields Array<String> ל‑data change הטריגר נבחן רק אם אחד מהשדות האלה השתנה
criterias Array תנאי סינון במבנה F/C/T/V/P
oneachupdate Boolean false (ברירת מחדל) = פעם אחת לרשומה · true = בכל עדכון תואם
schedulerField String ל‑scheduled שדה תאריך שממנו נגזר התזמון
shcedulerHours Number ל‑scheduled כמה שעות לפני ערך התאריך. שלילי = אחרי

בעדכון שלחו רק את מה שמשתנה, בשני הסוגים; ב‑scheduled, שינוי שם בלבד שומר את כל שאר ההגדרות.

מונע לולאות: טריגר על Sales שכותב חזרה ל‑Sales יפעיל את עצמו אלא אם השדה שהוא כותב אינו ברשימה. גם שיקול ביצועים: בלעדיו כל עדכון בטבלה נבחן מול כל התנאים. מערך ריק [] עובד, ופירושו “כל שינוי בשדה כלשהו”. באירוע create בחרו שדה שתמיד נקבע ביצירה.

JSON
{
"F": "SaleStatusId",
"FText": "סטטוס מכירה",
"C": "equalTo",
"T": "Pointer",
"V": "zrP1MSVBoq",
"P": { "targetClass": "SaleStatuses", "visibleVal": "הושלמה", "multiple": false },
"condOr": false
}

האופרטורים בסכימה: contains · startsWith · equalTo · greaterThan · lessThan · greaterThanOrEqualTo · lessThanOrEqualTo · notEqualTo · containedIn · notContainedIn.

תנאים בלי condOr הם AND, כולם חייבים להתקיים; תנאים עם condOr: true מרכיבים קבוצת OR שמספיק שאחד מהם יתקיים. condOr על תנאי בודד לא עושה כלום.

הפעולות — מה כל אחת דורשת

Section titled “הפעולות — מה כל אחת דורשת”
actionType שדות החובה ב‑actionData
email template · emailAccount · emailType (fixed/field) · emailTarget · emailSubject · saveToEmailsTable
sms from · local · content · toType · to
whatsapp-message toType · to · message · from · template · WATemplateParams
notification userType · user · content (+ icon, iconColor אופציונליים)
create-object targetClass · fieldsValue[]
update-object targetClass · connection · fieldsValue[]
http url · method (GET/POST/PUT/DELETE/AUTO)
server-side-code functionName
ai-webhook webhookId · webhookName (בבלוק actionData.aiWebhook; מוודאים את שם ה‑actionType ב‑tools/list)

AUTO ב‑http: POST ליצירה, PUT לעדכון.

connection — הכיוון של העדכון

Section titled “connection — הכיוון של העדכון”

הערך הוא DIRECTION.FIELD_NAME:

הכיוון המשמעות
target.<Field> הרשומה המעודכנת מצביעה לרשומה שהפעילה. למשל target.SaleId כשהטריגר על Sales והשדה SaleId בטבלה המעודכנת מצביע למכירה
source.<Field> הרשומה שהפעילה מצביעה לרשומה המעודכנת. למשל source.AccountId — לעדכן את הלקוח המקושר

בתוך fieldsValue, timeGap מוסיף דקות לערך תאריך דינמי. שלילי מותר.

JSON
{ "field": "DueDate", "type": "dynamic", "value": "updatedAt", "timeGap": 1440 }
// יום אחרי רגע העדכון

{{{FieldName}}} — שלוש סוגריים — עובד בנושא ובגוף המייל, בתוכן ה‑SMS, בתוכן ההתראה, ובכתובת ה‑URL של ה‑webhook:

  • {{{Name}}} — שדה מהרשומה שהפעילה
  • {{{AccountId.Name}}} — מעבר דרך Pointer
  • {{{SaleDate.format(date,he-IL,Asia/Jerusalem)}}} — סוג (date/timehm/datetime), locale, אזור זמן

emailTarget תומך גם הוא במעבר Pointer: "OwnerId.email" שולח לאחראי.

התבנית הטריגר הפעולה
התראה על שינוי סטטוס events: ["update"], onSetFields: ["StatusId"], קריטריון לסטטוס notification / email / sms
מייל ברוכים הבאים events: ["create"] email
משימת מעקב אוטומטית events: ["update"] + קריטריון לסטטוס סגירה create-object עם timeGap: 1440
סנכרון שדות בין טבלאות events: ["update"], onSetFields: ["<field>"] update-object עם connection
תזכורת מתוזמנת type: "scheduled", shcedulerHours: 24 sms / notification
webhook למערכת חיצונית events: ["create", "update"] http POST
  • מחיקת טריגר. MCP רק מכבה (active: false). מחיקה: Admin ← Databases ← Tables ← [הטבלה] ← Triggers, ידנית.
  • טריגר “הוספה לציר זמן” — בממשק בלבד.
  • עריכת תבניות מייל — נוצרות בממשק; הטריגר מפנה ל‑objectId קיים.
  • יצירת חשבונות SMTP — Get-SMTP-Accounts מציג קיימים; יצירה בממשק.
  • יצירת תבניות WhatsApp — דורש אישור מוקדם של Meta. Send-WhatsApp-Message עם getTemplates: true מציג את המאושרות.
  • מחיקת פעולה דורשת actionData — גם עם deleteAction: true, ובלעדיו Cannot read properties of undefined. שלחו מינימום שתקף סכימתית.
  • מזהה של טריגר מתוזמן בפורמט אחר — {"value":"69df53414167a73a568f34df"}", ObjectId של MongoDB ולא _id בסגנון Parse. השתמשו בשדה value כ‑triggerId.
  • Get-WhatsApp-Template-Params תלוי בבלוק ה‑example של מטא — הוא לא סופר את ה‑{{N}} בגוף התבנית אלא ממיר את ה‑example. יש example: כל הפרמטרים חוזרים נכון, גם כשיש כמה. אין example: מוחזר אובייקט ריק, גם לתבנית עם פרמטר יחיד. קיבלתם {} — בנו את WATemplateParams.BODY ידנית, ערך לכל {{N}} לפי הסדר.
  • מגבלה ידועה — שרשרת טריגרים מוגבלת ל‑3 רמות. הרביעי נחסם ונרשם ב‑_syslogTriggers עם blocked! trigger step is to deep -3. source trigger: <id>. הסכימה מזהירה מזה במפורש.
  • useQueue קיים ב‑http, sms ו‑server-side-code. לטריגר שעלול לרוץ פעמים רבות בו‑זמנית, הפעילו אותו.

Create-Data, Update-Data ו‑Create-Many מפעילים אירועי create/update, ולכן בדיקה דרך MCP היא בדיקה תקפה: ממשק ו‑API מתנהגים אותו דבר.

לא ירה? יומן הטריגרים:

JSON
Get-Data({ "table": "_syslogTriggers", "order": "-createdAt", "limit": 5,
"keys": ["triggerId", "actionId", "objectIdValue", "error", "event", "createdAt"] })

שורה לכל פעולה, ועוד שורה לטריגר עצמו עם actionId: null. השדות: triggerId, actionId, objectIdValue, error, data, event. אין triggerName; מצליבים מ‑Get-Triggers.

הסיבות החוזרות, לפי סדר: onSetFields לא כולל את השדה שהשתנה · criterias לא תואמים (objectId שגוי, T שגוי) · הטריגר כבוי · oneachupdate: false והוא כבר ירה על הרשומה · עומק שרשרת חורג מ‑3 · הרשומה נכתבה עם skipTriggers: true.


התנהגות שדות על דף כרטיס: הסתרה מותנית, חובה מותנית, נעילה, ערכים קבועים ודינמיים, נוסחאות, הודעות אזהרה, ומילוי מראש מ‑URL.

הכלי מה הוא עושה
Get-Form-Rules קורא את מערך הכללים הנוכחי. תמיד ראשון
Edit-Form-Rules מוסיף / עורך / מוחק כלל אחד. זה הכותב
Set-Form-Rules דורס את כל הכללים בטופס. מוצא אחרון בלבד
JSON
{ "pageId": "<pageId>", "action": "add",
"rule": { "name": "<שם ייחודי>", "conditions": [...], "actions": [...] } }
{ "pageId": "<pageId>", "action": "edit",
"rule": { "name": "<שם קיים>", "conditions": [...], "actions": [...] } }
{ "pageId": "<pageId>", "action": "delete",
"rule": { "name": "<שם קיים>", "conditions": [], "actions": [] } }

edit מחליף לגמרי את התנאים והפעולות של הכלל הנקוב; זה לא מיזוג. delete צריך רק את השם.

JSON
{
"name": "סיבת ביטול חובה כשהסטטוס בוטל",
"conditions": [
{ "field": "StatusId", "equesition": "equalTo",
"value": "abc1234567", "visibleVal": "בוטל", "condOr": false }
],
"actions": [
{ "field": "CancelReason", "action": "required", "value": "" }
]
}

האיות equesition הוא מה שיש בסכימה.

האופרטורים בסכימה של Edit-Form-Rules: equalTo · greaterThan · lessThan · greaterThanOrEqualTo · lessThanOrEqualTo · notEqualTo · containedIn · notContainedIn — וגם שני ערכי ה‑legacy equealTo ו‑empty.

שמונה הפעולות בסכימה: readonly · required · hidden · fixed-value · dynamic-value · formula-value · show-message · value-from-url.

AND הוא ברירת המחדל. OR דורש condOr: true על שני תנאים לפחות. conditions: [] פירושו שהכלל רץ תמיד — הניב של שיקוף שדות, אבל fixed-value תמידי בטעות דורס קלט של המשתמש בכל טעינת טופס.

הבקשה סקיצת הכלל
“שדה חובה רק כשסטטוס = X” זוג כללים: hidden כשהסטטוס notEqualTo X, ו‑required כשהוא equalTo X
“תסתיר את השדות עד שנבחר סוג” פעולות hidden (אחת לכל שדה) כל עוד שדה הסוג notEqualTo הערך המשחרר
“תנעל את הכרטיס אחרי סגירה” קבוצת OR של סטטוסי סיום (condOr: true על 2+) ← readonly לכל שדה נעול
“העתק פרטים מהלקוח לטופס” conditions: [] + dynamic-value לכל שדה ("AccountId.Email" — קפיצת Pointer אחת)
“תאריך סיום אוטומטי בסגירה” סטטוס equalTo סגור ← fixed-value בערך "today"
“חובה רק עבור סוגים מסוימים” containedIn עם מערך של objectIds ← required
“הצג אזהרה במצב רגיש” תנאי על המצב ← show-message עם טקסט ההודעה
“אחראי ברירת מחדל = המשתמש” conditions: [] + fixed-value בערך "currentUser" על ה‑Pointer ל‑_User
“קישור שממלא שדות מראש” פעולת value-from-url
הבקשה לאן היא שייכת
פעולה בשמירה / מייל / יצירת רשומה / אכיפה בשרת myb-p-trigger-setup
הוספה/הזזה של שדות, סקשנים, טאבים myb-p-card-design
מי רשאי לקרוא או לכתוב (CLP, תפקידים) myb-p-users-roles-permissions
עמודות בטבלה, סינון, צביעת שורות myb-p-page-tables
סינון אפשרויות בדרופ‑דאון לפי שדה אחר myb-p-parent-child-fields — לא פעולת כלל, מנגנון ילידי
0. Get-Site-Pages → איתור דף הכרטיס (יחיד = טופס, רבים = רשימה, Mobile-* = נייד)
1. Get-Form-Rules(pageId) → גיבוי + ספירת בסיס
Get-Schema(tableName) → שמות וטיפוסי שדות מדויקים
Get-Data(<lookup>) → objectIds לערכי תנאי מסוג Pointer
2. ניסוח הכלל
3. הצגת תוכנית ואישור — לפני הכתיבה הראשונה
4. Edit-Form-Rules — קריאה אחת לכל כלל
5. Get-Form-Rules — קריאה חוזרת + בדיקת התנהגות בדפדפן

formId מוגדר כברירת מחדל לטופס הראשון בדף. יותר מטופס אחד? העבירו formId במפורש — ה‑id של אלמנט ה‑<form> כפי שהוא מופיע ב‑Get-Page-Content(minimal: true) (למשל P268). formId שאינו קיים מחזיר Form not found.

Set-Form-Rules — אם באמת חייבים

Section titled “Set-Form-Rules — אם באמת חייבים”

כותב‑מצב‑מלא: כתיבה עיוורת מוחקת כל כלל שלא כללתם.

1. backup = Get-Form-Rules(pageId) // לשמור את ה-JSON המלא בצד
2. newRules = backup.rules ± השינויים // למזג, אף פעם לא לכתוב מהזיכרון
3. Set-Form-Rules(pageId, rules: newRules)
4. Get-Form-Rules(pageId) // לוודא ששום דבר לא אבד

Get-Form-Rules מוכיח אחסון, לא התנהגות: הכללים רצים בדפדפן בלבד ואין יומן שרת של הערכת כללים. פתחו את הדף, רענון קשה (Ctrl+F5) (הגדרות הכללים נטענות עם הדף), הפכו את שדה התנאי, וראו את הפעולה נכנסת ויוצאת.

לא ירה? בסדר הזה: דף שגוי (רגיל מול Mobile-*) · formId שגוי · לא היה רענון קשה · ערך התנאי הוא תווית תצוגה במקום objectId · condOr בודד · כלל אחר פועל על אותו שדה · ציפייה שהכלל יירה על כתיבת API.

  • צד לקוח בלבד — required/readonly/hidden הם חוויה, לא שלמות נתונים.
  • שכפול לפי דף וטופס — נפרדים בשקט.
  • אין כללים מותנים לפי תפקיד — לתנאי יש רק field/equesition/value. התנהגות לפי קהל דורשת הגדרות תפקיד ברמת הדף, או דפים נפרדים.
  • אין סדר עדיפויות בין כללים על אותו שדה; הפעולות מצטברות (hidden בכלל אחד ו‑required באחר על אותו שדה → השדה מוסתר וגם חובה, בשני הסדרים, והטופס לא ניתן לשליחה). תכננו תנאים בלעדיים הדדית.
  • formula-value הוא קופסה שחורה — התחביר לא מתועד בסכימה. המהלך הבטוח היחיד הוא העתקה מכלל חי שעובד.
  • fixed-value על צ’קבוקס: הערך שמסמן הוא "checked"; "checkbox" ו‑"true" לא עושים דבר.
  • dynamic-value — קפיצת Pointer אחת בלבד: "OwnerId.email" ו‑"SubDeptId.Name" עובדים; שתי קפיצות ("SubDeptId.DeptId.Name") מחזירות את ה‑objectId של ה‑Pointer הביניים, לא את השם.

מנגנון ה‑SLA של מודול הפניות בנוי משבעה חלקים שכולם חייבים להיות מוגדרים. חסר אחד, והמערכת נראית מוגדרת ולא עושה כלום.

# החלק מה הוא נותן
1 מינוח (_Dictionary) תוויות בעברית לשדות ה‑SLA
2 מצבי פנייה (CaseStates + CaseStatuses.StateId) קיבוץ סטטוסים לפתוח / סגור (במערכת חדשה קיימים שני אלה בלבד; “מושהה” מוסיפים ביישום). השעון רץ רק במצב “פתוח”
3 שעות עבודה (BusinessHours) חלון שבוע העבודה + חגי ישראל + תאריכים מיוחדים
4 יעדים (SLASettings) היעד עצמו, בשעות או בימים, לפי סוג / סוג+תת‑סוג / סוג+תת‑סוג+סטטוס
5 טריגרים שממלאים את שדות ה‑SLA SLADeadline, ResponseTime, ResolutionTime
6 טבלת מעקב + ווידג’ט (CaseSLAProcess) שורה לכל סטטוס — היסטוריית השעון על כרטיס הפנייה
7 הסלמה (טריגרים מתוזמנים + דוחות) התראות לפני/אחרי חריגה, ודוחות שחושפים חריגות

מה שואלים את הלקוח לפני שמתחילים

Section titled “מה שואלים את הלקוח לפני שמתחילים”
  1. גרנולריות — היעד תלוי רק ב‑CaseType? ב‑CaseType + SubType? או גם בסטטוס?
  2. ימים או שעות — SLADays או SLAHours. אחד לכל שורה, לא שניהם.
  3. חלון העבודה — חלון שבועי יחיד + חגי ישראל + תאריכים חריגים. מקבילים אינם נתמכים.
  4. מיפוי סטטוסים — סטטוסי “סגור”/“מושהה” ממופים ל‑CaseStates שאינם “פתוח”?
  5. מדיניות הסלמה — מי מקבל התראה ומתי (למשל שעתיים לפני היעד; בחריגה). התבנית הדיפולטיבית מתריעה ל‑OwnerId; ל“מנהל” צריך objectId ספציפי או תפקיד.
  6. עומק חישוב ימי העסקים — התבנית הפשוטה מוסיפה ימים קלנדריים. חישוב ימי עסקים אמיתי (דילוג על סופי שבוע וחגי ישראל) דורש server-side-code. אשרו שקלנדרי מספיק ל‑v1, או ערבו מפתח.
# השלב קובץ הייחוס בסקיל
1 אימות תנאים מקדימים — CaseTypes/CaseSubTypes/CaseStatuses/CaseStates מלאים, וכל סטטוס עם StateId prerequisites.md
2 תרגומי _Dictionary לכל השדות dictionary-setup.md
3 שורת BusinessHours יחידה business-hours.md
4 שורה אחת ב‑SLASettings לכל כלל sla-settings.md
5 שלושת טריגרי המילוי sla-triggers.md
6 טבלת CaseSLAProcess + שני טריגרים + ווידג’ט על הכרטיס case-sla-process-table.md
7 שני טריגרים מתוזמנים — אזהרה וחריגה escalation-triggers.md
8 שלושת הדוחות הסטנדרטיים sla-reports.md
9 אימות על פנייה אמיתית verify-and-troubleshoot.md

שלושת הדוחות: דוח SLA — כללי (כל הפניות עם כל השדות) · חריגות פניות פתוחות (IsClosed = false, ממוין לפי SLADeadline עולה) · חריגות פניות סגורות (IsClosed = true, ממוין לפי ResolutionTime יורד).

איך יודעים אם פנייה עמדה ב‑SLA

Section titled “איך יודעים אם פנייה עמדה ב‑SLA”
התנאי על שורת הפנייה המשמעות
ResponseTime קיים ו‑ResponseTime <= SLADeadline עמדה — המענה הראשון הגיע לפני היעד
ResponseTime קיים ו‑ResponseTime > SLADeadline חריגה — המענה הגיע, באיחור
ResponseTime ריק, SLADeadline < now, IsClosed = false בחריגה כרגע
ResponseTime ריק ו‑SLADeadline >= now בתוך התקציב

התצוגה לפי סטטוס מגיעה מ‑CaseSLAProcess: לכל שורה StatusEnteredAt, StatusExitedAt, DeadlineForStatus ודגל IsBreached.

Get-Data(table: "SLASettings", limit: 100)
Get-Data(table: "BusinessHours", limit: 5)
Get-Data(table: "CaseStates", limit: 20)
Get-Data(table: "CaseStatuses", keys: ["Name", "StateId"], limit: 50)
Get-Triggers(tableName: "Cases")
Get-Schema(className: "CaseSLAProcess")
Get-Reports()
Count-Data(table: "Cases", where: { "SLADeadline": { "$exists": true } })
Count-Data(table: "CaseSLAProcess")

התרחיש החוזר: ללקוח “יש SLA” כי דפי הניהול קיימים ול‑SLASettings יש שורות, אבל Count-Data על פניות עם SLADeadline מחזיר 0 — הטריגרים חסרים.

הבקשה התשובה
“טבלת היסטוריית SLA על כרטיס הפנייה” CaseSLAProcess — שלב 6
“SLA של 4 שעות לפניות VIP” שורה ב‑SLASettings עם SLAHours = 4 ו‑CaseTypeId תואם + ודאו שטריגר שלב 5 מכסה את הסוג
“SLA לא ירוץ בסופי שבוע וחגים” זה ב‑BusinessHours — אבל הטריגר הפשוט createdAt + N ימים לא מתייעץ איתו. דילוג על סופי שבוע דורש server-side-code
“הפנייה סגורה אבל ה‑SLADeadline עדיין מוצג כחורג” SLADeadline הוא ערך מחושב סטטי; הוא לא “מתנקה” בסגירה. הדוחות מסננים לפי IsClosed
“התראות למנהל במקום לאחראי” בטריגרי שלב 7, userType מ‑field/OwnerId ל‑fixed/<objectId של המנהל>
  • המנוע לא רץ מעצמו.
  • קלנדרי מול ימי עסקים — התבנית הפשוטה מוסיפה ימים קלנדריים.
  • קדימות גרנולריות — כללים עם יותר Pointers ספציפיים יותר. קדימות מלאה דורשת server-side-code; הטריגר הפשוט עם timeGap משתמש בערך קבוע אחד.
  • חלון שעות עבודה אחד בלבד. אל תמדלו שתי משמרות כשתי שורות.
  • לא לקבוע גם SLAHours וגם SLADays באותה שורה.

בוטים ב‑MyChat — בנייה, עריכה, תיקון ואימות של צ’אטבוטים, כולל בוט וואטסאפ וצמתי סוכן AI, דרך כלי ה‑MCP וגם בעורך הוויזואלי בדפדפן.

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

טריגרים: “צור צ’אטבוט”, “בוט וואטסאפ”, “סוכן AI בצ’אטבוט”, “תקן מפת בוט”. לטריגרים רגילים — myb-p-trigger-setup.