מעקב אחר אירועים
אירועים הם חומר הגלם של כל דבר ב-Joryio: סגמנטים, טריגרים של מסעות, מסנני קמפיינים ואנליטיקה - כולם פועלים על האירועים שהאפליקציות שלכם שולחות. מדריך זה מרכז את המוסכמות והמנגנונים המשותפים לכל ה-SDKs - Web, iOS, Android ו-React Native. להתקנה ולהגדרות ספציפיות לפלטפורמה, ראו את דפי ה-SDK הנפרדים.
איך המעקב עובד
כל SDK עוקב אחרי אותו מסלול:
- אתם קוראים ל-
track(eventName, properties)באפליקציה. - ה-SDK מוסיף את האירוע לתור מקומי (עם שמירה למצב לא-מקוון) ושולח אותו באצוות - כברירת מחדל כל 5 שניות או כל 50 אירועים, המוקדם מביניהם.
- האצווה נשלחת אל
POST /v1/track/batch, עם אימות באמצעות מפתח ה-SDK של האפליקציה (בפורמטjry_sdk_<platform>_<random>, מפתח אחד לכל אפליקציה - ראו סקירת אפליקציות). - השרת מזהה את המשתמש (אנונימי או מזוהה), שומר את האירועים ומפיץ אותם לסגמנטים, לטריגרים של מסעות ולאנליטיקה.
אצווה יכולה להכיל עד 500 אירועים. חותמת הזמן נקבעת על ידי ה-SDK בזמן הקריאה; השרת מקבל epoch במילישניות או מחרוזת ISO-8601, ומשתמש בזמן השרת אם חותמת הזמן חסרה או לא תקינה (כך ששעון מכשיר שגוי לעולם לא גורם לדחיית אירוע). כל ה-SDKs שולחים אותה ב-UTC בדיוק של מילישניות (ISO-8601 כמו 2026-10-07T09:15:02.123Z, או epoch במילישניות), כך ששתי קריאות באותה שנייה שומרות על הסדר שלהן.
Sessions
session מתחיל רק דרך מחזור החיים הרגיל של ה-SDK - כשהאפליקציה עוברת לחזית, או בטעינת עמוד ב-web - ותמיד שולח אירוע Session Start. קריאת ה-session (המזהה או הפרטים שלו) וסנכרון הודעות In-App הם ללא תופעות לוואי: הם לעולם לא מתחילים session ולא מאריכים אותו, כך שבדיקת ה-session מהקוד שלכם לא יכולה ליצור sessions בלי Session Start.
מוסכמות שמות לאירועים
שם אירוע הוא מחרוזת של עד 255 תווים. מעבר לכך, Joryio לא כופה פורמט - אבל עקביות חשובה, כי שמות האירועים הם הדרך שבה תמצאו אירועים אחר כך בבניית סגמנטים, בטריגרים של מסעות וב-Event Explorer.
המלצות:
- השתמשו ב-Title Case עם רווחים. האירועים המובנים של Joryio עוקבים אחר טקסונומיית אירועי המסחר המקובלת בתעשייה (עצם + פועל בזמן עבר, Title Case):
Product Viewed, Product Added, Checkout Started, Order Completedמאינטגרציות החנות, כך ששמות Title Case לאירועים מותאמים (Trial Started, Signup Completed) שומרים על קטלוג אחיד. גם snake case עובד - אבל בחרו מוסכמה אחת והיצמדו אליה; ערבוב יוצר אירועים שנראים כפולים. - תנו שם לפעולה, לא לממשק.
Order Completedישרוד עיצוב מחדש;Green Button Clickedלא. - השתמשו בעצם + פועל בזמן עבר.
Subscription Upgraded,Video Played,Search Performed. - שמרו את השונות במאפיינים, לא בשמות. אירוע
Product Viewedאחד עם מאפייןcategoryעדיף על חמישים אירועיViewed <Category>- סגמנטים וטריגרים מתאימים קודם לפי שם האירוע ורק אחר כך מסננים לפי מאפיינים. - הימנעו מאירועים כלליים מדי.
Clickedבלי מאפיינים לא אומר לכם שום דבר שאפשר לפעול לפיו.
שמות אירועים רגישים לאותיות גדולות/קטנות: order_placed ו-Order_Placed הם שני אירועים שונים.
שמות אירועים שמתחילים ב-canvas., ב-message. או ב-in_app. (בכל צורת אותיות) שמורים לאירועי המסע וההודעות של Joryio עצמה, ואירוע שאתם שולחים בשם כזה נדחה - ראו שמות אירועים שמורים.
מאפיינים וסוגי נתונים
מאפיינים הם אובייקט JSON שמצורף לכל אירוע. כל ערך JSON תקין מתקבל:
| סוג | דוגמה | הערות |
|---|---|---|
| מחרוזת | "currency": "USD" | השתמשו בה גם לתאריכים, כמחרוזות ISO-8601 |
| מספר | "total": 149.99 | מספרים שלמים ועשרוניים |
| בוליאני | "first_order": true | |
| מערך | "item_ids": ["SKU-1", "SKU-2"] | |
| אובייקט | "shipping": { "method": "express" } | מותר קינון של אובייקטים |
מגבלות בצד השרת לכל אירוע:
| מגבלה | ערך |
|---|---|
| אורך שם האירוע | 255 תווים |
| גודל כולל של המאפיינים (JSON מסודר) | 50 KB |
| מספר מפתחות ברמה העליונה | 200 |
| עומק קינון | 5 רמות |
| אירועים בבקשת אצווה אחת | 500 |
הגודל הוא אורך המאפיינים כ-JSON מסודר, בתווים (51,200), ועומק הקינון סופר את אובייקט המאפיינים עצמו כרמה 1. המגבלות חלות על המאפיינים שהאפליקציה שולחת - מאפייני ה-$ שהשרת מוסיף לא נספרים בהן. אירוע שחורג ממגבלה, או ששמו ריק או ארוך מדי, נדחה לצמיתות: תשובת האצווה מפרטת אותו ב-rejectedIndices (ראו תשובות לאצוות) ושאר האצווה נשמרת. ה-SDK-ים בודקים את אותן מגבלות כשקוראים ל-track() ומשליכים אירוע כזה כבר שם, עם שורת לוג.
אירועים שחורגים מהמגבלות נדחים. לשמות מאפיינים חלה אותה עצה כמו לשמות אירועים: בחרו מוסכמה (product_id, לא לפעמים productId) ושמרו על סוגים יציבים - order_id שהוא מחרוזת באירוע אחד ומספר באירוע אחר הופך את הסינון ללא אמין.
NaN, Infinity ו--Infinity אינם מספרי JSON. כל SDK משמיט מאפיין או מאפיין משתמש שהערך שלו הוא אחד מהם כבר בזמן הקריאה, רושם אזהרה ושולח את שאר הקריאה בלי המפתח הזה - שום דבר לא נזרק לקוד שלכם, שום דבר לא נשמר במכשיר, וערך שגוי אחד לעולם לא מעכב כתיבות אחרות. אותו כלל חל על המאפיינים המותאמים של ה-trackers למסחר אלקטרוני. ב-web, ערך של מאפיין משתמש שאי אפשר לבצע לו serialization (אובייקט מעגלי, BigInt, פונקציה) מושמט באותה דרך.
מאפיינים עם קידומת $ (כמו $platform, $session_id, $app_id) מתווספים אוטומטית - חלקם על ידי ה-SDKs ($device_id, נתוני מכשיר ב-Session Start) וחלקם על ידי צינור הקליטה של Joryio בעת קבלת האירוע ($app_id, $session_id, $is_identified). התייחסו לקידומת הזו כשמורה ואל תשתמשו בה למאפיינים שלכם.
כללי שמות למאפייני משתמש
למפתחות של מאפיינים (האובייקט שמועבר ל־setAttributes / setAttribute) יש שתי
מגבלות נוספות מעבר לעצות לעיל, ומפתח שמפר אחת מהן נשמט - שאר הקריאה נשמרת כרגיל:
| אסור | הסיבה |
|---|---|
. בכל מקום במפתח | הנקודה נקראת כמפריד נתיב, לא כתו. "profile.email" היה נשמר כמבנה מקונן profile: { email }, ולכן סגמנט על profile.email לא היה מוצא דבר - בלי שום דרך להבין למה. |
$ בתחילת המפתח | שמור, בדיוק כמו במאפייני אירוע למעלה. |
| מפתח ריק | אין מה לשמור. |
המפתחות נשמטים ולא משתנים - בכוונה: שינוי profile.email ל־profile_email היה
מדווח על הצלחה ושומר את הנתונים במקום שלעולם לא תשאילו. המפתחות שנשמטו מופיעים
בלוג של השרת, וה־SDK מתריע עליהם בקונסולה בזמן האינטגרציה.
identify מול track
שלחו תמיד מספרי טלפון בפורמט בינלאומי מלא (E.164): +, קידומת המדינה ואז המספר - למשל +972501234567. מספר בלי + נקרא לפי מדינת ברירת המחדל למספרי טלפון של סביבת העבודה; אם לא הוגדרה, או שאפשר לקרוא את הספרות בשתי דרכים, הוא נשמר כלא מאומת ולא משמש להודעות. איך מטופלים מספרי טלפון
לשתי הקריאות המרכזיות יש תפקידים שונים:
identify(userId)אומר מי המשתמש. הוא קושר את המכשיר/סשן הנוכחי למזהה המשתמש הקבוע שלכם וממזג היסטוריה אנונימית לתוך הפרופיל. מאפיינים שנקבעים עםsetAttributesמתארים את המשתמש (אימייל, תוכנית, שם) ונשמרים בפרופיל.track(eventName, properties)אומר מה קרה. המאפיינים מתארים את האירוע, לא את המשתמש, ואינם ניתנים לשינוי לאחר שנרשמו.
כללי אצבע:
- קראו ל-
identifyמוקדם ככל האפשר - בהתחברות, ובעליית האפליקציה אם סשן משוחזר. השתמשו באותו מזהה משתמש בכל הפלטפורמות כדי שפעילות web ומובייל תנחת על פרופיל אחד (ראו מעקב רב-פלטפורמי). - לפני
identify, אירועים נרשמים תחת מזהה אנונימי. כשאתם מזהים את המשתמש מאוחר יותר, השרת ממזג את ההיסטוריה האנונימית לתוך הפרופיל המזוהה, כך שאירועים מלפני ההרשמה (ביקור ראשון, ייחוס) לא הולכים לאיבוד. - אין קריאה נפרדת
alias(userId):identify(userId)גם מקשר את ההיסטוריה האנונימית וגם נותן שם לאדם. כדי לשמור את המזהים של האדם במערכות אחרות (מזהה CRM, מספר מועדון), השתמשו ב-addAlias(label, name)- זה עובד גם לפני התחברות, והכינויים עוברים לפרופיל המזוהה כשהמבקר מזדהה. - שימו נתונים של המקרה הבודד במאפייני אירוע (
total,coupon), ועובדות קבועות על האדם במאפייני הפרופיל (plan,lifetime_value). - קראו ל-
reset()בהתנתקות כדי שהמשתמש הבא במכשיר לא יירש את הפרופיל.
אותו אירוע בכל SDK
קריאת track זהה בכוונה בצורתה בכל ה-SDKs. הנה אותו אירוע Order Completed בכל ארבע הפלטפורמות.
- Web (JS)
- iOS (Swift)
- Android (Kotlin)
- React Native
import JoryioSDK from '@joryio/web-sdk';
const joryio = new JoryioSDK({ sdkKey: 'jry_sdk_web_...' });
joryio.track('Order Completed', {
orderId: 'ORD-2024-001',
total: 149.99,
currency: 'USD',
item_count: 3,
coupon: 'SAVE10',
});
Joryio.shared.track("Order Completed", properties: [
"orderId": "ORD-2024-001",
"total": 149.99,
"currency": "USD",
"item_count": 3,
"coupon": "SAVE10"
])
Joryio.track("Order Completed", mapOf(
"orderId" to "ORD-2024-001",
"total" to 149.99,
"currency" to "USD",
"item_count" to 3,
"coupon" to "SAVE10"
))
import Joryio from '@joryio/react-native-sdk';
Joryio.track('Order Completed', {
orderId: 'ORD-2024-001',
total: 149.99,
currency: 'USD',
item_count: 3,
coupon: 'SAVE10',
});
מכיוון שהשם והמאפיינים זהים, תנאי סגמנט אחד או טריגר מסע אחד מתאים לאירוע לא משנה מאיזו פלטפורמה הגיע.
לפעילות מסחר אלקטרוני סטנדרטית (צפיות במוצרים, עגלות, checkout, הזמנות) העדיפו את כלי המעקב המובנים למסחר אלקטרוני ב-SDKs - הם שולחים את שמות האירועים המתוקננים שיכולות המסחר האלקטרוני של Joryio מצפות להם. ראו את מדריך מעקב המסחר האלקטרוני המשותף לכל ה-SDKs.
מה קורה בצד השרת
לאחר שאצווה מתקבלת, כל אירוע:
- נשמר במאגר האנליטיקה, מוצמד לפרופיל המשתמש שזוהה (מזוהה או אנונימי).
- נבחן מול טריגרים של מסעות. מסע שטריגר הכניסה שלו תואם את שם האירוע (ואת מסנני המאפיינים) מצרף את המשתמש מיידית - כך מתחילים מסעות "עגלה נטושה" או "ברוכים הבאים".
- מזין סגמנטים. תנאי סגמנט מבוססי-אירוע ("ביצע
Order Completedב-30 הימים האחרונים") מתעדכנים מזרם האירועים, וקמפיינים שמכוונים לסגמנטים האלה קולטים את השינוי. - מופיע באנליטיקה - ב-Event Explorer, במשפכים ובאנליטיקה של כל אפליקציה.
- יכול לעדכן את הפרופיל. לחלק מהאירועים יש השפעות צד שמנוהלות בצד השרת: לדוגמה, אירועי
Session Startמרעננים את רשומת המכשיר של המשתמש ומעדכנים מאפייני פרופיל כמוcountry(הנגזרת מכתובת ה-IP של הבקשה).
שתי התנהגויות בצד השרת שכדאי להכיר:
- סימון בוטים. בקשות מ-user agents של בוטים מוכרים מסומנות (האירועים מתויגים, והאנליטיקה מסננת אותם); קריאות שמשנות פרופיל כמו
identifyו-setAttributesמדולגות עבור בוטים. תעבורה מדפדפנים headless באוטומציית הבדיקות שלכם עשויה לכן לא ליצור פרופילים. - אימות סלחני. שדות נוספים שאינם מוכרים במטען הבקשה מוסרים במקום להידחות, כך שאי-התאמה בגרסת SDK אינה גורמת לאובדן האירועים שלכם.
חוזה השרת לבקשות SDK
לוגיקת התור והניסיונות החוזרים של ה-SDK בנויה על התנהגות השרת שמתוארת כאן. אם אתם קוראים לנקודות הקצה האלה בעצמכם (אינטגרציה מותאמת או proxy), טפלו בתשובות באותו אופן.
תשובות לאצוות
POST /v1/track/batch מקבל עד 500 אירועים וגוף בקשה של עד 1 MB.
| תשובה | משמעות | מה לעשות |
|---|---|---|
200 עם success: true | כל האירועים נשמרו | למחוק את האצווה |
200 עם success: false | חלק מהאירועים או כולם לא נשמרו. שתי רשימות נותנות את המיקומים שלהם (מאפס) באצווה ששלחתם: failedIndices (כשל בצד שלנו) ו-rejectedIndices (נדחו לצמיתות - חריגה מהמגבלות לאירוע או שם לא תקין). partial: true אומר שהשאר נשמרו; failed סופר את שתי הרשימות | לשלוח שוב רק את האירועים שב-failedIndices - שליחה חוזרת של אירוע שכבר נשמר בטוחה, clientEventId מונע כפילות. להשליך את האירועים שב-rejectedIndices: שליחה חוזרת שלהם לעולם לא תצליח |
400 | הגוף נכשל בבדיקת תקינות (למשל יותר מ-500 אירועים, או אירוע פגום) | לא לשלוח שוב כמו שהוא - לפצל את האצווה |
413 | הגוף גדול מ-1 MB | לפצל את האצווה |
401 | מפתח ה-SDK לא תקין או לא פעיל, או (כש-SDK Authentication פעיל) לבקשה שמציינת userId חסר טוקן X-Joryio-Auth, או שהוא פג תוקף או שייך למשתמש אחר - בגוף error: "sdk_authentication_error" ו-reason: missing, expired, invalid או sub_mismatch (הטוקן שייך למשתמש אחר). בקשות אנונימיות לא צריכות טוקן | לרענן את הטוקן ולנסות שוב. לאירועים שממתינים עבור משתמש שכבר לא מחובר אי אפשר להשיג טוקן: בכל reason (missing, expired, invalid או sub_mismatch) להשליך אותם. רק כשלים של המשתמש המחובר כעת מגיעים ל-handler השגיאות של SDK Authentication, כך ששאריות של משתמש קודם אף פעם לא מנתקות את מי שמשתמש באפליקציה עכשיו |
402 עם code: "SDK_INGESTION_SUSPENDED" | קליטת האירועים מושהית בחשבון | להפסיק לשלוח עד סוף ה-session, לשמור את הכתיבות ולא לספור את ה-402 במגבלת הניסיונות שלהן; ביטולים עדיין נשלחים, גם כשהם ממתינים בתור מאחורי כתיבה שנדחתה |
403 | מדיניות הזהות של האפליקציה דחתה את הבקשה: Strict SDK identity דוחה כתיבות אנונימיות (code: "SDK_STRICT_IDENTITY_REQUIRED"), ו-SDK Authentication דוחה anonymousId ששייך למשתמש מזוהה (code: "SDK_ANONYMOUS_ID_IDENTIFIED"). ביטולים הם החריג ל-Strict SDK identity - ראו ביטולים נמסרים תמיד | להפסיק לשלוח עד סוף ה-session |
429 | הגבלת קצב. הכותרת Retry-After נותנת את זמן ההמתנה בשניות (וגם retryAfter בגוף) | להמתין ואז לנסות שוב |
5xx | שגיאת שרת | לנסות שוב עם backoff |
כך נראה כשל חלקי:
{ "success": false, "partial": true, "processed": 47, "failed": 3, "failedIndices": [3, 17], "rejectedIndices": [21], "error": "failed to track: 2 (retry), rejected: 1 (do not retry)" }
תשובות לשאר נתיבי הכתיבה
ל־/v1/identify, /v1/attributes, /v1/alias/add, /v1/subscriptions/channel, /v1/subscriptions/group, /v1/push/register ו־/v1/push/unregister אין תוצאה חלקית, ולכן קוד הסטטוס לבדו אומר מה קרה. רק נתיב האצוות שלמעלה עונה על כשל עם 200.
| תשובה | משמעות | מה לעשות |
|---|---|---|
200 עם success: true | בוצע | לאשר |
400 | הבקשה שגויה כפי שנשלחה - למשל אין userId או anonymousId, אין מאפיינים תקינים, web push בלי subscription, או endpoint שאינו מותר, או רישום push של iOS שהטוקן שלו אינו device token של APNs (למשל טוקן FCM - רשמו טוקנים של FCM ב-Android בלבד) | לא לנסות שוב - לוותר עליה ולרשום ביומן |
401, 402, 403, 429 | כמו בטבלת האצוות למעלה | כמו למעלה |
404 | הרשמות, בשרתים ישנים בלבד: עדיין אין פרופיל עבור ה־userId או ה־anonymousId. השרת הנוכחי יוצר במקום זה את הפרופיל החסר, כמו /v1/alias/add | לנסות שוב אחרי שהאירועים שבתור נשלחו, מספר פעמים מוגבל |
403 עם code: "verified_identity_required" | נקודות קצה של ה-SDK בלבד (/v1/subscriptions/channel, /v1/subscriptions/group): הרשמה מחדש של אדם שביטל במפורש (ביטול שלו או מרשימה, STOP, ביטול על האימייל או הטלפון שלו - גם של איש קשר אחר) מנושא שאינו מאומת - userId בלי SDK Authentication, או anonymousId ששייך לאדם מזוהה. הרשמה ראשונה מתקבלת; רשימה שדורשת אישור כפול עונה pending: true ושולחת את אימייל האישור. הסרה מותרת תמיד | לא לנסות שוב - להפעיל SDK Authentication, או לרשום מחדש מהשרת דרך ה-API |
409 עם code: "ALIAS_TAKEN" | /v1/alias/add בלבד: ה־alias שייך לפרופיל אחר | לא לנסות שוב |
400 עם code: "ALIAS_LABEL_RESERVED" | /v1/alias/add וה־API של aliases: התוויות shopify_customer, woocommerce_customer ו־magento_customer שמורות - אינטגרציית החנות כותבת אותן | לא לנסות שוב |
503 עם code: "SDK_TEMPORARILY_UNAVAILABLE" | כשל בצד שלנו | לשמור את הכתיבה ולנסות שוב עם backoff |
איך ה-SDKs סופרים ניסיונות חוזרים
כל ה-SDKs סופרים ניסיונות כושלים של כתיבה באותה דרך. מצב offline, timeout, 402, 429 ו-5xx לעולם לא נספרים: הכתיבה ממתינה ונשלחת כשהסיבה חולפת. 404 (שרתים ישנים, עדיין אין פרופיל) נספר למגבלה של 5, וכל תשובה אחרת שאפשר לנסות שוב - 401 של המשתמש המחובר, או success: false - נספרת למגבלה של 10, ואחריה מוותרים על הכתיבה. 400, 403, 413 ו-422 גורמים לוויתור עליה מיד.
Aliases למבקרים אנונימיים
POST /v1/alias/add מקבל { "anonymousId", "userId", "aliasLabel", "aliasName" }, כש-userId אופציונלי. בלי userId ה-alias מוצמד לפרופיל האנונימי; כשהמבקר עושה identify, ה-alias עובר לפרופיל המזוהה יחד עם שאר ההיסטוריה האנונימית.
alias (aliasLabel + aliasName) שייך לפרופיל אחד בכל workspace. אם הוא כבר שייך לפרופיל אחר הוא לא מועבר: התשובה היא 409 עם code: "ALIAS_TAKEN", וניסיון חוזר לא יעזור. SDK Authentication פועל כאן כמו בכל מקום: למבקר אנונימי אין token להציג, ולכן addAlias אנונימי מתקבל; ברגע שנשלח userId הוא חייב להיות קשור ל־token, כמו ב־identify. רק Strict SDK identity דוחה כינויים אנונימיים. התוויות shopify_customer, woocommerce_customer ו־magento_customer שמורות: הן מחזיקות את מזהי הלקוח של חנות Shopify, WooCommerce או Magento מחוברת ורק אינטגרציית החנות כותבת אותן, ולכן addAlias עם אחת מהן נדחה עם 400 ו־code: "ALIAS_LABEL_RESERVED".
זהות ומעקב קליקים ב-In-App
/v1/in-app/sync ו-/v1/in-app/track מקבלים userId (אחרי שהמבקר זוהה) ו-anonymousId כשדות נפרדים. השרת מעריך את הפרופיל המזוהה, וכל עוד ה-identify עוד בדרך - את הפרופיל האנונימי. לעולם אל תשימו כתובת אימייל ב-externalId.
action ב-/v1/in-app/track לקוח מאוצר מילים קבוע (displayed, clicked, dismissed, converted וכמה מילים נרדפות); פעולה לא מוכרת לא נרשמת והתשובה אומרת reason: "unknown_action". כדי לתעד על איזה כפתור או קישור לחצו, שלחו את השם שלו ב-elementId (עד 128 תווים) לצד action: "clicked". הוא נשמר על האירוע in_app.clicked, ודוח הקליקים של הקמפיין מקבץ לפיו.
נתיבי מעקב Push
אישורי מסירה של Push (POST /track/push/delivered/<trackingId>) וקליקים (GET /track/push/click/<trackingId>) מוגשים בשורש של שרת ה-API, לא תחת /api. ה-SDK בונים אותם מה-scheme וה-host של נקודת הקצה שהוגדרה. אותם נתיבים עונים גם תחת /api/track/push/..., כך שגרסה שהשאירה את הנתיב /api עדיין מדווחת.
תיעוד ההסרה ממעקב
כשאדם בוחר לצאת מהמעקב (optOut() בכל SDK), ה-SDK כותב בפרופיל את המאפיין tracking_opted_out: true, ו-optIn() מחזיר אותו ל-false. זה מאפיין בוליאני כמו כל מאפיין אחר: אפשר לסנן לפיו בסגמנט ("tracking_opted_out הוא true") כדי להוציא מקהל אנשים שיצאו מהמעקב, או כדי לספור אותם. זה תיעוד של ההחלטה ולא האכיפה שלה - ה-SDK מפסיק לשלוח בעצמו - וגרסאות SDK לפני 1.3.0 שלחו אותו כ-$tracking_opted_out, שהשרת שומר עכשיו תחת אותו מפתח tracking_opted_out.
ביטולים נמסרים תמיד
ארבע כתיבות רק מצמצמות את מה שנאסף או נשלח: הרשמה לערוץ שמוגדרת ל-unsubscribed, unsubscribe מקבוצה, תיעוד ההסרה tracking_opted_out: true ו-/v1/push/unregister. ה-SDKs שומרים אותן בתור ומנסים שוב גם כשהאדם הסיר את עצמו ממעקב, כשהסכמת המעקב נדחתה או ממתינה, ואחרי wipeData(); השרת מקבל אותן באותם מצבים:
- שום בדיקת הסכמה או הסרה ממעקב בשרת לא דוחה אותן - אדם שהסיר את עצמו ממעקב עדיין יכול לבטל הרשמה.
- Strict SDK identity לא דוחה אותן ממבקר אנונימי. רק הכיוון ההפוך - הרשמה,
tracking_opted_out: false, או התיעוד כשהוא נשלח יחד עם מאפיין אחר - עדיין דורש משתמש מזוהה שהטוקן שלו אומת. - חשבון מושהה לא דוחה אותן: בזמן שקליטת האירועים מושהית (
402,SDK_INGESTION_SUSPENDED) השרת עדיין מקבל אותן וה-SDKs ממשיכים לשלוח אותן, כך שה"לא" של אדם נרשם בלי קשר למצב החיוב של החשבון. - גם טוקן שתוקפו פג עובד עבורם. כש-SDK Authentication פעיל, ביטול שמציין
userIdמתקבל עם הטוקן של אותו משתמש עד 30 יום אחרי שתוקף הטוקן פג. החתימה והנושא (sub) נבדקים כמו תמיד; רק תאריך התפוגה מוקל, ורק עבור ארבע הכתיבות האלה - כל השאר דורש טוקן בתוקף. זה מה שמאפשר להתנתק בלי לאבד דבר: כשמשתמש מתנתק (reset()), ה-SDK שומר את הטוקן שלו - מוצפן היכן שלפלטפורמה יש אחסון מאובטח (iOS Keychain, ההעדפות המוצפנות של Android; ב-web, local storage לצד התור) - יחד עם הכתיבות הממתינות שלו, ומוחק אותו כשהאחרונה מהן נמסרה או שוויתרו עליה, כך שביטול מנוי שנלחץ רגע לפני ההתנתקות עדיין מגיע, גם אחרי שהאפליקציה נפתחת מחדש. - התחברות בזמן שהמעקב נדחה:
identify(userId)בזמן שההסכמה נדחתה או שהאדם הסיר את עצמו מהמעקב לא שולח דבר, לא עוקב אחרי דבר ולא כותב פרופיל, אבל ה-SDK שומר את ה-userIdבמכשיר למטרה אחת - ביטול שנעשה אז נושא אותו, כך שהפרופיל של האדם עצמו מוסר מהמנוי ולא פרופיל אנונימי חדש. כשההסכמה ניתנת או שהאדם חוזר למעקב, ה-identifyהרגיל רץ.reset()ו-wipeData()שוכחים אותו. /v1/push/unregisterלא צריך טוקןX-Joryio-Authגם כשהגוף מצייןuserId: מה שמוסר הוא טוקן ה-push או ה-endpoint של web push, כך שמכשיר של משתמש שהתנתק מפסיק לקבל הודעות push גם אחרי שהטוקן שלו נעלם.- הכלל היחיד שעדיין חל: כש-SDK Authentication פעיל,
anonymousIdששייך למשתמש מזוהה לא יכול לבטל את ההסכמה של אותו משתמש בלי הטוקן שלו (403,SDK_ANONYMOUS_ID_IDENTIFIED). כתיבת הרשמה שמציינתuserIdעדיין צריכה את הטוקן של אותו משתמש, כמו בכל מקום.
כשהתור במכשיר מלא, הכתיבה הוותיקה ביותר שאינה ביטול היא הראשונה שמוותרים עליה.
אימות ודיבוג
בדיקה שאירוע הגיע
- הפעילו את האירוע באפליקציה.
- בלוח הבקרה של Joryio, פתחו את Analytics → Event Explorer. סננו לפי שם האירוע - האירוע אמור להופיע שניות לאחר שה-SDK שולח את האצווה (מרווח שליחה ברירת מחדל: 5 שניות).
- לתצוגה לפי אפליקציה, פתחו את Settings → Apps ולחצו על View Analytics באפליקציה - מוצגים סך האירועים, חותמת הזמן של האירוע האחרון ושמות האירועים המובילים, מה שמאשר במהירות אם משהו ממפתח ה-SDK הזה בכלל מגיע.
אם אירועים לא מופיעים
- כפו שליחה מיידית. אירועים נשלחים באצוות; קראו ל-
flush()(זמין בכל SDK) כדי לשלוח מיד במקום לחכות לטיימר. - הפעילו רישום ניפוי שגיאות. בכל SDK יש אפשרות
enableDebugשרושמת כל אירוע שנכנס לתור וכל בקשת רשת עם התשובה שלה. - בדקו את מפתח ה-SDK. הוא חייב להתאים לפלטפורמת האפליקציה -
jry_sdk_web_...ל-Web SDK,jry_sdk_ios_...ל-iOS,jry_sdk_android_...ל-Android. מפתח שנוצר מחדש מבטל את הישן מיידית. ה-SDK של Android (כולל React Native ו-Unity ב-Android) מדווח לשרת על הפלטפורמה שלו, ומפתח של אפליקציה מפלטפורמה אחרת נדחה עם401ו-code: "SDK_KEY_PLATFORM_MISMATCH". - ודאו שהאפליקציה פעילה ב-Settings → Apps - אירועים שנשלחים עם מפתח של אפליקציה מושבתת נדחים.
- עקבו אחרי תשובת הרשת. תשובת אצווה כוללת
success, ובכשל חלקי גםfailedIndices(לא נשמרו, יישלחו שוב) ו-rejectedIndices(נדחו לצמיתות). מאפיינים גדולים מדי (מעל 50 KB, מעל 200 מפתחות, או קינון עמוק מ-5 רמות) הם הסיבה הנפוצה לאירועים שנדחים. - ב-Web בלבד: נקודות הקצה של ה-SDK מאפשרות כל origin (
Access-Control-Allow-Origin: *), כך ששגיאות CORS מעידות בדרך כלל עלapiEndpointשגוי או תוסף דפדפן חוסם - בדקו בקונסול. ודאו גם שהאתר רץ על HTTPS כדי ששמירת התור ב-localStorage תעבוד. - בודקים באמצעות אוטומציה? זכרו את סימון הבוטים למעלה - אמתו עם דפדפן או מכשיר אמיתי.