דלג לתוכן הראשי

מאפייני משתמש מותאמים

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

מה הם מאפייני משתמש?​

מאפיינים הם זוגות מפתח־ערך שמצורפים לפרופיל משתמש:

{
"userId": "user_123",
"email": "[email protected]",
"attributes": {
"firstName": "John",
"lastName": "Doe",
"plan": "premium",
"signupDate": "2024-01-15",
"totalPurchases": 5,
"lastLoginDate": "2024-01-20",
"preferences": {
"newsletter": true,
"notifications": "email"
}
}
}

הגדרת מאפיינים​

דרך SDK (צד הלקוח)​

import JoryioSDK from '@joryio/web-sdk';

const joryio = new JoryioSDK({ sdkKey: 'jry_sdk_web_...' });

// Identify a user
joryio.identify('user_123');

// Set attributes separately
joryio.setAttributes({
firstName: 'John',
lastName: 'Doe',
plan: 'premium',
signupDate: '2024-01-15'
});

// Update attributes later
joryio.setAttributes({
plan: 'enterprise',
lastUpgrade: new Date().toISOString()
});

דרך API (צד השרת)​

// Create or update user with attributes
fetch('https://api-eu1.joryio.com/api/users/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer jry_live_your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
attributes: {
externalId: 'user_123',
attributes: {
firstName: 'John',
plan: 'premium',
totalOrders: 10,
lifetimeValue: 1250.00
}
}
})
});

מאפיינים סטנדרטיים לעומת מותאמים​

מאפיינים סטנדרטיים​

שלחו מספרי טלפון עם + וקידומת מדינה

שלחו תמיד מספרי טלפון בפורמט בינלאומי מלא (E.164): +, קידומת המדינה ואז המספר - למשל +972501234567. מספר בלי + נקרא לפי מדינת ברירת המחדל למספרי טלפון של סביבת העבודה; אם לא הוגדרה, או שאפשר לקרוא את הספרות בשתי דרכים, הוא נשמר כלא מאומת ולא משמש להודעות. איך מטופלים מספרי טלפון

שמורים על ידי Joryio (נשמרים בשורש):

  • userId - מזהה משתמש ייחודי
  • email - כתובת אימייל
  • phone - מספר טלפון
  • externalId - מזהה במערכת חיצונית
  • createdAt - זמן יצירת משתמש
  • updatedAt - זמן עדכון אחרון

מאפיינים מותאמים​

כל מאפיין אחר שתגדירו (נשמר באובייקט attributes):

  • firstName, lastName, name
  • plan, subscription Tier
  • company, industry, jobTitle
  • totalPurchases, lifetimeValue
  • preferences, settings
  • וכל דבר נוסף שאתם צריכים!

סוגי נתונים​

מאפיינים תומכים בסוגי נתונים מרובים:

מחרוזת (String)​

{
firstName: "John",
plan: "premium",
country: "US"
}

מספר (Number)​

{
age: 30,
totalPurchases: 15,
lifetimeValue: 1250.50
}

בוליאני (Boolean)​

{
emailVerified: true,
newsletter: false,
isPremium: true
}

תאריך/חותמת זמן​

{
signupDate: "2024-01-15",
lastLoginDate: "2024-01-20T10:30:00Z",
trialEndsAt: "2024-02-15T23:59:59Z"
}
השתמשו בפורמט ISO 8601

לתאריכים, השתמשו בפורמט ISO 8601: YYYY-MM-DDTHH:mm:ssZ

מערך (Array)​

{
tags: ["vip", "early-adopter"],
interests: ["technology", "sports", "music"],
purchasedProducts: ["product_1", "product_2"]
}

אובייקט/מקונן​

{
preferences: {
theme: "dark",
language: "en",
notifications: {
email: true,
sms: false,
push: true
}
},
address: {
street: "123 Main St",
city: "San Francisco",
state: "CA",
zip: "94102"
}
}

כיצד נקבע הסוג​

