Παρακολούθηση συμβάντων
Τα συμβάντα είναι η πρώτη ύλη για τα πάντα στο Joryio: τα τμήματα, τα triggers journey, τα φίλτρα καμπάνιας και τα analytics λειτουργούν όλα με τα συμβάντα που στέλνουν οι εφαρμογές σας. Αυτός ο οδηγός καλύπτει τις συμβάσεις και τους μηχανισμούς που μοιράζονται όλα τα SDK - Web, iOS, Android και React Native. Για εγκατάσταση και ρυθμίσεις ανά πλατφόρμα, δείτε τις επιμέρους σελίδες SDK.
Πώς λειτουργεί η παρακολούθηση
Κάθε SDK ακολουθεί το ίδιο pipeline:
- Καλείτε
track(eventName, properties)στην εφαρμογή σας. - Το SDK τοποθετεί το συμβάν τοπικά σε ουρά (με διατήρηση εκτός σύνδεσης) και το στέλνει σε παρτίδες - από προεπιλογή κάθε 5 δευτερόλεπτα ή κάθε 50 συμβάντα, όποιο συμβεί πρώτο.
- Η παρτίδα παραδίδεται στο
POST /v1/track/batch, με έλεγχο ταυτότητας μέσω του κλειδιού SDK της εφαρμογής σας (μορφήjry_sdk_<platform>_<random>, ένα για κάθε εφαρμογή - δείτε Επισκόπηση εφαρμογών). - Ο διακομιστής επιλύει τον χρήστη (ανώνυμο ή αναγνωρισμένο), αποθηκεύει τα συμβάντα και τα διανέμει σε τμήματα, triggers journey και analytics.
Μια παρτίδα μπορεί να περιέχει έως 500 συμβάντα. Τα timestamps ορίζονται από το SDK κατά την κλήση· ο διακομιστής δέχεται epoch milliseconds ή συμβολοσειρές ISO-8601 και επιστρέφει στον χρόνο διακομιστή αν το timestamp λείπει ή δεν είναι έγκυρο, ώστε εσφαλμένο ρολόι συσκευής να μην απορρίπτει συμβάν. Κάθε SDK τα στέλνει σε 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 δεν επιβάλλει μορφή - όμως η συνέπεια έχει σημασία, επειδή έτσι βρίσκετε συμβάντα αργότερα σε builders τμημάτων, triggers journey και Event Explorer.
Συστάσεις:
- Χρησιμοποιήστε Title Case με κενά. Τα ενσωματωμένα συμβάντα του Joryio ακολουθούν την τυπική ταξινομία e-commerce (Αντικείμενο + ρήμα σε παρελθοντικό χρόνο, Title Case):
Product Viewed,Product Added,Checkout Started,Order Completed. Έτσι, προσαρμοσμένα συμβάντα όπωςTrial StartedκαιSignup Completedκρατούν τον κατάλογο ομοιόμορφο. Το snake case επίσης λειτουργεί - διαλέξτε μία σύμβαση και τηρήστε την. - Ονομάστε την ενέργεια, όχι το UI. Το
Order Completedαντέχει σε redesign· το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:
| Τύπος | Παράδειγμα | Σημειώσεις |
|---|---|---|
| String | "currency": "USD" | Χρησιμοποιήστε το και για ημερομηνίες, ως συμβολοσειρές ISO-8601 |
| Number | "total": 149.99 | Ακέραιοι και δεκαδικοί |
| Boolean | "first_order": true | |
| Array | "item_ids": ["SKU-1", "SKU-2"] | |
| Object | "shipping": { "method": "express" } | Επιτρέπονται ένθετα αντικείμενα |
Όρια διακομιστή ανά συμβάν:
| Όριο | Τιμή |
|---|---|
| Μήκος ονόματος συμβάντος | 255 χαρακτήρες |
| Συνολικό μέγεθος ιδιοτήτων (σειριοποιημένο JSON) | 50 KB |
| Κλειδιά ιδιοτήτων ανώτερου επιπέδου | 200 |
| Βάθος ένθεσης | 5 επίπεδα |
| Συμβάντα ανά αίτημα παρτίδας | 500 |
Το μέγεθος είναι το μήκος των ιδιοτήτων σειριοποιημένων ως JSON, σε χαρακτήρες (51.200), και το βάθος ένθεσης μετρά το ίδιο το αντικείμενο ιδιοτήτων ως επίπεδο 1. Τα όρια αφορούν τις ιδιότητες που στέλνει η εφαρμογή σας - οι ιδιότητες $ που προσθέτει ο διακομιστής δεν μετρούν. Ένα συμβάν που υπερβαίνει ένα όριο, ή με κενό ή υπερβολικά μεγάλο όνομα, απορρίπτεται οριστικά: η απόκριση παρτίδας το αναφέρει στο rejectedIndices (δείτε Αποκρίσεις παρτίδας) και η υπόλοιπη παρτίδα αποθηκεύεται. Τα SDK ελέγχουν τα ίδια όρια όταν καλείτε track() και απορρίπτουν ένα τέτοιο συμβάν εκεί, με μια γραμμή στο log.
Συμβάντα που υπερβαίνουν αυτά τα όρια απορρίπτονται. Τα ονόματα ιδιοτήτων ακολουθούν την ίδια συμβουλή: επιλέξτε μια σύμβαση (product_id, όχι άλλοτε productId) και κρατήστε τους τύπους σταθερούς.
Τα NaN, Infinity και -Infinity δεν είναι αριθμοί JSON. Κάθε SDK αφαιρεί μια ιδιότητα ή ένα χαρακτηριστικό με μία από αυτές τις τιμές τη στιγμή της κλήσης, καταγράφει μια προειδοποίηση και στέλνει την υπόλοιπη κλήση χωρίς αυτό το κλειδί - καμία εξαίρεση δεν φτάνει στον κώδικά σας, τίποτα δεν αποθηκεύεται στη συσκευή, και μια λάθος τιμή δεν καθυστερεί ποτέ άλλες εγγραφές. Το ίδιο ισχύει για τις προσαρμοσμένες ιδιότητες των trackers ηλεκτρονικού εμπορίου. Στο web, μια τιμή χαρακτηριστικού που δεν μπορεί να σειριοποιηθεί (κυκλικό αντικείμενο, BigInt, συνάρτηση) αφαιρείται με τον ίδιο τρόπο.
Ιδιότητες με πρόθεμα $ (όπως $platform, $session_id, $app_id) προστίθενται αυτόματα - μερικές από τα SDK και άλλες από το pipeline εισαγωγής του Joryio. Θεωρήστε το πρόθεμα δεσμευμένο και μην το χρησιμοποιείτε για δικές σας ιδιότητες.
Κανόνες ονομάτων για χαρακτηριστικά χρήστη
Τα κλειδιά χαρακτηριστικών (το αντικείμενο που δίνετε στο setAttributes /
setAttribute) έχουν δύο επιπλέον περιορισμούς, και ένα κλειδί που τους παραβιάζει
απορρίπτεται - η υπόλοιπη κλήση αποθηκεύεται κανονικά:
| Δεν επιτρέπεται | Γιατί |
|---|---|
. οπουδήποτε στο κλειδί | Η τελεία διαβάζεται ως διαχωριστικό ΔΙΑΔΡΟΜΗΣ. Το "profile.email" θα αποθηκευόταν ως ένθετο profile: { email }, οπότε ένα segment στο profile.email δεν θα ταίριαζε με τίποτα. |
$ στην αρχή | Δεσμευμένο, όπως και για τις ιδιότητες συμβάντων παραπάνω. |
| Κενό κλειδί | Δεν υπάρχει τίποτα να αποθηκευτεί. |
Τα κλειδιά απορρίπτονται αντί να μετονομάζονται σκόπιμα: η μετονομασία θα ανέφερε επιτυχία ενώ θα έβαζε τα δεδομένα κάπου που δεν ρωτάτε ποτέ.
identify έναντι track
Στέλνετε πάντα τους αριθμούς τηλεφώνου σε πλήρη διεθνή μορφή (E.164): +, ο κωδικός χώρας και μετά ο αριθμός - για παράδειγμα +972501234567. Ένας αριθμός χωρίς + διαβάζεται με την προεπιλεγμένη χώρα για αριθμούς τηλεφώνου του χώρου εργασίας· αν δεν έχει οριστεί, ή αν τα ψηφία διαβάζονται με δύο τρόπους, αποθηκεύεται ως μη επαληθευμένος και δεν χρησιμοποιείται για μηνύματα. Πώς χειρίζονται οι αριθμοί τηλεφώνου
Οι δύο βασικές κλήσεις έχουν διαφορετικό ρόλο:
identify(userId)δηλώνει ποιος είναι ο χρήστης. Συνδέει την τρέχουσα συσκευή/συνεδρία με το σταθερό αναγνωριστικό χρήστη και συγχωνεύει ανώνυμο ιστορικό στο προφίλ. Γνωρίσματα που ορίζονται μεsetAttributesπεριγράφουν τον χρήστη.track(eventName, properties)δηλώνει τι συνέβη. Οι ιδιότητες περιγράφουν το συμβάν και είναι αμετάβλητες μετά την καταγραφή.
Κανόνες:
- Καλέστε
identifyμόλις γνωρίζετε τον χρήστη - κατά τη σύνδεση και κατά την εκκίνηση εφαρμογής αν αποκαθίσταται συνεδρία. Χρησιμοποιήστε το ίδιο αναγνωριστικό σε κάθε πλατφόρμα ώστε η δραστηριότητα web και mobile να καταλήγει στο ίδιο προφίλ (δείτε Παρακολούθηση πολλών πλατφορμών). - Πριν από το
identify, τα συμβάντα καταγράφονται κάτω από ανώνυμο ID. Όταν αναγνωρίσετε αργότερα τον χρήστη, ο διακομιστής συγχωνεύει το ανώνυμο ιστορικό, επομένως τα συμβάντα πριν από την εγγραφή δεν χάνονται. - Δεν υπάρχει ξεχωριστή κλήση
alias(userId): τοidentify(userId)συνδέει το ανώνυμο ιστορικό και ονομάζει το άτομο. Για να καταγράψετε τα αναγνωριστικά του ατόμου σε άλλα συστήματα (ID CRM, αριθμό μέλους), χρησιμοποιήστεaddAlias(label, name)- λειτουργεί και πριν από τη σύνδεση, και τα ψευδώνυμα μεταφέρονται στο αναγνωρισμένο προφίλ όταν ο επισκέπτης αναγνωριστεί. - Βάλτε δεδομένα ανά εμφάνιση σε ιδιότητες συμβάντος (
total,coupon) και διαρκή στοιχεία του ατόμου σε γνωρίσματα (plan,lifetime_value). - Καλέστε
reset()κατά την αποσύνδεση ώστε ο επόμενος χρήστης στη συσκευή να μην κληρονομήσει το προφίλ.
Το ίδιο συμβάν σε κάθε SDK
Η κλήση track είναι σκόπιμα ίδια σε μορφή σε όλα τα SDK. Ακολουθεί το ίδιο συμβάν 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',
});
Επειδή το όνομα και οι ιδιότητες είναι ίδιες, μία συνθήκη τμήματος ή trigger journey ταιριάζει με το συμβάν ανεξάρτητα από την πλατφόρμα προέλευσής του.
Για τυπική δραστηριότητα e-commerce (προβολές προϊόντων, καλάθια, checkout, παραγγελίες), προτιμήστε τους ενσωματωμένους e-commerce trackers των SDK - εκπέμπουν τα τυποποιημένα ονόματα συμβάντων που περιμένουν οι λειτουργίες e-commerce του Joryio. Δείτε τον δια-SDK οδηγό E-Commerce Tracking.
Τι συμβαίνει στον διακομιστή
Μόλις γίνει δεκτή μια παρτίδα, κάθε συμβάν:
- Αποθηκεύεται στο analytics store, συνδεδεμένο με το επιλυμένο προφίλ χρήστη.
- Αξιολογείται έναντι triggers journey. Journey με trigger εισόδου που ταιριάζει με το όνομα συμβάντος εγγράφει τον χρήστη αμέσως.
- Τροφοδοτεί τμήματα. Οι συνθήκες τμημάτων βάσει συμβάντος ενημερώνονται από τη ροή συμβάντων.
- Εμφανίζεται στα analytics - στο Event Explorer, τα funnels και τα analytics ανά εφαρμογή.
- Μπορεί να ενημερώσει το προφίλ. Για παράδειγμα, συμβάντα
Session Startενημερώνουν την εγγραφή συσκευής του χρήστη και γνωρίσματα όπωςcountry.
Δύο συμπεριφορές διακομιστή που αξίζει να γνωρίζετε:
- Σήμανση bot. Αιτήματα από γνωστά bot user agents επισημαίνονται· κλήσεις που μεταβάλλουν προφίλ, όπως
identifyκαιsetAttributes, παραλείπονται για bots. - Επιεικής επικύρωση. Άγνωστα επιπλέον πεδία στο payload αφαιρούνται αντί να απορρίπτονται, ώστε ασυμφωνία έκδοσης SDK να μη χάνει τα συμβάντα σας.
Σύμβαση διακομιστή για αιτήματα SDK
Η λογική ουράς και επανάληψης των SDK βασίζεται στη συμπεριφορά του διακομιστή που περιγράφεται παρακάτω. Αν καλείτε αυτά τα endpoints μόνοι σας (προσαρμοσμένη ενσωμάτωση ή proxy), χειριστείτε τις αποκρίσεις με τον ίδιο τρόπο.
Αποκρίσεις παρτίδας
Το POST /v1/track/batch δέχεται έως 500 συμβάντα και σώμα αιτήματος έως 1 MB.
| Απόκριση | Σημασία | Τι να κάνετε |
|---|---|---|
200 με success: true | Όλα τα συμβάντα αποθηκεύτηκαν | Διαγράψτε την παρτίδα |
200 με success: false | Κάποια ή όλα τα συμβάντα δεν αποθηκεύτηκαν. Δύο λίστες δίνουν τις θέσεις τους (από το 0) στην παρτίδα που στείλατε: failedIndices (αποτυχία από τη δική μας πλευρά) και rejectedIndices (οριστική απόρριψη - υπέρβαση των ορίων ανά συμβάν ή μη έγκυρο όνομα). Το partial: true σημαίνει ότι τα υπόλοιπα αποθηκεύτηκαν· το failed μετρά και τις δύο λίστες | Στείλτε ξανά μόνο τα συμβάντα του failedIndices - η επανάληψη ενός αποθηκευμένου συμβάντος είναι ασφαλής, το clientEventId αποτρέπει διπλότυπα. Απορρίψτε τα συμβάντα του rejectedIndices: η αποστολή τους ξανά δεν θα πετύχει ποτέ |
400 | Το σώμα απέτυχε στην επικύρωση (για παράδειγμα πάνω από 500 συμβάντα ή ένα λανθασμένο συμβάν) | Μην το ξαναστείλετε όπως είναι - χωρίστε την παρτίδα |
413 | Το σώμα ξεπερνά το 1 MB | Χωρίστε την παρτίδα |
401 | Το κλειδί SDK δεν είναι έγκυρο ή ενεργό, ή (με ενεργό SDK Authentication) σε αίτημα που αναφέρει userId το token X-Joryio-Auth λείπει, έχει λήξει ή ανήκει σε άλλο χρήστη - σώμα error: "sdk_authentication_error" και ένα reason: missing, expired, invalid ή sub_mismatch (το token ανήκει σε άλλο χρήστη). Τα ανώνυμα αιτήματα δεν χρειάζονται token | Ανανεώστε το token και δοκιμάστε ξανά. Συμβάντα σε αναμονή για χρήστη που δεν είναι πια συνδεδεμένος δεν μπορούν να πάρουν token: σε οποιοδήποτε reason (missing, expired, invalid ή sub_mismatch) απορρίψτε τα. Μόνο οι αποτυχίες του τρέχοντος συνδεδεμένου χρήστη φτάνουν στον χειριστή σφαλμάτων του 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 - δείτε Οι ανακλήσεις παραδίδονται πάντα | Σταματήστε την αποστολή για αυτή τη συνεδρία |
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 της οποίας το token δεν είναι device token του APNs (για παράδειγμα token FCM - καταχωρίστε tokens FCM μόνο στο Android) | Μην το ξαναστείλετε - απορρίψτε το και καταγράψτε το |
401, 402, 403, 429 | Όπως στον πίνακα παρτίδας παραπάνω | Όπως παραπάνω |
404 | Συνδρομές, μόνο σε παλαιότερους διακομιστές: δεν υπάρχει ακόμη προφίλ για αυτό το userId ή anonymousId. Ο τρέχων διακομιστής δημιουργεί αντί γι' αυτό το προφίλ που λείπει, όπως το /v1/alias/add | Δοκιμάστε ξανά αφού σταλούν τα συμβάντα σε αναμονή, λίγες φορές το πολύ |
403 με code: "verified_identity_required" | Μόνο endpoints του SDK (/v1/subscriptions/channel, /v1/subscriptions/group): επανεγγραφή προσώπου που διαγράφηκε ρητά (δική του διαγραφή ή από λίστα, STOP, διαγραφή στο email ή στο τηλέφωνό του - και από άλλη επαφή) από μη επαληθευμένο υποκείμενο - ένα userId χωρίς SDK Authentication, ή ένα anonymousId που ανήκει σε ταυτοποιημένο πρόσωπο. Η πρώτη εγγραφή γίνεται δεκτή· μια λίστα με διπλό opt-in απαντά pending: true και στέλνει το email επιβεβαίωσης. Η διαγραφή επιτρέπεται πάντα | Μην δοκιμάσετε ξανά - ενεργοποιήστε το SDK Authentication ή κάντε την επανεγγραφή από τον server σας με το 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 |
Πώς μετρούν τα SDK τις επαναλήψεις
Κάθε SDK μετρά τις αποτυχημένες προσπάθειες μιας εγγραφής με τον ίδιο τρόπο. Η έλλειψη σύνδεσης, ένα 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 απορρίπτει ανώνυμα aliases. Οι ετικέτες 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 βρίσκεται ακόμη καθ' οδόν, το ανώνυμο προφίλ. Μη βάζετε ποτέ διεύθυνση email στο 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>) εξυπηρετούνται στη ρίζα του host του API, όχι κάτω από το /api. Τα SDK τις δημιουργούν από το scheme και το host του ρυθμισμένου endpoint. Οι ίδιες διαδρομές απαντούν και κάτω από /api/track/push/..., οπότε μια έκδοση που κράτησε τη διαδρομή /api εξακολουθεί να αναφέρει.
Η καταγραφή της εξαίρεσης
Όταν ένα άτομο εξαιρείται από την παρακολούθηση (optOut() σε κάθε SDK), το SDK γράφει στο προφίλ το χαρακτηριστικό tracking_opted_out: true, και το optIn() το επαναφέρει σε false. Είναι ένα boolean χαρακτηριστικό όπως κάθε άλλο: φιλτράρετε με αυτό σε ένα τμήμα ("tracking_opted_out είναι true") για να κρατήσετε έξω από ένα κοινό όσους εξαιρέθηκαν, ή για να τους μετρήσετε. Είναι καταγραφή της απόφασης, όχι η επιβολή της - το SDK σταματά να στέλνει μόνο του - και οι εκδόσεις SDK πριν από την 1.3.0 το έστελναν ως $tracking_opted_out, που ο διακομιστής αποθηκεύει πλέον στο ίδιο κλειδί tracking_opted_out.
Οι ανακλήσεις παραδίδονται πάντα
Τέσσερις εγγραφές μόνο μειώνουν όσα συλλέγονται ή αποστέλλονται: μια συνδρομή καναλιού που ορίζεται σε unsubscribed, ένα unsubscribe από ομάδα, η καταγραφή εξαίρεσης tracking_opted_out: true και το /v1/push/unregister. Τα SDK τις κρατούν στην ουρά και τις ξαναστέλνουν όταν το άτομο έχει εξαιρεθεί από την παρακολούθηση, όταν η συγκατάθεση παρακολούθησης έχει απορριφθεί ή εκκρεμεί, και μετά από wipeData()· ο διακομιστής τις δέχεται στις ίδιες περιπτώσεις:
- Κανένας έλεγχος συγκατάθεσης ή εξαίρεσης στον διακομιστή δεν τις απορρίπτει - ένα άτομο που έχει εξαιρεθεί μπορεί ακόμη να απεγγραφεί.
- Το Strict SDK identity δεν τις απορρίπτει από ανώνυμο επισκέπτη. Μόνο η αντίθετη κατεύθυνση - εγγραφή,
tracking_opted_out: false, ή η καταγραφή μαζί με οποιοδήποτε άλλο χαρακτηριστικό - εξακολουθεί να χρειάζεται ταυτοποιημένο χρήστη με επαληθευμένο token. - Ένας λογαριασμός σε παύση δεν τις απορρίπτει: όσο η λήψη συμβάντων είναι σε παύση (
402,SDK_INGESTION_SUSPENDED), ο server εξακολουθεί να τις δέχεται και τα SDK συνεχίζουν να τις στέλνουν, ώστε το «όχι» ενός ατόμου να καταγράφεται όποια κι αν είναι η κατάσταση χρέωσης του λογαριασμού. - Ένα ληγμένο token εξακολουθεί να λειτουργεί για αυτές. Με ενεργό το SDK Authentication, μια ανάκληση που αναφέρει
userIdγίνεται δεκτή με το token αυτού του χρήστη έως 30 ημέρες μετά τη λήξη του. Η υπογραφή και το υποκείμενο (sub) ελέγχονται όπως πάντα· μόνο η λήξη χαλαρώνει, και μόνο για αυτές τις τέσσερις εγγραφές - όλα τα άλλα χρειάζονται token που δεν έχει λήξει. Έτσι μια αποσύνδεση δεν χάνει τίποτα: όταν ένας χρήστης αποσυνδέεται (reset()), το SDK κρατά το token του - κρυπτογραφημένο όπου η πλατφόρμα έχει ασφαλή αποθήκευση (iOS Keychain, κρυπτογραφημένες προτιμήσεις του Android· στο web, local storage δίπλα στην ουρά) - μαζί με τις εγγραφές του που περιμένουν, και το διαγράφει μόλις η τελευταία από αυτές παραδοθεί ή απορριφθεί, ώστε μια απεγγραφή που πατήθηκε λίγο πριν από την αποσύνδεση να φτάνει, ακόμη και μετά από επανεκκίνηση της εφαρμογής. - Σύνδεση ενώ η παρακολούθηση απορρίπτεται: το
identify(userId)ενώ η συγκατάθεση έχει απορριφθεί ή το άτομο έχει εξαιρεθεί δεν στέλνει τίποτα, δεν παρακολουθεί τίποτα και δεν γράφει προφίλ, αλλά το SDK κρατά τοuserIdστη συσκευή για έναν σκοπό - μια ανάκληση που γίνεται τότε το μεταφέρει, ώστε να απεγγράφεται το δικό του προφίλ και όχι ένα νέο ανώνυμο. Όταν δοθεί συγκατάθεση ή το άτομο επιστρέψει στην παρακολούθηση, εκτελείται το κανονικόidentify. Ταreset()καιwipeData()το ξεχνούν. - Το
/v1/push/unregisterδεν χρειάζεται tokenX-Joryio-Authακόμη κι όταν το σώμα αναφέρειuserId: αφαιρείται το push token ή το endpoint του web push, οπότε η συσκευή ενός χρήστη που αποσυνδέθηκε σταματά να λαμβάνει push αν και το token του δεν υπάρχει πια. - Ο μόνος κανόνας που εξακολουθεί να ισχύει: με ενεργό το SDK Authentication, ένα
anonymousIdπου ανήκει σε ταυτοποιημένο χρήστη δεν μπορεί να ανακαλέσει τη συγκατάθεση αυτού του χρήστη χωρίς το token του (403,SDK_ANONYMOUS_ID_IDENTIFIED). Μια εγγραφή συνδρομής που αναφέρειuserIdχρειάζεται ακόμη το token αυτού του χρήστη, όπως παντού.
Όταν η ουρά στη συσκευή γεμίσει, απορρίπτεται πρώτα η παλαιότερη εγγραφή που δεν είναι ανάκληση.
Επαλήθευση και εντοπισμός σφαλμάτων
Ελέγξτε ότι έφτασε ένα συμβάν
- Ενεργοποιήστε το συμβάν στην εφαρμογή σας.
- Στο dashboard του Joryio, ανοίξτε Analytics → Event Explorer. Φιλτράρετε με όνομα συμβάντος· θα πρέπει να εμφανιστεί μέσα σε δευτερόλεπτα από την αποστολή της παρτίδας από το SDK.
- Για προβολή ανά εφαρμογή, ανοίξτε Ρυθμίσεις → Εφαρμογές και επιλέξτε View Analytics στην εφαρμογή.
Αν τα συμβάντα δεν εμφανίζονται
- Εξαναγκάστε αποστολή. Τα συμβάντα ομαδοποιούνται· καλέστε
flush()για άμεση αποστολή. - Ενεργοποιήστε debug logging. Κάθε SDK διαθέτει επιλογή
enableDebugπου καταγράφει κάθε συμβάν στην ουρά και αίτημα δικτύου. - Ελέγξτε το κλειδί SDK. Πρέπει να ταιριάζει με την πλατφόρμα:
jry_sdk_web_...,jry_sdk_ios_...,jry_sdk_android_.... Ένα αναδημιουργημένο κλειδί ακυρώνει αμέσως το παλιό. Το Android SDK (μαζί με React Native και Unity στο Android) δηλώνει στον διακομιστή την πλατφόρμα του, και ένα κλειδί εφαρμογής άλλης πλατφόρμας απορρίπτεται με401καιcode: "SDK_KEY_PLATFORM_MISMATCH". - Ελέγξτε ότι η εφαρμογή είναι ενεργή στις Ρυθμίσεις → Εφαρμογές.
- Παρακολουθήστε την απόκριση δικτύου. Η απόκριση παρτίδας περιλαμβάνει
successκαι, σε μερική αποτυχία,failedIndices(δεν αποθηκεύτηκαν, θα σταλούν ξανά) καιrejectedIndices(οριστική απόρριψη). Οι πολύ μεγάλες ιδιότητες (πάνω από 50 KB, πάνω από 200 κλειδιά ή ένθεση βαθύτερη από 5 επίπεδα) είναι η συνηθισμένη αιτία απορριφθέντων συμβάντων. - Μόνο Web: τα endpoints επιτρέπουν κάθε origin (
Access-Control-Allow-Origin: *), επομένως τα σφάλματα CORS συνήθως δείχνουν λάθοςapiEndpointή επέκταση προγράμματος περιήγησης. - Δοκιμή από automation; Θυμηθείτε τη σήμανση bot παραπάνω - επαληθεύστε με πραγματικό πρόγραμμα περιήγησης ή συσκευή.