Ενσωμάτωση Web SDK
Το Joryio Web SDK σάς επιτρέπει να παρακολουθείτε τη συμπεριφορά χρηστών, να στέλνετε συμβάντα και να διαχειρίζεστε προφίλ χρηστών στον ιστότοπό σας.
Εγκατάσταση
Μέσω npm/yarn
npm install @joryio/web-sdk
# or
yarn add @joryio/web-sdk
Μέσω CDN
Τα αρχεία του SDK σερβίρονται από έναν παγκόσμιο host, https://sdk.joryio.com, όποια κι αν είναι η περιοχή του χώρου εργασίας σας. Τα συμβάντα και οι κλήσεις API εξακολουθούν να πηγαίνουν στον host API της περιοχής σας (η ρύθμιση apiEndpoint) - μόνο η θέση του αρχείου είναι παγκόσμια.
<!-- Recommended: the newest 1.x. Picks up fixes, never a breaking change. -->
<script src="https://sdk.joryio.com/web/1/joryio.min.js"></script>
<!-- Pinned: one exact version that never changes. You upgrade by changing the URL. -->
<script src="https://sdk.joryio.com/web/1.3.3/joryio.min.js"></script>
| Διαδρομή | Τι σερβίρει |
|---|---|
/web/1/<file> | Η νεότερη έκδοση 1.x (συνιστάται) |
/web/<version>/<file> | Μία συγκεκριμένη έκδοση, π.χ. /web/1.3.3/ - το περιεχόμενό της δεν αλλάζει ποτέ |
Αρχεία: joryio.min.js (το SDK), joryio-sw.js (ο service worker του web push) και joryio.umd.js (το μη ελαχιστοποιημένο UMD build).
/web/1/- οι περισσότεροι ιστότοποι. Οι διορθώσεις και οι νέες δυνατότητες της 1.x φτάνουν αυτόματα, και μια αλλαγή που σπάει τη συμβατότητα (2.0) δεν φτάνει ποτέ σε αυτή τη διαδρομή.- Καρφιτσωμένη (
/web/1.3.3/) - ιστότοποι που θέλουν προβλέψιμο έλεγχο του πότε αναβαθμίζεται το SDK. Το αρχείο δεν αλλάζει ποτέ, οπότε τα προγράμματα περιήγησης το κρατούν στην cache για πολύ καιρό.
Αναβάθμιση καρφιτσωμένης ενσωμάτωσης. Όταν το Joryio κυκλοφορεί νέα έκδοση SDK, αλλάξτε τον αριθμό στο snippet:
<!-- Before -->
<script src="https://sdk.joryio.com/web/1.3.3/joryio.min.js"></script>
<!-- After -->
<script src="https://sdk.joryio.com/web/1.4.0/joryio.min.js"></script>
Το πρόγραμμα περιήγησης αντιμετωπίζει το νέο URL ως νέο αρχείο και εκτελεί το νέο SDK.
Μέχρι τον Οκτώβριο του 2026 το αρχείο του SDK σερβιριζόταν από τον host του API, στο https://api-eu1.joryio.com/sdk/web/.... Αυτή η διαδρομή δεν υπάρχει πια - αντικαταστήστε την με https://sdk.joryio.com/web/1/.
Ασύγχρονο snippet
Επικολλήστε αυτόν τον κώδικα στο <head>. Φορτώνει το SDK χωρίς να μπλοκάρει τη σελίδα, και οι κλήσεις που γίνονται πριν φορτωθεί το αρχείο μπαίνουν σε ουρά και εκτελούνται με τη σειρά. Κάθε δημόσια μέθοδος μπορεί να κληθεί έτσι, και το ίδιο το init μπορεί να έρθει αργότερα - για παράδειγμα από το callback του banner συναίνεσης.
<script>
!function(){var e=window.joryio=window.joryio||[];if(!e.initialize)if(e.invoked)window.console&&console.error&&console.error("Joryio snippet included twice.");else{e.invoked=!0,e.methods=["init","track","identify","addAlias","setAttributes","setAttribute","incrementAttribute","unsetAttribute","addToArray","removeFromArray","reset","flush","optOut","optIn","updateConsent","getTrackingConsent","isUserOptedOut","setSdkAuthenticationToken","setSdkAuthenticationErrorCallback","getAnonymousId","getUserId","ready","getIdentity","getSessionInfo","getUTMData","updateUTM","syncInAppCampaigns","getInAppCampaigns","displayInAppCampaign","dismissInAppMessage","trackInAppConversion","ecommerce","wipeData","destroy"],e.keep=["init","optOut","optIn","updateConsent","wipeData"],e.factory=function(t){return function(){var n=Array.prototype.slice.call(arguments);if(n.unshift(t),e.length>=1e3)for(var i=0;i<e.length;i++)if(e.keep.indexOf(e[i][0])<0){e.splice(i,1);break}return e.push(n),/^(get|is)[A-Z]/.test(t)?void 0:e}};for(var t=0;t<e.methods.length;t++){var n=e.methods[t];e[n]=e.factory(n)}e.load=function(e){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src="https://sdk.joryio.com/web/1/joryio.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)},e.load()}}();
joryio.init({ sdkKey: 'jry_sdk_web_YOUR_KEY' });
</script>
- Η ουρά κρατά έως 1.000 κλήσεις. Πέρα από αυτό διαγράφονται οι παλαιότερες - ποτέ το
init, τοoptOut(), τοoptIn(), τοupdateConsent()ή τοwipeData(). - Μια κλήση στην ουρά δεν μπορεί να επιστρέψει τιμή. Ένας getter όπως το
getUserId()ή τοisUserOptedOut()επιστρέφειundefinedμέχρι να φορτωθεί το SDK. Για να διαβάσετε ένα αναγνωριστικό, ή για να χρησιμοποιήσετε τοuser, τοpushή τον tracker που επιστρέφει τοecommerce(), χρησιμοποιήστε τοready:joryio.ready(function (sdk) { sdk.getAnonymousId(); }). - Ένα αποτυχημένο
initδεν χάνει τίποτα. Αν τοinitαποτύχει (κλειδί SDK που λείπει ή είναι λανθασμένο - η αιτία καταγράφεται στην κονσόλα), τοwindow.joryioπαραμένει η ουρά. Καλέστε ξανά τοjoryio.init({...})με το σωστό κλειδί και το SDK ξεκινά με όλες τις κλήσεις που έγιναν ως τότε - πρώτα οι αποφάσεις απορρήτου, μετά οι υπόλοιπες με τη σειρά, μαζί και μια κατάργηση συνδρομής. - Οι κλήσεις που έγιναν ενώ η παρακολούθηση ήταν απενεργοποιημένη απορρίπτονται. Ένα
track(), μια εγγραφή χαρακτηριστικού, έναaddAlias()ή έναtrackInAppConversion()στην ουρά, που έγινε ενώ ο επισκέπτης είχε κάνει opt-out ή η συναίνεση είχε απορριφθεί - από την αποθηκευμένη επιλογή, τη ρύθμιση του init ή μια απόφαση στην ουρά πριν από αυτό - απορρίπτεται, και ένα μεταγενέστεροoptIn()ήupdateConsent('granted')στην ουρά δεν το επαναφέρει. Τοidentify()και οι διαγραφές συνδρομής διατηρούνται. Το ίδιο ισχύει για μια κλήση στην ουρά πριν από έναoptOut()ήupdateConsent('denied')στην ουρά, ή πριν από έναwipeData()στην ουρά πριν από τοinit. Ένα callback τουready()που μπήκε στην ουρά ενώ η παρακολούθηση ήταν απενεργοποιημένη, ή πριν από έναoptOut()ήupdateConsent('denied')στην ουρά, εκτελείται κανονικά, αλλά οι κλήσειςtrack(), οι εγγραφές χαρακτηριστικών, τα aliases, οι μετατροπές και οι εγγραφές συνδρομής που κάνει όσο εκτελείται απορρίπτονται επίσης - εκτός αν το ίδιο το callback άρει αυτό που απενεργοποίησε την παρακολούθηση, για το υπόλοιπο της εκτέλεσής του: το δικό τουoptIn()αίρει ένα opt-out, το δικό τουupdateConsent('granted')αίρει μια άρνηση, κανένα δεν αίρει το άλλο, και τίποτα μέσα σε αυτό δεν αίρει έναoptOut()ή μια άρνηση που μπήκε στην ουρά μετά από αυτό. ΈναwipeData()στην ουρά πριν από τοinitδεν περιορίζει ένα callback τουready()που μπήκε στην ουρά πριν από αυτό (το callback εκτελείται για τον νέο επισκέπτη). Οι αναγνώσεις και οι διαγραφές συνδρομής λειτουργούν, και το instance του SDK που έλαβε συμπεριφέρεται κανονικά στη συνέχεια. - Οι αποφάσεις ιδιωτικότητας εκτελούνται πρώτες. Ένα
optOut(),optIn()ήupdateConsent()στην ουρά, και έναwipeData()που μπήκε στην ουρά πριν από τοinit, εφαρμόζονται μέσα στοinit, πριν στείλει οτιδήποτε - έτσι κανένα Session Start, συγχρονισμός in-app ή εγγραφή push δεν φεύγει με την κατάσταση που αντικαθιστούν:
<script>
/* the snippet above, then: */
joryio.updateConsent('denied'); // applied inside init, before anything is sent
joryio.init({ sdkKey: 'jry_sdk_web_YOUR_KEY' });
</script>
Γρήγορη εκκίνηση
1. Αρχικοποιήστε το SDK
Αρχικά, αρχικοποιήστε το SDK με το κλειδί SDK σας. Θα το βρείτε στο dashboard του Joryio, στις Ρυθμίσεις → Εφαρμογές.
import JoryioSDK from '@joryio/web-sdk';
// Initialize the SDK
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_your_sdk_key_here',
enableDebug: false, // Enable debug logging in development
});
Το πακέτο έχει χάρτη exports: build ES module για το import και build CommonJS για το require. Οι bundlers (webpack, esbuild, Rollup, Vite) χρησιμοποιούν το build ES module και για τα δύο, έτσι μια εφαρμογή που κάνει import το SDK σε ένα αρχείο και require σε άλλο εξακολουθεί να τρέχει ένα SDK. Η προεπιλεγμένη εισαγωγή είναι η κλάση τόσο στους bundlers όσο και στο Node ESM (SSR, Vitest, scripts .mjs), λειτουργεί και το import { JoryioSDK } from '@joryio/web-sdk', και η TypeScript της δίνει τον ίδιο τύπο με moduleResolution node16, nodenext ή bundler.
Όταν το φορτώνετε από CDN αντί για npm, η ίδια κλάση είναι διαθέσιμη ως window.Joryio:
const joryio = new Joryio({
sdkKey: 'jry_sdk_web_your_sdk_key_here',
});
2. Αναγνωρίστε χρήστες
Στέλνετε πάντα τους αριθμούς τηλεφώνου σε πλήρη διεθνή μορφή (E.164): +, ο κωδικός χώρας και μετά ο αριθμός - για παράδειγμα +972501234567. Ένας αριθμός χωρίς + διαβάζεται με την προεπιλεγμένη χώρα για αριθμούς τηλεφώνου του χώρου εργασίας· αν δεν έχει οριστεί, ή αν τα ψηφία διαβάζονται με δύο τρόπους, αποθηκεύεται ως μη επαληθευμένος και δεν χρησιμοποιείται για μηνύματα. Πώς χειρίζονται οι αριθμοί τηλεφώνου
Αναγνωρίστε χρήστες όταν εγγράφονται ή συνδέονται:
// Identify a user
joryio.identify('user_123');
// Set profile attributes separately
joryio.setAttributes({
firstName: 'John',
lastName: 'Doe',
plan: 'premium',
signupDate: '2024-01-15',
});
3. Παρακολουθήστε συμβάντα
Παρακολουθήστε ενέργειες και συμπεριφορά χρηστών:
// Track a custom event
joryio.track('Product Viewed', {
product_id: 'prod_123',
product_name: 'Premium Plan',
price: 99.99,
currency: 'USD',
});
// Track page views
joryio.track('Page Viewed', {
page: '/pricing',
title: 'Pricing Page',
category: 'Marketing',
});
Επιλογές ρυθμίσεων
| Επιλογή | Τύπος | Προεπιλογή | Περιγραφή |
|---|---|---|---|
sdkKey | string | Απαιτείται | Το κλειδί SDK σας από το dashboard του Joryio |
apiEndpoint | string | https://api-eu1.joryio.com/api | Ο API host της περιοχής σας. Αρκεί και σκέτο όνομα host· προστίθεται το /api |
userId | string | - | Έναρξη με γνωστό ID χρήστη |
anonymousId | string | δημιουργείται | Χρήση δικού σας ανώνυμου ID |
enableDebug | boolean | false | Ενεργοποιεί καταγραφή εντοπισμού σφαλμάτων στην κονσόλα (logLevel: 'debug'). Ένα ρητό logLevel υπερισχύει |
batchFlushInterval | number | 5000 | Συχνότητα αποστολής ομαδοποιημένων συμβάντων στον διακομιστή (χιλιοστά του δευτερολέπτου). Τα συμβάντα τοποθετούνται τοπικά σε ουρά και αποστέλλονται κάθε 5 δευτερόλεπτα, για λιγότερα αιτήματα δικτύου. Τιμές κάτω από 1000 αυξάνονται σε 1000. |
batchSize | number | 50 | Συμβάντα ανά αίτημα, και το μέγεθος ουράς που προκαλεί αποστολή πριν από τον χρονοδιακόπτη. Ποτέ πάνω από 500 ανά αίτημα (το όριο του API) |
sendImmediately | boolean | false | Στέλνει κάθε συμβάν αμέσως χωρίς ομαδοποίηση (δεν συνιστάται για παραγωγή) |
sessionTimeout | number | 1800000 | Λήξη συνεδρίας σε χιλιοστά του δευτερολέπτου (προεπιλογή: 30 λεπτά). Νέα συνεδρία ξεκινά μετά από αυτό το διάστημα αδράνειας - ελέγχεται σε κάθε track() και όταν η καρτέλα γίνεται ξανά ορατή. |
trackSessionStart | boolean | true | Ένα συμβάν «Session Start» ανά νέα συνεδρία. Μια επαναφόρτωση που συνεχίζει τη συνεδρία δεν στέλνει κανένα. |
trackPageViews | boolean | false | Παρακολουθεί αυτόματα το «Page Viewed» κατά τη φόρτωση της σελίδας |
captureUTM | boolean | true | Καταγράφει αυτόματα παραμέτρους UTM από το URL για απόδοση καμπάνιας |
resetSessionOnNewCampaign | boolean | false | Ξεκινά νέα συνεδρία όταν αλλάζουν οι παράμετροι UTM (χρήσιμο για ανάλυση συνεδριών ανά καμπάνια) |
trackDeviceProperties | boolean | true | Συμπεριλαμβάνει πληροφορίες συσκευής στο Session Start |
persistQueue | boolean | true | Διατηρεί συμβάντα στην ουρά στο localStorage ώστε να επιβιώνουν από ανανέωση σελίδας |
maxQueueSize | number | 1000 | Τα περισσότερα συμβάντα που κρατά η τοπική ουρά όσο οι αποστολές αποτυγχάνουν· πέρα από αυτό απορρίπτονται τα παλαιότερα (με προειδοποίηση στο log όταν η καταγραφή είναι ενεργή) |
maxRetries | number | 3 | Άμεσες επαναλήψεις ενός αιτήματος (5xx, 429, σφάλμα δικτύου). Μια παρτίδα που αποτυγχάνει ακόμα κρατιέται και ξαναστέλνεται αργότερα |
retryBackoffMs | number | 1000 | Η πρώτη αναμονή πριν από επανάληψη, σε χιλιοστά του δευτερολέπτου· διπλασιάζεται σε κάθε αποτυχία, έως 5 λεπτά |
requestTimeout | number | 10000 | Χρονικό όριο σε χιλιοστά του δευτερολέπτου για κάθε αίτημα API (συμβάντα, γνωρίσματα, in-app, push) |
trackPageProperties | boolean | true | Προσθήκη του referrer και της σελίδας προσγείωσης στα συμβάντα "Page Viewed" |
respectDoNotTrack | boolean | true | Η ρύθμιση Do Not Track του browser λογίζεται ως απενεργοποίηση παρακολούθησης |
logLevel | string | - | 'error', 'warn', 'info' ή 'debug'. Δεν καταγράφεται τίποτα αν δεν οριστεί αυτό ή το enableDebug |
trackingConsent | string | χωρίς τιμή | 'granted', 'denied' ή 'pending'. Αφήστε το χωρίς τιμή αν ο ιστότοπός σας δεν έχει banner συναίνεσης. Δείτε Ιδιωτικότητα και συναίνεση |
optOut | boolean | false | Το true απενεργοποιεί την παρακολούθηση του επισκέπτη και διατηρείται μεταξύ φορτώσεων σελίδας, όπως το optOut(). Το false δεν αναιρεί μια αποθηκευμένη απενεργοποίηση - μόνο το optIn() την αναιρεί |
enableSdkAuthentication | boolean | false | Επισύναψη και ανανέωση ενός JWT που εκδίδει το backend σας. Δείτε Ταυτοποίηση SDK |
sdkAuthenticationToken | string | - | Το πρώτο JWT, όταν το enableSdkAuthentication είναι true |
plugins | array | [] | Plugins με hooks beforeTrack / afterTrack (μόνο web) |
inApp.enabled | boolean | true | Ενεργοποίηση ή απενεργοποίηση των μηνυμάτων in-app |
inApp.evaluationMode | string | 'differential-sync' | Πότε ανακτώνται οι καμπάνιες in-app: 'differential-sync' (κατά τη φόρτωση, στο identify(), στο reset(), σε νέα συνεδρία, σε αλλαγή παρακολουθούμενου γνωρίσματος και κάθε inApp.syncInterval) ή 'session-start-only' (μόνο κατά τη φόρτωση, στο identify(), στο reset() και σε νέα συνεδρία) |
inApp.syncInterval | number | 0 (ανενεργό) | Νέα ανάκτηση καμπανιών in-app κάθε N χιλιοστά του δευτερολέπτου σε λειτουργία 'differential-sync'. Τιμές κάτω από 30000 αυξάνονται σε 30000· σε παύση όσο η καρτέλα είναι κρυφή |
inApp.allowHtmlJsInAppMessages | boolean | false | Επιτρέπει in-app μηνύματα HTML. Το μήνυμα εμφανίζεται σε sandboxed iframe με αυστηρό Content-Security-Policy: εκτελείται μόνο το script γέφυρας του SDK - τα δικά σας <script>, οι ενσωματωμένοι χειριστές on* και τα <iframe> όχι - οπότε κουμπιά και φόρμες λειτουργούν μέσω data-joryio-action / data-jry-form. Απαιτεί ενεργοποίηση επειδή αποδίδει HTML που έγραψε κάποιος. Το μήνυμα δεν μπορεί ποτέ να πλοηγήσει το δικό του iframe: οι σύνδεσμοι και οι ανακατευθύνσεις περνούν από το SDK, που τους ανοίγει στη σελίδα σας (μόνο σύνδεσμοι http(s) και σχετικοί ως προς τη ρίζα)· αν το iframe πλοηγηθεί παρ' όλα αυτά, το μήνυμα κλείνει. Τα native μηνύματα εμφανίζονται ούτως ή άλλως. Μηνύματα εντός εφαρμογής |
inApp.displayOptions.defaultPosition | string | 'center' | 'top', 'center' ή 'bottom': πού εμφανίζεται ένα μήνυμα τύπου Custom. Τα μηνύματα modal, banner, slide-up και πλήρους οθόνης κρατούν τη δική τους θέση |
inApp.displayOptions.defaultAnimation | string | 'fade' | 'fade', 'slide' ή 'none': πώς εμφανίζονται τα μηνύματα. Παραλείπεται όταν το σύστημα του επισκέπτη ζητά λιγότερη κίνηση |
inApp.displayOptions.backdropColor | string | 'rgba(0, 0, 0, 0.5)' | Χρώμα του σκοτεινού επιπέδου πίσω από μηνύματα modal και πλήρους οθόνης |
inApp.displayOptions.closeButtonColor | string | το χρώμα κειμένου του μηνύματος | Χρώμα του κουμπιού κλεισίματος |
inApp.displayOptions.zIndex | number | 999999 | Σειρά στοίβαξης των μηνυμάτων (το σκοτεινό επίπεδο βρίσκεται μία θέση κάτω) |
inApp.onMessageDisplay / onMessageClick / onMessageDismiss | function | - | Callbacks για κάθε βήμα - δείτε Callbacks |
Ομαδοποίηση και αποστολή συμβάντων
Τα συμβάντα ομαδοποιούνται τοπικά και αποστέλλονται στον διακομιστή σε ομάδες για βέλτιστη χρήση δικτύου:
- Αυτόματη αποστολή: τα συμβάντα στέλνονται κάθε
batchFlushIntervalχιλιοστά του δευτερολέπτου (προεπιλογή 5 δευτ.) - Αποστολή βάσει μεγέθους: αποστέλλονται αμέσως όταν συσσωρευτούν
batchSizeσυμβάντα (προεπιλογή 50) - Μη αυτόματη αποστολή: καλέστε
joryio.flush()για άμεση αποστολή των συμβάντων της ουράς - Κατά την έξοδο από τη σελίδα: τα συμβάντα της ουράς παραδίδονται στον browser με
fetch(..., { keepalive: true })- χωρίς cookies, με την κεφαλίδα ταυτοποίησης του SDK. Παραδίδεται μόνο ό,τι χωρά στο όριο keepalive του browser (64 KB) - ένας προϋπολογισμός για όλη τη σελίδα, όσα συμβάντα εξόδου κι αν ενεργοποιηθούν· τα υπόλοιπα μένουν στην ουρά για την επόμενη προβολή σελίδας. Όταν ο browser είναι εκτός σύνδεσης, ή μετά από αποτυχία της τελευταίας αποστολής, δεν παραδίδεται τίποτα: τα συμβάντα μένουν στην ουρά αντί να φύγουν με ένα αίτημα που πιθανότατα θα αποτύχει - Μια αποτυχημένη αποστολή δεν μπλοκάρει την ουρά: κάθε αίτημα μεταφέρει το πολύ
batchSizeσυμβάντα (ποτέ πάνω από 500 ή περίπου 900 KB). Ένα αίτημα που το API απορρίπτει ως λανθασμένο (400, 413, 422) διασπάται μέχρι να απομονωθεί και να απορριφθεί το ένα προβληματικό συμβάν· σφάλματα δικτύου, 429 και 5xx κρατούν όλα τα συμβάντα και ξαναδοκιμάζουν με εκθετική καθυστέρηση· ένα 402 (η λήψη συμβάντων έχει παυθεί για το workspace σας), 403 ή ένα άκυρο κλειδί σταματά την αποστολή συμβάντων για αυτή την προβολή σελίδας και τα κρατά. Μετά από ένα 402 περιμένουν και οι εγγραφές προφίλ - εκτός από τις ανακλήσεις, που το API εξακολουθεί να δέχεται και που εξακολουθούν να στέλνονται - Χρονοσημάνσεις: τα συμβάντα φέρουν χρονοσήμανση ISO 8601 σε UTC με χιλιοστά του δευτερολέπτου (
2026-10-07T09:30:00.123Z), όπως σε κάθε SDK του Joryio - Το
success: falseείναι αποτυχία: μια απάντηση 2xx της οποίας το σώμα λέειsuccess: false- για παρτίδα, identify, γνωρίσματα, alias, αλλαγή συνδρομής ή εγγραφή push - ξαναστέλνεται και δεν θεωρείται ποτέ ολοκληρωμένη. Σε παρτίδα κρατιούνται μόνο τα συμβάντα που αναφέρει το API στοfailedIndices - Οριστική απόρριψη σημαίνει διαγραφή: τα συμβάντα που αναφέρει το API στο
rejectedIndicesδιαγράφονται και δεν ξαναστέλνονται. Τοtrack()απορρίπτει ένα συμβάν πριν μπει στην ουρά (με γραμμή καταγραφής) όταν το όνομά του δεν έχει 1-255 χαρακτήρες ή όταν οι ιδιότητές του ξεπερνούν τα όρια του API: πάνω από 50 KB σε σειριοποίηση, πάνω από 200 κλειδιά, ή ένθεση βαθύτερη από 5 επίπεδα - Ένας χρήστης ανά αίτημα: ένα αίτημα δεν αναμειγνύει ποτέ συμβάντα δύο χρηστών, έτσι τα συμβάντα σε ουρά ενός χρήστη που αποσυνδέθηκε δεν καθυστερούν αυτά του επόμενου (δείτε Ταυτοποίηση SDK)
- Οι εγγραφές προφίλ είναι ανθεκτικές και με σειρά: οι εγγραφές γνωρισμάτων, το
addAlias()και οι αλλαγές συνδρομών και ομάδων συνδρομών κρατιούνται στοlocalStorageμέχρι να τις επιβεβαιώσει το API, ώστε μια πλοήγηση ή μια καρτέλα που κλείνει να μην τις χάνει, και κατά την εκφόρτωση της σελίδας όσες περιμένουν παραδίδονται επιπλέον στοfetch(..., { keepalive: true }). Μια νεότερη αλλαγή στο ίδιο κανάλι, ομάδα ή γνώρισμα αντικαθιστά μια παλαιότερη που ακόμη περιμένει, έτσι μια παλαιότερη αλλαγή δεν φτάνει ποτέ μετά από μια νεότερη - Ένας κανόνας επανάληψης για κάθε εγγραφή (και για το
identify()): σφάλματα δικτύου, λήξεις χρόνου, 429, 5xx και 402 δεν μετρούν ποτέ και ξαναδοκιμάζονται με αυξανόμενη καθυστέρηση· ένα 404 ("δεν υπάρχει ακόμη προφίλ") ξαναδοκιμάζεται το πολύ 5 φορές και κάθε άλλη απόρριψη που επιδέχεται επανάληψη (success: false, ένα 401 ταυτοποίησης SDK για τον τρέχοντα χρήστη) το πολύ 10 φορές· τα 400, 403, 409, 413 και 422 απορρίπτουν την εγγραφή με γραμμή καταγραφής - Όριο ουράς: η τοπική ουρά περιέχει έως
maxQueueSizeσυμβάντα (προεπιλογή 1.000). Αν ξεπεραστεί το όριο (π.χ. σε μεγάλη περίοδο εκτός σύνδεσης), τα παλαιότερα συμβάντα απορρίπτονται (με προειδοποίηση στο log όταν η καταγραφή είναι ενεργή)
// Send events immediately instead of batching
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_...',
sendImmediately: true // Send each event immediately
});
// Or configure batching behavior
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_...',
batchFlushInterval: 10000, // Flush every 10 seconds
batchSize: 20 // Or when 20 events accumulate
});
// Or manually flush at any time
joryio.track('Important Event', {...});
joryio.flush(); // Send now
Διαχείριση συνεδριών
Οι συνεδρίες παρακολουθούν συνεχή δραστηριότητα χρηστών και διαχειρίζονται αυτόματα:
- Λήξη συνεδρίας: προεπιλογή 30 λεπτά αδράνειας (ρυθμίζεται μέσω
sessionTimeout) - Νέα συνεδρία ξεκινά όταν:
- Ο χρήστης φορτώνει τη σελίδα για πρώτη φορά
- Παρέρχεται το χρονικό όριο συνεδρίας χωρίς συμβάντα
- Ο χρήστης καλεί
joryio.reset()(π.χ. κατά την αποσύνδεση) - Εντοπίζεται νέα καμπάνια (αν είναι ενεργοποιημένο το
resetSessionOnNewCampaign)
Ρύθμιση λήξης συνεδρίας:
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_...',
sessionTimeout: 3600000 // 1 hour in milliseconds
});
// Or shorter session timeout
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_...',
sessionTimeout: 600000 // 10 minutes
});
Οι συνεδρίες διαχειρίζονται αυτόματα με βάση τη δραστηριότητα του χρήστη. Κάθε συμβάν που παρακολουθείται επαναφέρει τον χρονοδιακόπτη αδράνειας.
Παρακολούθηση έναρξης συνεδρίας
Από προεπιλογή, το SDK παρακολουθεί αυτόματα ένα συμβάν «Session Start» κάθε φορά που ξεκινά μια νέα συνεδρία. Αυτό το συμβάν:
- Μπορεί να χρησιμοποιηθεί ως έναυσμα σε καμπάνιες και ροές journey
- Περιλαμβάνει όλο το πλαίσιο συνεδρίας (παραμέτρους UTM, referrer, σελίδα προορισμού και - όταν είναι ενεργό το
trackDeviceProperties- δεδομένα συσκευής) - Αποθηκεύεται στο προφίλ του χρήστη όπως κάθε άλλο συμβάν, ώστε τα τμήματα και τα analytics να μπορούν να μετρούν συνεδρίες ανά χρήστη
Παράδειγμα συμβάντος έναρξης συνεδρίας:
// Automatically tracked when user visits your site
{
event: "Session Start",
properties: {
utm_source: "google", // If UTM parameters present
utm_medium: "cpc",
utm_campaign: "spring_sale",
referrer: "https://google.com",
landing_page: "https://example.com/..."
},
userId: "user_123", // If identified
anonymousId: "anon_456",
sessionId: "sess_789"
}
Αυτόματα δεδομένα συνεδρίας
Το Web SDK εμπλουτίζει τα συμβάντα Session Start με δεδομένα συσκευής και περιβάλλοντος:
$user_agent$timezone$screen_width/$screen_height$viewport_width/$viewport_height$language/$languages$platform$browser$device_idcountry(ISO-3166-1 alpha-2, προέρχεται από IP κατά την έναρξη συνεδρίας)
Περιπτώσεις χρήσης:
-
Journeys καλωσορίσματος: χρησιμοποιήστε το
Session Startως έναυσμα journey για να προσεγγίσετε χρήστες όταν φτάνουν στον ιστότοπό σας. -
Τμήματα βάσει συνεδρίας: τα συμβάντα Session Start αποθηκεύονται ανά χρήστη, ώστε οι συνθήκες τμημάτων βάσει συμβάντων να μπορούν να τα μετρούν - για παράδειγμα, «εκτέλεσε
Session Startτουλάχιστον 10 φορές» (ενεργοί προχωρημένοι χρήστες) ή «δεν εκτέλεσεSession Startτις τελευταίες 7 ημέρες» (επανενεργοποίηση). -
Απόδοση καμπάνιας: φιλτράρετε τα analytics στο
Session Startκαι ομαδοποιήστε κατάutm_campaignγια να δείτε ποιες καμπάνιες φέρνουν τις περισσότερες συνεδρίες.
Απενεργοποίηση παρακολούθησης έναρξης συνεδρίας:
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_...',
trackSessionStart: false // Disable automatic session start events
});
Μηνύματα εντός εφαρμογής
Το SDK εμφανίζει τα in-app μηνύματα για εσάς. Οι επιλέξιμες καμπάνιες εμφανίζονται μόνες τους και οι εμφανίσεις, τα κλικ και οι απορρίψεις καταγράφονται αυτόματα.
Tokens παράδοσης (delivery tokens)
Όταν ο διακομιστής σερβίρει μια επιλέξιμη καμπάνια, εκδίδει επίσης ένα υπογεγραμμένο token παράδοσης μικρής διάρκειας. Το SDK το επιστρέφει όταν αναφέρει εμφάνιση, κλικ ή απόρριψη, και ο διακομιστής επαληθεύει την υπογραφή πριν καταγράψει οτιδήποτε.
Δεν χρειάζεται να κάνετε τίποτα - το SDK το χειρίζεται για εσάς. Τεκμηριώνεται επειδή ο διακομιστής μπορεί να ρυθμιστεί ώστε να το απαιτεί. Από προεπιλογή, μια αναφορά χωρίς token γίνεται ακόμη δεκτή - ο διακομιστής την καταγράφει ως client παλαιότερης έκδοσης - και μόνο όταν το backend τρέχει με IN_APP_REQUIRE_DELIVERY_TOKEN=true απορρίπτεται η ίδια αναφορά:
POST /v1/in-app/track (no deliveryToken)
{ "success": false, "error": "A delivery token is required" }
Ένα token που υπάρχει αλλά δεν επαληθεύεται - πλαστό, αλλοιωμένο ή ληγμένο - απορρίπτεται πάντα, ανεξάρτητα από τη ρύθμιση.
Το token είναι αυτό που κάνει μια εμφάνιση αξιόπιστη: χωρίς αυτό, οποιοσδήποτε κατέχει το SDK key - το οποίο περιλαμβάνεται σε κάθε εφαρμογή και σελίδα - θα μπορούσε να αναφέρει εμφανίσεις και κλικ για μια καμπάνια που δεν εμφανίστηκε ποτέ, και τα δεδομένα σας θα τα μετρούσαν.
Οι ιστότοποι που φορτώνουν το φιλοξενούμενο bundle από το https://sdk.joryio.com/web/1/joryio.min.js το λαμβάνουν αυτόματα.
Δύο είδη περιεχομένου
| Περιεχόμενο | Τι είναι | Πώς αποδίδεται |
|---|---|---|
| Native | Δομημένα δεδομένα - τίτλος, κείμενο, εικόνα, κουμπιά | Απλά στοιχεία DOM, εισαγόμενα ως κόμβοι κειμένου. Χωρίς iframe, χωρίς εκτέλεση script. |
| HTML | Κώδικας HTML και CSS γραμμένος από τον συντάκτη. Διατηρείται όπως γράφτηκε (αφαιρούνται μόνο τα <base> και <meta http-equiv="refresh">) | Ένα sandboxed iframe στη σελίδα σας, με νέο Content-Security-Policy για κάθε μήνυμα, όπου εκτελείται μόνο το script γέφυρας του SDK. |
Ενεργοποίηση μηνυμάτων HTML
Τα μηνύματα HTML είναι απενεργοποιημένα από προεπιλογή. Τα δικά σας scripts δεν εκτελούνται σε αυτά: το Joryio διατηρεί τον κώδικα όπως γράφτηκε, αλλά κάθε μήνυμα παίρνει νέο Content-Security-Policy με νέο nonce, ώστε να εκτελείται μόνο το script γέφυρας του SDK - τα <script> και οι handlers on* του συντάκτη μένουν ανενεργά, και το iframe δεν μπορεί να κάνει κλήσεις δικτύου (connect-src 'none') ούτε να υποβάλει φόρμες (form-action 'none'). Όμως αυτό το iframe μπορεί να εκτελέσει script στο origin της σελίδας σας, οπότε ο κίνδυνος που απομένει είναι ένα κενό σε αυτή την πολιτική, π.χ. ένας browser που δεν την εφαρμόζει - γι' αυτό η ενεργοποίηση είναι απόφαση της δικής σας ομάδας:
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_YOUR_KEY',
inApp: {
allowHtmlJsInAppMessages: true, // προεπιλογή: false
},
});
Αφήνοντάς το απενεργοποιημένο δεν απενεργοποιείτε τα in-app μηνύματα. Τα native μηνύματα συνεχίζουν να εμφανίζονται, επειδή είναι δεδομένα που γράφονται σε κόμβους κειμένου DOM - χωρίς κανέναν διερμηνέα. Οι καμπάνιες HTML παραλείπονται (με προειδοποίηση στο log όταν η καταγραφή είναι ενεργή). Μια καμπάνια που παραλείφθηκε δεν καταναλώνει εμφάνιση και παραμένει διαθέσιμη.
Αν το Content Security Policy σας απαγορεύει inline scripts ή περιεχόμενο σε iframe, αφήστε το απενεργοποιημένο και συντάξτε τις καμπάνιες σας ως native μηνύματα.
Στυλ σε native μηνύματα από το δικό σας CSS
Ένα native μήνυμα είναι πραγματικό DOM στη σελίδα σας, όχι iframe, οπότε μπορείτε να το μορφοποιήσετε όπως οτιδήποτε δικό σας. Ο renderer εκθέτει σταθερά άγκιστρα:
.joryio-inapp-native /* η κάρτα */
.joryio-inapp-native h2 /* τίτλος */
.joryio-inapp-native p /* σώμα */
.joryio-inapp-native img /* εικόνα */
.joryio-inapp-native button.primary /* πρώτο κουμπί */
.joryio-inapp-native button.secondary /* τα υπόλοιπα */
.joryio-inapp-close /* κλείσιμο */
.joryio-inapp-backdrop /* σκίαση */
.joryio-inapp-modal / -banner / -slideup / -fullscreen /* ανά τύπο */
Προτιμήστε τις μεταβλητές από τους επιλογείς. Ό,τι μπορεί να ορίσει μια
καμπάνια διαβάζεται από custom property, οπότε ορίζοντάς τες στο :root έχετε
ένα στυλ σπιτιού που η καμπάνια μπορεί ακόμη να παρακάμψει για ένα μήνυμα:
:root {
--joryio-inapp-bg: #0A1240;
--joryio-inapp-fg: #FFFFFF;
--joryio-inapp-primary: #00C8B7;
--joryio-inapp-primary-fg: #041028;
--joryio-inapp-radius: 18px;
--joryio-inapp-font: 'Inter', system-ui, sans-serif;
--joryio-inapp-size: 15px;
--joryio-inapp-align: start; /* start | center | end */
--joryio-inapp-title-weight: 700;
}
Η προτεραιότητα, από την υψηλότερη:
- όσα ορίζει η καμπάνια στο Style (optional) - γράφονται inline στην κάρτα
- οι δικές σας τιμές
--joryio-inapp-* - οι προεπιλογές του SDK, που είναι χρώματα συστήματος
Έτσι μια καμπάνια που δεν ορίζει τίποτα κληρονομεί το στυλ σας, ενώ μία που
ορίζει φόντο υπερισχύει μόνο για εκείνο το μήνυμα. Χωρίς !important πουθενά.
Αν πάλι χρησιμοποιήσετε τους επιλογείς, το φύλλο στυλ του SDK εισάγεται τη στιγμή
της εμφάνισης και άρα βρίσκεται μετά το δικό σας, οπότε κερδίζει στις ισοπαλίες.
Προσθέστε ειδικότητα - .joryio-inapp .joryio-inapp-native {…} - αντί για έναν
κανόνα μίας κλάσης.
Η κατεύθυνση ρυθμίζεται αυτόματα: η κάρτα φέρει dir="auto", οπότε ένα εβραϊκό ή
αραβικό μήνυμα στοιχίζεται δεξιά μέσα σε μια κατά τα άλλα αριστερόστροφη σελίδα.
Τύποι μηνυμάτων
- Modal - Στο κέντρο της οθόνης με σκίαση
- Banner - Στο επάνω μέρος της σελίδας
- Slide-Up - Μικρή ειδοποίηση από κάτω
- Full-Screen - Μήνυμα που καταλαμβάνει την οθόνη
- Custom - Η σελίδα σας αποφασίζει τη θέση
Επιλογές εμφάνισης
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_YOUR_KEY',
inApp: {
displayOptions: {
defaultPosition: 'bottom', // Custom-type messages only
defaultAnimation: 'slide', // 'fade' (default), 'slide' or 'none'
backdropColor: 'rgba(10, 18, 64, 0.6)',
closeButtonColor: '#ffffff',
zIndex: 2147483000,
},
},
});
Callbacks
Κάθε callback λαμβάνει το μήνυμα· η καμπάνια του είναι το message.campaign (message.campaign.id, message.campaign.name).
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_YOUR_KEY',
inApp: {
onMessageDisplay: (message) => console.log('shown', message.campaign.id),
onMessageClick: (message, action) => console.log('clicked', message.campaign.id, action), // action: the button id
onMessageDismiss: (message, action) => console.log('dismissed', message.campaign.id, action), // e.g. 'close_button'
},
});
Τα callbacks είναι ειδοποιήσεις: το SDK εξακολουθεί να σχεδιάζει το μήνυμα.
Ένα callback που ρίχνει εξαίρεση καταγράφεται και αγνοείται: το SDK εξακολουθεί να καταγράφει την εμφάνιση, το κλικ ή το κλείσιμο, και καθαρίζει.
Όταν δύο triggers ενεργοποιούνται μαζί (το ίδιο συμβάν δύο φορές, για παράδειγμα), το μήνυμα εμφανίζεται - και μετριέται - μία φορά.
Χειροκίνητος έλεγχος
await joryio.syncInAppCampaigns(); // fetch campaigns now
const campaigns = joryio.getInAppCampaigns(); // what is currently eligible
await joryio.displayInAppCampaign(campaignId); // show one now
joryio.dismissInAppMessage(campaignId); // close it
await joryio.trackInAppConversion(campaignId, eventName); // record a conversion
| Μέθοδος | Περιγραφή |
|---|---|
syncInAppCampaigns(attributeChanges?) | Ζητά τώρα από τον server τις καμπάνιες του επισκέπτη. Δεν κάνει τίποτα όσο η παρακολούθηση είναι ανενεργή ή η συναίνεση εκκρεμεί |
getInAppCampaigns() | Οι καμπάνιες που είναι διαθέσιμες τώρα, όπως συγχρονίστηκαν |
displayInAppCampaign(campaignId) | Εμφάνιση μιας από αυτές τώρα (το όριο συχνότητας εξακολουθεί να ισχύει) |
dismissInAppMessage(campaignId) | Κλείσιμο ενός μηνύματος που εμφανίζεται (καταγράφεται ως dismissed) |
trackInAppConversion(campaignId, eventName) | Καταγραφή μετατροπής για μια καμπάνια |
Πότε ένα μήνυμα μετρά ως εμφανισμένο
Ένα μήνυμα μετρά ως εμφανισμένο - αναφέρεται το in_app.displayed και καταναλώνεται το όριο συχνότητας της καμπάνιας - μόνο όταν το άτομο μπορούσε πράγματι να το δει. Ο χρόνος που πρέπει να μείνει στην οθόνη είναι το IN_APP_DISPLAY_DWELL_MS (1000 ms), η ίδια σταθερά σε κάθε Joryio SDK.
- Ένα μήνυμα εμφανίζεται μόνο αφού η σελίδα ολοκληρώσει τη φόρτωση και ηρεμήσει, και ποτέ ενώ η σελίδα αποφορτώνεται (ανακατεύθυνση, μετάβαση μέσω συνδέσμου, κλείσιμο καρτέλας).
- Μετρά ως εμφανισμένο αφού μείνει στην οθόνη 1 δευτερόλεπτο με την καρτέλα ορατή. Αν η καρτέλα κρυφτεί νωρίτερα, το δευτερόλεπτο ξεκινά από την αρχή όταν γίνει ξανά ορατή.
- Αν η σελίδα αποφορτωθεί νωρίτερα - ανακατεύθυνση μετά τη σύνδεση, σύνδεσμος αποσύνδεσης - δεν αναφέρεται τίποτα, το όριο δεν καταναλώνεται και το μήνυμα εμφανίζεται ξανά στην επόμενη σελίδα.
- Ένα κλικ ή κλείσιμο νωρίτερα μετρά ως προβολή: αναφέρεται πρώτα το
displayedκαι μετά το κλικ ή η απόρριψη. Η αφαίρεση του μηνύματος από κώδικα (dismissInAppMessage,reset()) νωρίτερα δεν αναφέρει τίποτα. - Το
onDisplayκαλείται όταν το μήνυμα μετρά ως εμφανισμένο, μαζί με την αναφορά - όχι όταν μπαίνει στην οθόνη. Το πακέτο εξάγει τοIN_APP_DISPLAY_DWELL_MS.
Ιδιωτικότητα και συναίνεση
Δύο ανεξάρτητοι διακόπτες αποφασίζουν αν συλλέγεται κάτι: η συναίνεση (η απάντηση στο banner cookies) και η απενεργοποίηση που επιλέγει ο ίδιος ο επισκέπτης. Το SDK συλλέγει μόνο όταν η συναίνεση έχει δοθεί και ο επισκέπτης δεν έχει απενεργοποιήσει την παρακολούθηση - κάθε «όχι» υπερισχύει.
joryio.updateConsent('granted'); // or 'denied' or 'pending'
joryio.optOut(); // remembered across page loads until optIn()
joryio.optIn();
joryio.ready(function (sdk) {
sdk.getTrackingConsent(); // 'granted' | 'denied' | 'pending'
sdk.isUserOptedOut(); // the opt-out switch only
});
| Κατάσταση | Τι κάνει το SDK |
|---|---|
Συναίνεση granted (ή χωρίς τιμή, χωρίς αποθηκευμένη άρνηση) | Συλλέγει και στέλνει κανονικά |
Συναίνεση pending | Συλλέγει τοπικά και δεν στέλνει τίποτα - ούτε Session Start, ούτε συγχρονισμό in-app, ούτε εγγραφή push - μέχρι το updateConsent('granted') να τα απελευθερώσει. Το updateConsent('denied') τα απορρίπτει. Ό,τι κρατιέται αποθηκεύεται στο localStorage, ώστε μια επαναφόρτωση να μην το χάνει: συμβάντα και identify() (έως maxQueueSize συμβάντα), εγγραφές γνωρισμάτων (έως 500) και αλλαγές alias και συνδρομών (έως 200). Εξαίρεση αποτελούν οι καταργήσεις συνδρομών: στέλνονται κανονικά. Ο service worker του web push δεν αναφέρει στο μεταξύ παραδόσεις ή κλικ |
Συναίνεση denied | Δεν συλλέγει τίποτα και καθαρίζει ό,τι υπάρχει στην ουρά. Ο service worker σταματά να αναφέρει παραδόσεις και κλικ |
optOut() | Δεν συλλέγει τίποτα, καθαρίζει τα συμβάντα σε ουρά και τις εκκρεμείς εγγραφές γνωρισμάτων, alias και εγγραφής συνδρομών (οι καταργήσεις συνδρομών παραδίδονται κανονικά), και αποθηκεύεται ώστε να επιβιώνει μιας επαναφόρτωσης. Ο service worker του web push εξακολουθεί να εμφανίζει ειδοποιήσεις αλλά σταματά να αναφέρει παραδόσεις και κλικ |
| Do Not Track | Θεωρείται απενεργοποίηση όσο το respectDoNotTrack είναι true (η προεπιλογή) |
Πώς συμπεριφέρονται οι δύο διακόπτες:
- Το
deniedαποθηκεύεται. Ισχύει στις επόμενες προβολές σελίδας μέχρι τοupdateConsent('granted')ή ένα ρητόtrackingConsent: 'granted'στη ρύθμιση του init. Αν αφήσετε τοtrackingConsentχωρίς τιμή, μια αποθηκευμένη άρνηση διατηρείται - γι' αυτό η επιλογή δεν έχει προεπιλογή. - Το
pendingισχύει για μία προβολή σελίδας. Δεν αποθηκεύεται ποτέ και δεν υπερισχύει ποτέ μιας αποθηκευμένης άρνησης. - Η συναίνεση δεν αναιρεί ποτέ μια απενεργοποίηση. Το
updateConsent('granted')δεν αναιρεί τοoptOut()· μόνο τοoptIn(). ΤαoptOut()καιoptIn()δεν αλλάζουν ποτέ την αποθηκευμένη συναίνεση. - Το προφίλ καταγράφει την απενεργοποίηση. Όταν αλλάζει ο διακόπτης απενεργοποίησης - και με
optOut: trueστο init - το SDK γράφει τοtracking_opted_out(trueήfalse) στο προφίλ, με τα ID του επισκέπτη που έκανε την επιλογή, και το ξαναστέλνει σύμφωνα με τον κανόνα επανάληψης. Τίποτα δεν στέλνεται όσο ο διακόπτης δεν αλλάζει. Τοtrueστέλνεται ακόμη και όσο η συναίνεση είναιdeniedήpending· τοfalseπεριμένει μέχρι να επιτραπεί η παρακολούθηση. - Οι ανακλήσεις παραδίδονται πάντα. Μια κατάργηση συνδρομής (
SubscriptionStatus.UNSUBSCRIBED,removeFromSubscriptionGroup()), η ένδειξηtracking_opted_outκαι μια κατάργηση καταχώρησης push στέλνονται ακόμη και όσο ο επισκέπτης έχει απενεργοποιήσει την παρακολούθηση, με τη συναίνεσηdeniedήpending, και μετά απόwipeData(). Κάθε άλλη εγγραφή σταματά μαζί τους. - Μια συνεδρία που ξεκίνησε με την παρακολούθηση απενεργοποιημένη παίρνει το ένα Session Start της όταν δοθεί συναίνεση ή όταν ο επισκέπτης την ενεργοποιήσει ξανά.
- Το
identify()με την παρακολούθηση απενεργοποιημένη (η συναίνεση απορρίφθηκε ή ο επισκέπτης έκανε opt-out) δεν στέλνει τίποτα και δεν γράφει τίποτα σε προφίλ. Το αναγνωριστικό χρήστη κρατιέται μόνο σε αυτή τη συσκευή, ώστε μια μεταγενέστερη διαγραφή συνδρομής ή ένα opt-out να φτάσει σε αυτό το άτομο και όχι σε ένα ανώνυμο προφίλ· το κανονικόidentify()εκτελείται όταν η παρακολούθηση επιτραπεί ξανά. Ταreset()καιwipeData()το ξεχνούν. Με τη συναίνεση ή το opt-in, τοidentify()που κρατήθηκε τρέχει πριν από το Session Start μιας συνεδρίας που ξεκίνησε στο μεταξύ, ώστε η συνεδρία αυτή να ανήκει στον νέο χρήστη. Το ID που κρατήθηκε χρησιμοποιείται σε κάθε απόσυρση: κατάργηση συνδρομής, κατάργηση συνδρομής ομάδας, τον δείκτηtracking_opted_outκαι τοpush.unsubscribe(). Έναidentify()όταν η παρακολούθηση επιτρέπεται το αντικαθιστά, και ένα ρητόuserIdστις ρυθμίσεις αρχικοποίησης υπερισχύει. - Ακολουθούν όλες οι ανοιχτές καρτέλες. Ένα opt-out, μια αλλαγή συναίνεσης, ένα
reset()ή έναidentify()σε μία καρτέλα του ιστότοπού σας ισχύει αμέσως και στις άλλες ανοιχτές καρτέλες, όχι μόνο στην επόμενη φόρτωσή τους. Μια αποσύνδεση σε μία καρτέλα είναι πλήρεςreset()στις άλλες: περνούν στον νέο επισκέπτη και στη νέα συνεδρία, και οι εγγραφές που έκαναν για τον χρήστη που αποχώρησε παραμένουν δικές του. Μια συναίνεση σε μία καρτέλα αποδεσμεύει και μια καρτέλα που περιμένει σεpending. Μια άλλη καρτέλα ή ένα script που καλείlocalStorage.clear()δεν αίρει ποτέ ένα opt-out ή μια άρνηση - η καρτέλα την κρατά και την αποθηκεύει ξανά. Οι εγγραφές προφίλ και τα tokens των αποσυνδεδεμένων χρηστών που κρατά κάθε καρτέλα στοlocalStorageσυγχωνεύονται και καμία καρτέλα δεν τα αντικαθιστά. Ακολουθείται και ο χρήστης που κρατά έναidentify()για τις ανακλήσεις ενώ η παρακολούθηση είναι απενεργοποιημένη. Ένα ρητόupdateConsent('granted')ήoptIn()αμέσως μετά από ένα τέτοιοlocalStorage.clear()είναι νεότερο από την αποθηκευμένη απόφαση και υπερισχύει σε όλες τις καρτέλες. Μια εγγραφή προφίλ που άλλη καρτέλα έχει ήδη παραδώσει, ή έχει αντικαταστήσει με νεότερη, δεν στέλνεται ποτέ από αυτή την καρτέλα, και τοwipeData()σε μία καρτέλα απορρίπτει και τις εκκρεμείς εγγραφές των άλλων καρτελών (εκτός από τις ανακλήσεις). - Με το ασύγχρονο snippet, αυτές οι κλήσεις ισχύουν πριν το
initστείλει οτιδήποτε - δείτε Ασύγχρονο snippet.
Διαγραφή τοπικών δεδομένων
await joryio.wipeData();
Διαγράφει ό,τι κρατά το SDK για τον επισκέπτη σε αυτόν τον browser: την ταυτότητα (νέο ανώνυμο αναγνωριστικό, χωρίς αναγνωριστικό χρήστη), τα συμβάντα σε ουρά και ένα εκκρεμές identify(), τις εκκρεμείς εγγραφές γνωρισμάτων, alias και συνδρομών, την κατάσταση in-app και το ιστορικό εμφανίσεων, τη συνεδρία, τα δεδομένα UTM, το αναγνωριστικό συσκευής και τη συνδρομή push (καταργείται και στο Joryio· μένει καταργημένη μέχρι να κληθεί ξανά το push.subscribe()). Οι ανακλήσεις που ακόμη περιμένουν - μια κατάργηση συνδρομής, η ένδειξη απενεργοποίησης, η κατάργηση καταχώρησης push - παραδίδονται κανονικά, με τα ID με τα οποία έγιναν. Κρατά την απενεργοποίηση και μια άρνηση συναίνεσης, και δεν απενεργοποιεί κανέναν - γι' αυτό υπάρχει το optOut(). Η παρακολούθηση συνεχίζει ως νέος ανώνυμος επισκέπτης, σε νέα συνεδρία με δικό της Session Start.
Αναφορά API
Αρχικοποίηση
const joryio = new JoryioSDK(config)
Αρχικοποιήστε το SDK με τις ρυθμίσεις σας. Ο constructor επιστρέφει singleton - αν το κατασκευάσετε δεύτερη φορά, επιστρέφεται το υπάρχον instance, το οποίο επιστρέφει και το JoryioSDK.getInstance() (ή null πριν από την αρχικοποίηση).
Το SDK δεν πετά ποτέ σφάλμα στη σελίδα σας. Ένα sdkKey που λείπει ή είναι λανθασμένο καταγράφεται μία φορά, σε οποιοδήποτε επίπεδο καταγραφής, και αυτό το instance αγνοεί κάθε κλήση· ένα όρισμα null εκεί που χρειάζεται τιμή καταγράφεται και αγνοείται.
Identify
joryio.identify(userId)
Συνδέει ένα αναγνωριστικό χρήστη με την τρέχουσα συνεδρία.
Παράμετροι:
userId(string): Μοναδικό αναγνωριστικό του χρήστη
Παράδειγμα:
joryio.identify('user_123');
joryio.setAttributes({
name: 'John Doe',
plan: 'premium',
});
Track
joryio.track(eventName, properties?)
Παρακολουθήστε ένα προσαρμοσμένο συμβάν με προαιρετικές ιδιότητες.
Παράμετροι:
eventName(string): Όνομα του συμβάντοςproperties(object, προαιρετικό): Ιδιότητες συμβάντος
Παράδειγμα:
joryio.track('Plan Upgraded', {
from_plan: 'basic',
to_plan: 'premium',
});
Για αγορές χρησιμοποιήστε το εργαλείο e-commerce, που στέλνει τα κλειδιά που διαβάζουν οι αναφορές εσόδων (orderId και total σε ένα συμβάν Order Completed):
joryio.ecommerce({ currency: 'USD' }).purchase({
orderId: 'order_789',
items: [{ productId: 'SKU123', name: 'Blue Shirt', price: 49.99, quantity: 3 }],
value: 149.99, // sent as `total`
});
Δείτε το Παρακολούθηση e-commerce για όλες τις μεθόδους του. Κάθε βοηθητική μέθοδος ελέγχει τα υποχρεωτικά ορίσματά της - ένα productId, ένα orderId, μια πεπερασμένη τιμή παραγγελίας value, έναν πίνακα items - και όταν λείπει κάποιο καταγράφει μια προειδοποίηση και δεν στέλνει τίποτα (ποτέ μια κενή παραγγελία ή παραγγελία μηδενικής αξίας). Δεν πετά ποτέ εξαίρεση στη σελίδα σας. Το ecommerce() δέχεται μία επιλογή, το currency (προεπιλογή 'USD').
Ενεργοποιήστε την αυτόματη παρακολούθηση προβολών σελίδας:
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_...',
trackPageViews: true
});
Προσθήκη alias
joryio.addAlias(aliasLabel, aliasName)
Προσθέστε ένα alias με ετικέτα σε αυτόν τον επισκέπτη. Λειτουργεί και πριν από το identify(): το αίτημα μεταφέρει το ανώνυμο ID (και το ID χρήστη μετά την αναγνώριση), και το alias συνδέεται με το προφίλ στο οποίο αντιστοιχούν.
Για να συνδέσετε έναν ανώνυμο επισκέπτη με το ID χρήστη του, καλέστε το identify(). Στην πρώτη σύνδεση το ανώνυμο προφίλ γίνεται το προφίλ του χρήστη, μαζί με όλο το ιστορικό· αν ο χρήστης έχει ήδη προφίλ, το ανώνυμο συγχωνεύεται σε αυτό. Το alias() χωρίς ετικέτα αφαιρέθηκε στην έκδοση 1.3.0.
Παράδειγμα:
joryio.addAlias('crm', 'crm_98765');
Reset
joryio.reset()
Αποσυνδέστε τον τρέχοντα χρήστη. Ο επισκέπτης παίρνει νέο ανώνυμο ID και νέα συνεδρία· τα μηνύματα in-app του προηγούμενου χρήστη καθαρίζονται και το token ταυτοποίησης SDK του ξεχνιέται· οι εγγραφές γνωρισμάτων, alias και συνδρομών του που δεν έχουν ακόμη επιβεβαιωθεί στέλνονται κανονικά, με τα δικά του ID - ποτέ με του επόμενου επισκέπτη· τα δεδομένα UTM (και της πρώτης και της τελευταίας επαφής) καθαρίζονται· οι καμπάνιες in-app ανακτώνται για τον νέο επισκέπτη· και μια υπάρχουσα συνδρομή web push εγγράφεται ξανά με το νέο ανώνυμο ID, ώστε τα push του προηγούμενου χρήστη να σταματήσουν να φτάνουν σε αυτόν τον browser.
Η νέα ταυτότητα ισχύει μόλις επιστρέψει το reset(). Το promise που επιστρέφει καλύπτει μόνο την αποστολή όσων ήταν ήδη στην ουρά (κάθε συμβάν κρατά τα ID με τα οποία καταγράφηκε), οπότε το reset(); identify(nextUser) είναι ασφαλές και χωρίς await.
Παράδειγμα:
// On user logout
function handleLogout() {
joryio.reset();
// ... other logout logic
}
Λήψη ανώνυμου ID
joryio.getAnonymousId()
Επιστρέφει το τρέχον ανώνυμο ID - το ID που η Joryio αναθέτει σε κάθε επισκέπτη πριν ταυτοποιηθεί. Δημιουργείται κατά την πρώτη αρχικοποίηση, αποθηκεύεται στο localStorage και παραμένει σταθερό σε όλες τις φορτώσεις σελίδων για όλη τη διάρκεια ζωής του ανώνυμου επισκέπτη (το reset() το αναδημιουργεί κατά την αποσύνδεση). Είναι ακριβώς το anonymousId που επισυνάπτεται σε κάθε συμβάν που στέλνει το track(), οπότε χρησιμοποιήστε το για να συνδέσετε ένα συμβάν από την πλευρά του διακομιστή ή μια εγγραφή συγκατάθεσης με το ίδιο προφίλ.
Επιστρέφει:
string- το ανώνυμο ID (πάντα παρόν)
Με το ασύγχρονο snippet, το window.joryio είναι μια ουρά εντολών μέχρι να ολοκληρωθεί η φόρτωση του SDK, και μια εντολή στην ουρά δεν μπορεί να επιστρέψει τιμή. Διαβάστε το ID στο επιλυμένο στιγμιότυπο μετά τη φόρτωση, ή μέσα από το ready() (παρακάτω).
Παράδειγμα:
joryio.ready(function (sdk) {
const anonId = sdk.getAnonymousId();
fetch('/consent', { method: 'POST', body: JSON.stringify({ anonymousId: anonId }) });
});
Λήψη ID χρήστη
joryio.getUserId()
Επιστρέφει το τρέχον ID ταυτοποιημένου χρήστη, ή null αν ο επισκέπτης είναι ακόμη ανώνυμος (δηλαδή δεν έχει κληθεί το identify()).
Επιστρέφει:
string | null
Παράδειγμα:
joryio.ready(function (sdk) {
const userId = sdk.getUserId(); // null μέχρι να καλέσετε το joryio.identify(...)
});
Ready
joryio.ready(callback)
Εκτελεί το callback(sdk) αφού φορτωθεί και αρχικοποιηθεί το SDK. Αυτός είναι ο ασφαλής τρόπος για να διαβάσετε μια τιμή (όπως getAnonymousId() / getUserId()) που ένα stub στην ουρά δεν μπορεί να επιστρέψει πριν τη φόρτωση. Το callback λαμβάνει το στιγμιότυπο του SDK· αν το SDK έχει ήδη φορτωθεί, εκτελείται αμέσως.
Παράδειγμα:
joryio.ready(function (sdk) {
console.log('anon:', sdk.getAnonymousId(), 'user:', sdk.getUserId());
});
Λήψη δεδομένων UTM
joryio.getUTMData()
Επιστρέφει τις τρέχουσες παραμέτρους UTM, καθώς και εκείνες της πρώτης και της τελευταίας επαφής.
Επιστρέφει:
- Ένα αντικείμενο με δεδομένα UTM
current,firstTouchκαιlastTouch
Παράδειγμα:
const utmData = joryio.getUTMData();
console.log(utmData.current?.utm_source); // "google"
console.log(utmData.firstTouch?.utm_campaign); // "awareness_campaign"
console.log(utmData.lastTouch?.utm_campaign); // "conversion_campaign"
Ενημέρωση UTM
joryio.updateUTM()
Ενημερώστε μη αυτόματα τις παραμέτρους UTM από το τρέχον URL. Χρήσιμο για Single Page Applications που αλλάζουν URL χωρίς ανανέωση της σελίδας.
Παράδειγμα:
// React Router
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function App() {
const location = useLocation();
useEffect(() => {
joryio.updateUTM();
}, [location]);
}
// Vue Router
router.afterEach(() => {
joryio.updateUTM();
});
Γνωρίσματα
joryio.setAttributes(attributes)
joryio.setAttribute(key, value)
joryio.incrementAttribute(key, by?)
joryio.unsetAttribute(key)
- Το
setAttributes({ plan: 'pro', city: 'Athens' })ορίζει πολλά μαζί· τοsetAttribute('plan', 'pro')ορίζει ένα. - Μια τιμή
nullήundefinedαφαιρεί το γνώρισμα, ακριβώς όπως τοunsetAttribute(key). - Μια τιμή που δεν μπορεί να μεταφέρει το JSON -
NaN,Infinity, έναBigInt, μια συνάρτηση, ένα αντικείμενο που αναφέρεται στον εαυτό του - απορρίπτεται με προειδοποίηση στο log: το κλειδί αυτό παραλείπεται και η υπόλοιπη κλήση συνεχίζει. Το ίδιο ισχύει για τις ιδιότητες συμβάντων. Μία λανθασμένη τιμή δεν καθυστερεί ποτέ άλλες εγγραφές. - Το
incrementAttribute('logins', 1)προσθέτει σε έναν αριθμό στον server (προεπιλογή1), οπότε δύο καρτέλες δεν αντικαθιστούν ποτέ η μία την καταμέτρηση της άλλης. - Εγγραφές που γίνονται κοντά χρονικά στέλνονται σε ένα αίτημα. Περιμένουν πρώτα να φτάσει στον server ένα εκκρεμές
identify(), κρατιούνται στοlocalStorageμέχρι να επιβεβαιωθούν, και μια εγγραφή που απέτυχε ξαναστέλνεται σύμφωνα με τον κανόνα επανάληψης. - Μια εγγραφή κρατά την ταυτότητα με την οποία έγινε: μία που έγινε λίγο πριν από το
identify()στέλνεται με αυτό το ID χρήστη μόλις το identify φτάσει στον server· μία του χρήστη A που ακόμη περιμένει όταν καλείται τοidentify('B')ή τοreset()πηγαίνει και πάλι στον A.
Γνωρίσματα πίνακα
joryio.addToArray(key, value)
joryio.removeFromArray(key, value)
Χειριστείτε αποτελεσματικά γνωρίσματα τύπου πίνακα.
Παράμετροι:
key(string): Όνομα γνωρίσματοςvalue(any): Τιμή προς προσθήκη ή αφαίρεση
Παράδειγμα:
// Add tags to user
joryio.addToArray('tags', 'vip');
joryio.addToArray('tags', 'premium');
// Result: tags = ['vip', 'premium']
// Add duplicate (no-op, prevents duplicates)
joryio.addToArray('tags', 'vip');
// Result: tags = ['vip', 'premium'] (unchanged)
// Remove tag
joryio.removeFromArray('tags', 'vip');
// Result: tags = ['premium']
// Common use cases
joryio.addToArray('interests', 'technology');
joryio.addToArray('purchasedProducts', 'prod_123');
joryio.addToArray('featureFlags', 'beta-access');
Συμπεριφορά:
- Το
addToArray()προσθέτει την τιμή μόνο αν δεν υπάρχει ήδη (αποτρέπει διπλότυπα) - Το
addToArray()δημιουργεί νέο πίνακα αν το γνώρισμα δεν υπάρχει - Το
removeFromArray()αφαιρεί όλες τις εμφανίσεις της τιμής - Οι αλλαγές συγχρονίζονται αυτόματα με το backend, τόσο για αναγνωρισμένους όσο και για ανώνυμους χρήστες
Οι κλήσεις στο ίδιο γνώρισμα διατηρούν τη σειρά τους: δύο κλήσεις addToArray() στο ίδιο κλειδί φτάνουν και οι δύο στον διακομιστή, και ένα addToArray() που ακολουθείται από removeFromArray() του ίδιου κλειδιού στέλνονται το ένα μετά το άλλο, ποτέ στο ίδιο αίτημα.
Flush
await joryio.flush()
Στέλνει τώρα ό,τι υπάρχει στην ουρά αντί να περιμένει την επόμενη παρτίδα. Περιμένει επίσης μια αποστολή που ήδη εκτελείται.
Το flush() παρακάμπτει το backoff του ίδιου του SDK, αλλά ποτέ ένα Retry-After που ζήτησε το API.
Πληροφορίες ταυτότητας και συνεδρίας
joryio.getIdentity() // { userId, anonymousId, attributes }
joryio.getSessionInfo() // { sessionId, sessionStart, lastActivity, isNewSession }
Το attributes περιέχει ό,τι όρισε αυτή η σελίδα (δεν διαβάζεται από τον server).
Κατάσταση συναίνεσης και απενεργοποίησης
joryio.getTrackingConsent() // 'granted' | 'denied' | 'pending'
joryio.isUserOptedOut() // true after optOut(), until optIn()
Το isUserOptedOut() αντικατοπτρίζει μόνο την απενεργοποίηση του ίδιου του επισκέπτη - όχι τη συναίνεση ούτε το Do Not Track. Δείτε Ιδιωτικότητα και συναίνεση. Με το ασύγχρονο snippet, διαβάστε τα μέσα στο ready().
Destroy
await joryio.destroy()
Στέλνει ό,τι υπάρχει στην ουρά, σταματά κάθε χρονοδιακόπτη, αφαιρεί τους listeners της σελίδας και ξεφορτώνει τα plugins. Ένα μεταγενέστερο new JoryioSDK(config) ξεκινά νέο instance.
Web push
Το web push χρειάζεται έναν service worker στο δικό σας origin (το απαιτούν οι browsers). Φιλοξενήστε στη ρίζα του ιστότοπού σας ένα αρχείο με όνομα joryio-sw.js που περιέχει μία γραμμή:
importScripts('https://sdk.joryio.com/web/1/joryio-sw.js');
Μετά ζητήστε άδεια από μια ενέργεια του χρήστη, π.χ. κλικ σε κουμπί:
if (joryio.push.isSupported() && joryio.push.getPermissionState() === 'notDetermined') {
button.onclick = () => joryio.push.subscribe();
}
| Μέθοδος | Περιγραφή |
|---|---|
push.isSupported() | Αν αυτός ο browser υποστηρίζει καθόλου web push (χρειάζονται HTTPS, service worker και το Push API) |
push.getPermissionState() | 'granted', 'denied', 'notDetermined' ή 'unavailable' - τα ίδια ονόματα σε κάθε SDK του Joryio |
push.prepare(options?) | Εγγράφει τον service worker και ανακτά το κλειδί εκ των προτέρων, ώστε το μεταγενέστερο subscribe() να ζητά άδεια αμέσως. Δεν ζητά ποτέ άδεια |
push.subscribe(options?) | Ζητά άδεια (αν χρειάζεται), κάνει εγγραφή και καταχωρεί αυτόν τον browser στο Joryio. Επιστρέφει τη συνδρομή ή null |
push.getExistingSubscription(options?) | Η τρέχουσα συνδρομή, χωρίς αίτημα άδειας |
push.unsubscribe(options?) | Αφαιρεί τη συνδρομή του browser και τη διαγράφει από το Joryio. Μένει ανενεργή στις επόμενες επισκέψεις μέχρι να κληθεί ξανά το subscribe(). Δεν απορρίπτεται ποτέ· επιστρέφει false όταν δεν υπήρχε κάτι να αφαιρεθεί |
Το options δέχεται swPath (προεπιλογή '/joryio-sw.js') και scope (προεπιλογή '/') αν φιλοξενείτε τον worker αλλού.
Δεν χρειάζεται να καλέσετε ξανά το subscribe() σε επόμενες επισκέψεις. Όταν η άδεια έχει ήδη δοθεί, το SDK ελέγχει τη συνδρομή του browser κατά τη φόρτωση και την καταχωρεί ξανά αν ο browser την άλλαξε, αν άλλαξε το κλειδί του workspace σας (εγγράφεται ξανά χωρίς αίτημα άδειας) ή μετά από reset() - εκτός αν κλήθηκε το unsubscribe(). Κάθε καταχώρηση φέρει το σταθερό ID συσκευής του SDK. Τίποτα δεν καταχωρείται όσο η παρακολούθηση είναι απενεργοποιημένη ή η συναίνεση εκκρεμεί. Η κατάργηση καταχώρησης του unsubscribe() είναι ανάκληση: στέλνεται ακόμη και τότε, κρατιέται μέχρι να απαντήσει το API και ξαναστέλνεται σύμφωνα με τον κανόνα επανάληψης. Μια νέα καταχώρηση του ίδιου browser ακυρώνει μια κατάργηση καταχώρησης που δεν έχει σταλεί ακόμη.
Ο service worker εμφανίζει κάθε push με τον τίτλο, το κείμενο, το εικονίδιο, την εικόνα, το badge, τις ενέργειες, το tag (ένα νεότερο push με το ίδιο tag αντικαθιστά αυτό που φαίνεται στην οθόνη) και το requireInteraction (μένει μέχρι να κλείσει), αναφέρει την παράδοσή του και καταγράφει το κλικ. Διαβάζει αυτά τα κλειδιά από τα data του push, τα ίδια ονόματα που διαβάζουν τα SDK Android και iOS:
| Κλειδί | Αποτέλεσμα |
|---|---|
trackingId | Χρησιμοποιείται για την απόδειξη παράδοσης και την παρακολούθηση κλικ. Λείπει στις δοκιμαστικές αποστολές, που δεν μετρώνται |
jry_deep_link | Η σελίδα που ανοίγει ένα κλικ (η ρίζα του ιστότοπου αν λείπει) |
jry_image_url | Μεγάλη εικόνα, σε browsers που την εμφανίζουν |
jry_api_origin | Πού στέλνει ο worker την απόδειξη παράδοσης και το κλικ |
jry_campaign_id | Το ID της καμπάνιας, ή το ID του ταξιδιού για αποστολή από ταξίδι. Πληροφοριακό |
Ταυτοποίηση SDK
Προαιρετική. Όταν είναι ενεργή, κάθε αίτημα φέρει ένα JWT που εκδίδει το backend σας, ως κεφαλίδα X-Joryio-Auth, και το SDK το ανανεώνει όταν το API το απορρίπτει. Το token αποδεικνύει ποιος είναι ένας αναγνωρισμένος επισκέπτης: οι ανώνυμοι επισκέπτες συνεχίζουν να λειτουργούν χωρίς αυτό.
Το backend σας υπογράφει το JWT με ένα κλειδί που καταχωρείτε στο Joryio, με sub ίδιο με το ID χρήστη που περνάτε στο identify(). Ένα λανθασμένο, ληγμένο ή απόν token απαντάται με 401 { error: 'sdk_authentication_error', reason: 'missing' | 'invalid' | 'expired' | 'sub_mismatch' }.
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_YOUR_KEY',
enableSdkAuthentication: true,
sdkAuthenticationToken: await mintJoryioJwt(),
});
// Fires on a 401 sdk_authentication_error. Return a fresh token (or call
// setSdkAuthenticationToken); the failed request is then retried once.
joryio.setSdkAuthenticationErrorCallback(async (info) => {
// info = { reason, endpoint, userId }
return await mintJoryioJwt();
});
// Replace the token at any time, e.g. before it expires
joryio.setSdkAuthenticationToken(await mintJoryioJwt());
| Μέθοδος | Περιγραφή |
|---|---|
setSdkAuthenticationToken(token) | Ορίζει ή αντικαθιστά το JWT. Αγνοείται (με προειδοποίηση) αν το enableSdkAuthentication δεν είναι true |
setSdkAuthenticationErrorCallback(callback) | Το callback(info) εκτελείται όταν ένα token απορρίπτεται· επιστρέψτε νέο token ή promise για ένα |
- Το callback ενεργοποιείται σε ένα
401ταυτοποίησης SDK για αίτημα του τρέχοντος χρήστη όσο τοenableSdkAuthenticationείναι ενεργό - ακόμη και πριν οριστεί οποιοδήποτε token (reason: 'missing'). Δεν ενεργοποιείται ποτέ για αίτημα ενός χρήστη που έχει στο μεταξύ αποσυνδεθεί, ώστε να μην μπορεί να κάνει την εφαρμογή σας να αποσυνδέσει το άτομο που τη χρησιμοποιεί τώρα. - Μία άμεση επανάληψη. Το αίτημα που απέτυχε ξαναστέλνεται μία φορά με το νέο token. Αν δεν υπάρχει callback, αν δεν επιστρέψει token ή αν αποτύχει και η επανάληψη, τίποτα δεν χάνεται: τα συμβάντα μένουν στην ουρά και ξαναστέλνονται με το κανονικό backoff, με όποιο token έχει οριστεί τότε. Μια εγγραφή προφίλ ξαναδοκιμάζεται το πολύ 10 φορές.
- Το token ενός χρήστη που αποσυνδέθηκε κρατιέται για ό,τι άφησε. Στο
reset()- ή στοidentify()άλλου χρήστη - το token παύει να είναι της συνεδρίας αλλά μένει δεμένο με τα συμβάντα και τις εγγραφές του χρήστη που φεύγει που βρίσκονται στην ουρά, αποθηκεύεται μαζί τους στοlocalStorageώστε να μη χάνεται σε επαναφόρτωση, και διαγράφεται μόλις το τελευταίο από αυτά παραδοθεί ή απορριφθεί. Ένα token που ορίσατε για τον χρήστη που μπαίνει πριν καλέσετε τοidentify()αναγνωρίζεται από τοsubτου και παραμένει δικό του. Ο ορισμός ενός token μεsubάλλου χρήστη κρατά στην άκρη με τον ίδιο τρόπο το token που αντικαθιστά, οπότε η σειρά δεν έχει σημασία: ό,τι άφησε ο χρήστης που αποχώρησε κρατά το δικό του token. Η ανανέωση του token του ίδιου χρήστη δεν κρατά τίποτα στην άκρη. Ένα token που κρατήθηκε στην άκρη διατηρείται τουλάχιστον ένα λεπτό και το πολύ 30 ημέρες. Ένα token του οποίου τοsubδεν είναι ο τρέχων χρήστης κρατιέται έτσι για εκείνον τον χρήστη και όταν δεν είναι συνδεδεμένος κανείς, μέχρι τοidentify()να το κάνει token της συνεδρίας· τοwipeData()διαγράφει ένα τέτοιο token. - Ένας χρήστης ανά αίτημα. Τα συμβάντα δεν ομαδοποιούνται ποτέ πέρα από μια αλλαγή χρήστη. Το
reset()βγάζει το token από τη συνεδρία· μένει με ό,τι έχει βάλει στην ουρά ο χρήστης που φεύγει. Συμβάντα και εγγραφές που ο χρήστης που αποσυνδέεται είχε ήδη βάλει στην ουρά εξακολουθούν να στέλνονται με το δικό του token, οπότε μια κανονική αποσύνδεση δεν χάνει τίποτα. Συμβάντα, έναidentify()και εγγραφές προφίλ ενός χρήστη που δεν είναι πια ο τρέχων, που απορρίφθηκαν με οποιοδήποτε401ταυτοποίησης SDK (missing,sub_mismatch,expiredήinvalid), διαγράφονται - δεν θα οριστεί ξανά token για αυτόν τον χρήστη - ώστε να μην καθυστερούν ποτέ τα αιτήματα του επόμενου χρήστη. Ένα αίτημα φέρει μόνο token του οποίου τοsubείναι ο χρήστης του αιτήματος: το τρέχον token όταν είναι δικό του, αλλιώς το token που φυλάχτηκε γι' αυτόν, αλλιώς κανένα - έτσι ένα token που ορίζετε για τον επόμενο χρήστη πριν από τοidentify()δεν φεύγει ποτέ με τα αιτήματα του τρέχοντος χρήστη. Τα ανώνυμα αιτήματα δεν φέρουν token.
Προτιμήσεις συνδρομών
Το αντικείμενο user, μόνο για εγγραφή, ενημερώνει τις συνδρομές μάρκετινγκ ενός επισκέπτη. Οι αλλαγές περιμένουν να φτάσει στον server ένα εκκρεμές identify(), φέρουν και το ID χρήστη και το ανώνυμο ID, και ξαναστέλνονται αν η επαφή δεν υπάρχει ακόμα. Μια αλλαγή που έγινε πριν από το identify() στέλνεται με το ID χρήστη μόλις το identify φτάσει στον server, ώστε η ταυτοποίηση SDK να τη δέχεται. Οι αλλαγές κρατιούνται στο localStorage μέχρι να επιβεβαιωθούν και παραδίδονται με σειρά: μια νεότερη αλλαγή σε ένα κανάλι ή μια ομάδα αντικαθιστά μια παλαιότερη που ακόμη περιμένει. Μια κατάργηση συνδρομής παραδίδεται ακόμη και όσο ο επισκέπτης έχει απενεργοποιήσει την παρακολούθηση ή η συναίνεση είναι denied.
import { SubscriptionStatus } from '@joryio/web-sdk';
joryio.user.setSubscription('email', SubscriptionStatus.OPTED_IN);
joryio.user.setSubscriptions({
email: SubscriptionStatus.OPTED_IN,
sms: SubscriptionStatus.UNSUBSCRIBED,
});
joryio.user.addToSubscriptionGroup('newsletter-list-id', 'email');
joryio.user.removeFromSubscriptionGroup('newsletter-list-id', 'email');
| Μέθοδος | Περιγραφή |
|---|---|
user.setSubscription(channel, status) | Ένα κανάλι |
user.setSubscriptions(preferences) | Πολλά κανάλια, ως { channel: status } |
user.addToSubscriptionGroup(groupId, channel?) | Ένταξη σε ομάδα συνδρομής (λίστα)· το channel έχει προεπιλογή 'email' |
user.removeFromSubscriptionGroup(groupId, channel?) | Αποχώρηση από ομάδα συνδρομής |
Κανάλια: email, sms, whatsapp, push, viber. Καταστάσεις: SubscriptionStatus.OPTED_IN (ρητή συναίνεση, π.χ. επιβεβαιωμένο double opt-in), SubscriptionStatus.SUBSCRIBED (απλή συναίνεση) και SubscriptionStatus.UNSUBSCRIBED. Με το build του CDN περάστε τις συμβολοσειρές 'optedIn', 'subscribed' ή 'unsubscribed'.
Τι εξάγει το πακέτο
| Εξαγωγή | Τι είναι |
|---|---|
default / JoryioSDK | Η κλάση του SDK (window.Joryio στο build του CDN) |
SubscriptionStatus | Οι καταστάσεις συνδρομής παραπάνω |
User, PushManager, EcommerceTracker | Οι κλάσεις πίσω από τα joryio.user, joryio.push και joryio.ecommerce() - για τύπους· δεν τις κατασκευάζετε εσείς |
createEcommerceTracker(sdk, config?) | Το ίδιο με το sdk.ecommerce(config) |
SDK_VERSION | Η έκδοση του SDK ως συμβολοσειρά, π.χ. '1.3.3' |
| Τύποι | InitConfig, InAppOptions, InAppDisplayOptions, InAppCampaign, InAppMessage, InAppTrigger, Plugin, TrackingConsent, PushPermissionState, PushSubscribeOptions, SubscriptionChannel, SubscriptionPreferences, UTMParameters, UTMData, EcommerceProduct, EcommerceCartItem, EcommerceOrder, EcommerceConfig, SdkAuthFailureInfo, SdkAuthFailureReason, SdkAuthFailureCallback |
Το installSnippetQueue εξάγεται για τα δικά τεστ του SDK· μην το καλείτε.
Αυτόματα δεδομένα συνεδρίας
Το Web SDK εμπλουτίζει αυτόματα τα συμβάντα Session Start με δεδομένα συσκευής και περιβάλλοντος. Αυτές οι τιμές αποθηκεύονται στο προφίλ χρήστη και στις εγγραφές συσκευής:
$user_agent$timezone$screen_width/$screen_height$viewport_width/$viewport_height$language/$languages$platform$browser$device_idcountry(ISO-3166-1 alpha-2, προέρχεται από IP κατά την έναρξη συνεδρίας)
Ιδιότητες συμβάντων
Τυπικές ιδιότητες
Κάθε αποθηκευμένο συμβάν περιέχει αυτές τις ιδιότητες - το $device_id προστίθεται από το SDK και οι υπόλοιπες προστίθενται από το pipeline εισαγωγής του Joryio όταν λαμβάνεται το συμβάν:
$device_id: Σταθερό αναγνωριστικό συσκευής ανά πρόγραμμα περιήγησης (προστίθεται από το SDK)$session_id: Αναγνωριστικό τρέχουσας συνεδρίας$anonymous_id: Αναγνωριστικό ανώνυμου χρήστη (πριν από την αναγνώριση)$app_id: Αναγνωριστικό εφαρμογής σας$app_name: Όνομα εφαρμογής σας$platform: Πάνταwebγια το Web SDK$is_identified: Αν ο χρήστης έχει αναγνωριστεί
Το πρόθεμα $ είναι δεσμευμένο - μην το χρησιμοποιείτε για δικές σας ιδιότητες.
Προσαρμοσμένες ιδιότητες
Μπορείτε να προσθέσετε οποιεσδήποτε προσαρμοσμένες ιδιότητες στα συμβάντα σας:
joryio.track('Video Played', {
video_id: 'vid_123',
video_title: 'Product Demo',
duration: 120,
autoplay: false,
// Any other custom data
});
Βέλτιστες πρακτικές
1. Αρχικοποιήστε νωρίς
Αρχικοποιήστε το SDK όσο το δυνατόν νωρίτερα στην εφαρμογή σας:
// In your main app file
import JoryioSDK from '@joryio/web-sdk';
const joryio = new JoryioSDK({
sdkKey: process.env.JORYIO_SDK_KEY,
enableDebug: process.env.NODE_ENV === 'development',
});
2. Παρακολουθήστε ουσιαστικά συμβάντα
Εστιάστε στην παρακολούθηση συμβάντων που είναι σημαντικά για την επιχείρησή σας:
// Good: Specific, actionable events
joryio.track('Trial Started', { plan: 'premium' });
joryio.track('Feature Used', { feature: 'export', format: 'csv' });
// Avoid: Overly generic events
joryio.track('Button Clicked'); // Too generic
3. Χρησιμοποιήστε συνεπή ονοματοδοσία
Χρησιμοποιήστε μια συνεπή σύμβαση ονοματοδοσίας για συμβάντα και ιδιότητες:
// Good: Clear, consistent naming
joryio.track('Subscription Upgraded', {
from_plan: 'basic',
to_plan: 'premium',
billing_cycle: 'monthly',
});
// Avoid: Inconsistent naming
joryio.track('upgraded_subscription', {
FromPlan: 'basic',
'to-plan': 'premium',
});
4. Χειριστείτε τον κύκλο ζωής χρήστη
Χειριστείτε σωστά την αναγνώριση χρήστη και τη διαχείριση συνεδριών:
// On login
function handleLogin(userId, userInfo) {
joryio.identify(userId);
joryio.setAttributes({
email: userInfo.email,
name: userInfo.name,
});
}
// On logout
function handleLogout() {
joryio.reset();
}
// On signup
function handleSignup(userId, userInfo) {
joryio.identify(userId);
joryio.setAttributes(userInfo);
}
Αντιμετώπιση προβλημάτων
Τα συμβάντα δεν εμφανίζονται
- Ελέγξτε το κλειδί SDK - βεβαιωθείτε ότι ξεκινά με
jry_sdk_web_(λειτουργεί και το κλειδί μιας ενσωμάτωσης καταστήματος). Το κλειδί μιας εφαρμογής κινητού (jry_sdk_ios_,jry_sdk_android_) απορρίπτεται: το SDK καταγράφει τον λόγο και μένει ανενεργό - Ελέγξτε την κονσόλα - ενεργοποιήστε τη λειτουργία εντοπισμού σφαλμάτων για λεπτομερή logs
- Επαληθεύστε την αρχικοποίηση - βεβαιωθείτε ότι το
new JoryioSDK(config)εκτελείται πριν κληθούν άλλες μέθοδοι
Σφάλματα CORS
Τα endpoints παρακολούθησης του SDK απαντούν με Access-Control-Allow-Origin: *, επομένως δεν απαιτείται επιτρεπόμενη λίστα domain. Αν εξακολουθείτε να βλέπετε σφάλματα CORS, ελέγξτε ότι το apiEndpoint δείχνει στο σωστό βασικό URL (https://api-eu1.joryio.com/api) και ότι το αίτημα δεν αποκλείεται από επέκταση προγράμματος περιήγησης ή proxy που αφαιρεί κεφαλίδες CORS.
Προβλήματα παρακολούθησης συνεδρίας
Το SDK χρησιμοποιεί localStorage για διατήρηση συνεδρίας. Βεβαιωθείτε ότι:
- Ο ιστότοπός σας σερβίρεται μέσω HTTPS (απαιτείται για ασφαλή contexts)
- Οι χρήστες δεν έχουν απενεργοποιήσει το localStorage
- Δεν καλείτε κατά λάθος το
reset()
Επόμενα βήματα
- Web SDK: UTM & Attribution - Απόδοση καμπάνιας, πρώτη/τελευταία επαφή και καταγραφή UTM
- E-Commerce Tracking - Συμβάντα προϊόντων, καλαθιού, checkout και παραγγελιών
- Παρακολούθηση προσαρμοσμένων συμβάντων
- Ορισμός γνωρισμάτων χρήστη
- Δημιουργία τμημάτων
- Δημιουργία καμπανιών