Joryio לעולם לא מנחשת לפי השם של השדה. הסוג נקבע לפי הסדר הזה:

  1. הוגדר - מישהו קבע את הסוג בעמוד המאפיינים (או בעמוד האירועים, עבור מאפייני אירוע). זה תמיד גובר.
  2. שדה מסחר סטנדרטי - price, total, revenue, quantity, tax, shipping, discount, subtotal ו-value מטופלים כמספרים כברירת מחדל, בין אם שלחתם 12.34 או "12.34". מזהים כמו order_id ו-sku אינם ברשימה הזו במכוון: הם נראים לעיתים קרובות כמספרים, וקביעתם כמספר היא הסיבה שהזמנה כמו 007 מפסיקה להתאים.
  3. הוסק מהנתונים שלכם - הסוג הנפוץ ביותר בדגימה, לכל אירוע בנפרד. Product Added.step ו-Onboarding Step Tapped.step מקבלים סוג נפרד, כך ששם שחוזר לשני דברים שונים אינו התנגשות.

כשהערכים לא מסכימים​

אם יותר מכ-20% מהערכים הם מסוג אחר, המאפיין מוצג כ-מעורב יחד עם הספירות (למשל string 994 - number 448). Joryio לא בוחרת צד. היא משווה את הערכים כטקסט - מה שלעולם לא נותן תשובה שגויה, רק גסה - ומבקשת מכם לקבוע את הסוג.

קביעת הסוג מתקנת את ההשוואה גם עבור ערכים שכבר נשמרו: שדה שהוגדר כמספר משווה "12.34" ו-12.34 כאותו מספר, כך ש-price > 100 מפסיק להשוות טקסט (שבו "90" > "100" הוא אמת).

הערה

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

מה עולה קביעת סוג​

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

נניח ש-step מכיל את המספרים 1, 2, 3 ברוב האירועים ואת המילים "invite" ו-"photo" בחלקם, ואתם קובעים אותו כמספר:

מסנןאיש קשר שה-step שלו הוא "invite"
step > 1לא תואם
step <= 1לא תואם
step = 1לא תואם
step שונה מ-1תואם
step קייםתואם

כך ששתי שכבות שנועדו לחלק את הקהל לשניים - step > 1 ו-step <= 1 - משאירות את אנשי הקשר האלה באף אחת מהן. בדיקת פיצול שנבנתה כך מאבדת אותם בשקט.

מספרים שנכתבו כטקסט תקינים: "12.34" נקרא כ-12.34 ומתאים כרגיל. רק ערכים שאין להם קריאה כסוג שנבחר מושפעים.

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

שדות סטנדרטיים מקבלים סוג אוטומטית​

לחלק מהשדות יש משמעות שאנחנו מגדירים ולא אתם בוחרים, והסוג שלהם קבוע:

  • מאפייני פלטפורמה שהמערכת כותבת - lastEventTime (תאריך, גם אם הוא נשמר כטקסט), total_purchases, ml_churn_score, is_purchase_overdue.
  • מאפייני מסחר סטנדרטיים - price, total, revenue, quantity, tax, shipping, discount, subtotal, value.

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

אם אחד מהשמות האלה אומר משהו אחר בנתונים שלכם, שלחו אותו בשם אחר. price שהוא בעצם תווית צריך להיות price_label. כל מה שמחוץ לרשימות האלה נתון לקביעתכם.

דוגמאות נפוצות למאפיינים​

מסחר אלקטרוני​

joryio.setAttributes({
// Account info
accountType: "premium",
memberSince: "2024-01-15",

// Purchase history
totalOrders: 15,
lastOrderDate: "2024-01-20",
lifetimeValue: 2500.00,
avgOrderValue: 166.67,

// Preferences
favoriteCategory: "electronics",
preferredShipping: "express",

// Engagement
cartAbandoned: false,
wishlistItems: 5,
reviewsWritten: 3
});

SaaS​

joryio.setAttributes({
// Subscription
plan: "pro",
billingCycle: "monthly",
subscriptionStatus: "active",
trialEndsAt: "2024-02-15T23:59:59Z",
mrr: 99,

// Usage
loginCount: 45,
lastLoginDate: "2024-01-20",
featuresUsed: ["export", "api", "integrations"],
apiCallsThisMonth: 10500,
storageUsedGB: 15.5,

// Team
teamSize: 8,
role: "admin",
companyName: "Acme Corp"
});

מדיה/תוכן​

joryio.setAttributes({
// Subscription
subscriptionTier: "premium",
contentAccessLevel: "unlimited",

// Engagement
articlesRead: 125,
videosWatched: 45,
podcastsListened: 30,
favoriteTopics: ["technology", "business"],

// Behavior
avgSessionDuration: 25.5,
lastVisit: "2024-01-20T14:30:00Z",
deviceType: "mobile"
});

עדכון מאפיינים​

מיזוג לעומת החלפה​

מיזוג (ברירת מחדל) - מעדכן שדות שצוינו:

// Initial attributes
{
firstName: "John",
plan: "free",
country: "US"
}

// Update attributes (merges with existing)
joryio.setAttributes({
plan: "premium"
});

// Result (plan updated, others preserved)
{
firstName: "John",
plan: "premium", // Updated
country: "US" // Preserved
}
מאפיינים מתמזגים

קריאה ל־setAttributes() ממזגת מאפיינים חדשים עם קיימים. מאפיינים שלא צוינו נשמרים.

הגדלה/הפחתה​

עבור מונים, הגדילו במקום לאחזר את הערך הנוכחי:

// Bad: Race condition possible
const current = await getUserAttribute('loginCount');
joryio.setAttributes({ loginCount: current + 1 });

// Good: Atomic increment
joryio.incrementAttribute('loginCount', 1);

// Decrement
joryio.incrementAttribute('creditsRemaining', -10);

מאפייני מערך​

אפשר לשמור ולתפעל מערכים כערכי מאפיינים:

// Set array attribute
joryio.setAttributes({
tags: ['vip', 'early-adopter'],
interests: ['technology', 'sports']
});

// Add to array (only adds if value doesn't already exist)
joryio.addToArray('tags', 'premium');
// Result: ['vip', 'early-adopter', 'premium']

// Add duplicate (no-op, prevents duplicates)
joryio.addToArray('tags', 'vip');
// Result: ['vip', 'early-adopter', 'premium'] (unchanged)

// Remove from array
joryio.removeFromArray('tags', 'early-adopter');
// Result: ['vip', 'premium']

פרטי השיטות:

שיטהתיאור
addToArray(key, value)מוסיף ערך למערך אם הוא לא קיים (מונע כפילויות). יוצר מערך חדש אם המאפיין לא קיים.
removeFromArray(key, value)מסיר את כל המופעים של הערך מהמערך. מזהיר אם המאפיין אינו מערך.
מקרי שימוש

מאפייני מערך מתאימים ל:

  • תגיות משתמשים: ['vip', 'trial', 'beta-tester']
  • תחומי עניין: ['sports', 'technology', 'fashion']
  • מוצרים שנרכשו: ['prod_123', 'prod_456']
  • דגלי יכולות: ['feature-a', 'feature-b']
  • תפקידים: ['admin', 'editor']

שימוש במאפיינים לסגמנטציה​

צרו סגמנטים לפי מאפיינים:

מסנן מאפיין פשוט​

plan equals "premium"

השוואה מספרית​

lifetimeValue >= 1000
totalPurchases > 5
age between 25 and 45

מסננים לפי תאריך​

signupDate is within last 30 days
trialEndsAt is within next 7 days
lastLoginDate is more than 14 days ago

התאמת מחרוזות​

email contains "@company.com"
country equals "US"
firstName exists
plan is not "free"

מסנני מערך​

tags contains "vip"
interests contains any of ["technology", "business"]

התאמה אישית של הודעות​

השתמשו במאפיינים בתוכן קמפיינים:

התאמה אישית למייל​

Hi {{firstName}},

Your {{plan}} plan includes these benefits:
...

{{#if trialEndsAt}}
Your trial ends on {{trialEndsAt}}. Upgrade now!
{{/if}}

תוכן דינמי​

{{#if plan == "free"}}
<p>Upgrade to Premium for more features!</p>
{{else}}
<p>Thanks for being a {{plan}} member!</p>
{{/if}}

בלוקים מותנים​

{{#if totalPurchases > 10}}
<div class="vip-offer">
As a valued customer, here's an exclusive offer...
</div>
{{/if}}

שיטות עבודה מומלצות למאפיינים​

1. השתמשו בשמות תיאוריים​

טוב:

{
subscriptionTier: "premium",
lifetimeValueUSD: 1250.00,
emailVerified: true
}

לא טוב:

{
sub: "p",
ltv: 1250,
verified: 1
}

2. היו עקביים​

השתמשו באותה מוסכמה לשמות:

טוב (camelCase):

{
firstName: "John",
lastName: "Doe",
signupDate: "2024-01-15"
}

לא טוב (מעורב):

{
first_name: "John",
LastName: "Doe",
"signup-date": "2024-01-15"
}

3. השתמשו בסוגים מתאימים​

טוב:

{
age: 30, // Number
isPremium: true, // Boolean
signupDate: "2024-01-15", // ISO Date String
tags: ["vip", "beta"] // Array
}

לא טוב:

{
age: "30", // String instead of number
isPremium: "true", // String instead of boolean
signupDate: 1705276800, // Timestamp instead of ISO
tags: "vip,beta" // String instead of array
}

4. אל תשמרו נתונים רגישים​

לעולם אל תשמרו:

  • סיסמאות או גיבובי סיסמאות
  • מספרי כרטיס אשראי מלאים
  • מספרי תעודת זהות
  • פרטי בנק
  • מידע רפואי

מותר לשמור:

  • 4 ספרות אחרונות של כרטיס
  • סוג אמצעי תשלום ("visa", "mastercard")
  • טוקנים מוצפנים/מגובבים
  • מידע פרופיל ציבורי

5. שמרו על שמות קצרים​

טוב: plan, ltv, mrr לא טוב: currentSubscriptionPlanTierLevel

שמות מאפיינים שמורים​

הימנעו משימוש בשמות השמורים הבאים:

  • userId, user_id, id
  • email
  • phone
  • createdAt, created_at
  • updatedAt, updated_at
  • $app_id, $platform (עם קידומת $)

עדכונים בכמות גדולה​

עדכנו מאפיינים למספר משתמשים בבת אחת:

// API: Bulk update - each field of POST /users/track accepts an array (attributes: max 1000)
POST /users/track
{
"attributes": [
{
"externalId": "user_1",
"attributes": { "plan": "premium" }
},
{
"externalId": "user_2",
"attributes": { "plan": "enterprise" }
}
]
}

מגבלות מאפיינים​

מגבלהערך
מקסימום מאפיינים למשתמש200
אורך מקסימלי לשם מאפיין100 תווים
אורך מקסימלי לערך מחרוזת10,000 תווים
אורך מקסימלי למערך100 פריטים
עומק קינון מקסימלי5 רמות

פתרון בעיות​

מאפיינים לא מופיעים​

  1. בדקו את איות שם המאפיין
  2. ודאו שהמשתמש עבר identify
  3. הפעילו מצב debug כדי לראות את קריאות ה-API
  4. בדקו שגיאות API בתגובה

מאפיין לא מתעדכן​

  1. ודאו שאתם משתמשים במיזוג (לא בהחלפה)
  2. בדקו שסוג הנתונים תואם
  3. ודאו ששם המאפיין נכון
  4. בדקו את מגבלות הקצב (rate limits)

סגמנטציה לא עובדת​

  1. ודאו שהמאפיין קיים אצל המשתמשים
  2. בדקו את סוג הנתונים של המאפיין
  3. בדקו את לוגיקת המסנן על משתמשים מוכרים
  4. ודאו שערכי המאפיין תואמים למסנן במדויק

השלבים הבאים​