Μετάβαση στο κύριο περιεχόμενο

Ενσωμάτωση 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.

Μεταφέρθηκε από τον host του API

Μέχρι τον Οκτώβριο του 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',
});

Επιλογές ρυθμίσεων​

ΕπιλογήΤύποςΠροεπιλογήΠεριγραφή
sdkKeystringΑπαιτείταιΤο κλειδί SDK σας από το dashboard του Joryio
apiEndpointstringhttps://api-eu1.joryio.com/apiΟ API host της περιοχής σας. Αρκεί και σκέτο όνομα host· προστίθεται το /api
userIdstring-Έναρξη με γνωστό ID χρήστη
anonymousIdstringδημιουργείταιΧρήση δικού σας ανώνυμου ID
enableDebugbooleanfalseΕνεργοποιεί καταγραφή εντοπισμού σφαλμάτων στην κονσόλα (logLevel: 'debug'). Ένα ρητό logLevel υπερισχύει
batchFlushIntervalnumber5000Συχνότητα αποστολής ομαδοποιημένων συμβάντων στον διακομιστή (χιλιοστά του δευτερολέπτου). Τα συμβάντα τοποθετούνται τοπικά σε ουρά και αποστέλλονται κάθε 5 δευτερόλεπτα, για λιγότερα αιτήματα δικτύου. Τιμές κάτω από 1000 αυξάνονται σε 1000.
batchSizenumber50Συμβάντα ανά αίτημα, και το μέγεθος ουράς που προκαλεί αποστολή πριν από τον χρονοδιακόπτη. Ποτέ πάνω από 500 ανά αίτημα (το όριο του API)
sendImmediatelybooleanfalseΣτέλνει κάθε συμβάν αμέσως χωρίς ομαδοποίηση (δεν συνιστάται για παραγωγή)
sessionTimeoutnumber1800000Λήξη συνεδρίας σε χιλιοστά του δευτερολέπτου (προεπιλογή: 30 λεπτά). Νέα συνεδρία ξεκινά μετά από αυτό το διάστημα αδράνειας - ελέγχεται σε κάθε track() και όταν η καρτέλα γίνεται ξανά ορατή.
trackSessionStartbooleantrueΈνα συμβάν «Session Start» ανά νέα συνεδρία. Μια επαναφόρτωση που συνεχίζει τη συνεδρία δεν στέλνει κανένα.
trackPageViewsbooleanfalseΠαρακολουθεί αυτόματα το «Page Viewed» κατά τη φόρτωση της σελίδας
captureUTMbooleantrueΚαταγράφει αυτόματα παραμέτρους UTM από το URL για απόδοση καμπάνιας
resetSessionOnNewCampaignbooleanfalseΞεκινά νέα συνεδρία όταν αλλάζουν οι παράμετροι UTM (χρήσιμο για ανάλυση συνεδριών ανά καμπάνια)
trackDevicePropertiesbooleantrueΣυμπεριλαμβάνει πληροφορίες συσκευής στο Session Start
persistQueuebooleantrueΔιατηρεί συμβάντα στην ουρά στο localStorage ώστε να επιβιώνουν από ανανέωση σελίδας
maxQueueSizenumber1000Τα περισσότερα συμβάντα που κρατά η τοπική ουρά όσο οι αποστολές αποτυγχάνουν· πέρα από αυτό απορρίπτονται τα παλαιότερα (με προειδοποίηση στο log όταν η καταγραφή είναι ενεργή)
maxRetriesnumber3Άμεσες επαναλήψεις ενός αιτήματος (5xx, 429, σφάλμα δικτύου). Μια παρτίδα που αποτυγχάνει ακόμα κρατιέται και ξαναστέλνεται αργότερα
retryBackoffMsnumber1000Η πρώτη αναμονή πριν από επανάληψη, σε χιλιοστά του δευτερολέπτου· διπλασιάζεται σε κάθε αποτυχία, έως 5 λεπτά
requestTimeoutnumber10000Χρονικό όριο σε χιλιοστά του δευτερολέπτου για κάθε αίτημα API (συμβάντα, γνωρίσματα, in-app, push)
trackPagePropertiesbooleantrueΠροσθήκη του referrer και της σελίδας προσγείωσης στα συμβάντα "Page Viewed"
respectDoNotTrackbooleantrueΗ ρύθμιση Do Not Track του browser λογίζεται ως απενεργοποίηση παρακολούθησης
logLevelstring-'error', 'warn', 'info' ή 'debug'. Δεν καταγράφεται τίποτα αν δεν οριστεί αυτό ή το enableDebug
trackingConsentstringχωρίς τιμή'granted', 'denied' ή 'pending'. Αφήστε το χωρίς τιμή αν ο ιστότοπός σας δεν έχει banner συναίνεσης. Δείτε Ιδιωτικότητα και συναίνεση
optOutbooleanfalseΤο true απενεργοποιεί την παρακολούθηση του επισκέπτη και διατηρείται μεταξύ φορτώσεων σελίδας, όπως το optOut(). Το false δεν αναιρεί μια αποθηκευμένη απενεργοποίηση - μόνο το optIn() την αναιρεί
enableSdkAuthenticationbooleanfalseΕπισύναψη και ανανέωση ενός JWT που εκδίδει το backend σας. Δείτε Ταυτοποίηση SDK
sdkAuthenticationTokenstring-Το πρώτο JWT, όταν το enableSdkAuthentication είναι true
pluginsarray[]Plugins με hooks beforeTrack / afterTrack (μόνο web)
inApp.enabledbooleantrueΕνεργοποίηση ή απενεργοποίηση των μηνυμάτων in-app
inApp.evaluationModestring'differential-sync'Πότε ανακτώνται οι καμπάνιες in-app: 'differential-sync' (κατά τη φόρτωση, στο identify(), στο reset(), σε νέα συνεδρία, σε αλλαγή παρακολουθούμενου γνωρίσματος και κάθε inApp.syncInterval) ή 'session-start-only' (μόνο κατά τη φόρτωση, στο identify(), στο reset() και σε νέα συνεδρία)
inApp.syncIntervalnumber0 (ανενεργό)Νέα ανάκτηση καμπανιών in-app κάθε N χιλιοστά του δευτερολέπτου σε λειτουργία 'differential-sync'. Τιμές κάτω από 30000 αυξάνονται σε 30000· σε παύση όσο η καρτέλα είναι κρυφή
inApp.allowHtmlJsInAppMessagesbooleanfalseΕπιτρέπει 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.defaultPositionstring'center''top', 'center' ή 'bottom': πού εμφανίζεται ένα μήνυμα τύπου Custom. Τα μηνύματα modal, banner, slide-up και πλήρους οθόνης κρατούν τη δική τους θέση
inApp.displayOptions.defaultAnimationstring'fade''fade', 'slide' ή 'none': πώς εμφανίζονται τα μηνύματα. Παραλείπεται όταν το σύστημα του επισκέπτη ζητά λιγότερη κίνηση
inApp.displayOptions.backdropColorstring'rgba(0, 0, 0, 0.5)'Χρώμα του σκοτεινού επιπέδου πίσω από μηνύματα modal και πλήρους οθόνης
inApp.displayOptions.closeButtonColorstringτο χρώμα κειμένου του μηνύματοςΧρώμα του κουμπιού κλεισίματος
inApp.displayOptions.zIndexnumber999999Σειρά στοίβαξης των μηνυμάτων (το σκοτεινό επίπεδο βρίσκεται μία θέση κάτω)
inApp.onMessageDisplay / onMessageClick / onMessageDismissfunction-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)
  • Νέα συνεδρία ξεκινά όταν:
    1. Ο χρήστης φορτώνει τη σελίδα για πρώτη φορά
    2. Παρέρχεται το χρονικό όριο συνεδρίας χωρίς συμβάντα
    3. Ο χρήστης καλεί joryio.reset() (π.χ. κατά την αποσύνδεση)
    4. Εντοπίζεται νέα καμπάνια (αν είναι ενεργοποιημένο το 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_id
  • country (ISO-3166-1 alpha-2, προέρχεται από IP κατά την έναρξη συνεδρίας)

Περιπτώσεις χρήσης:

  1. Journeys καλωσορίσματος: χρησιμοποιήστε το Session Start ως έναυσμα journey για να προσεγγίσετε χρήστες όταν φτάνουν στον ιστότοπό σας.

  2. Τμήματα βάσει συνεδρίας: τα συμβάντα Session Start αποθηκεύονται ανά χρήστη, ώστε οι συνθήκες τμημάτων βάσει συμβάντων να μπορούν να τα μετρούν - για παράδειγμα, «εκτέλεσε Session Start τουλάχιστον 10 φορές» (ενεργοί προχωρημένοι χρήστες) ή «δεν εκτέλεσε Session Start τις τελευταίες 7 ημέρες» (επανενεργοποίηση).

  3. Απόδοση καμπάνιας: φιλτράρετε τα 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;
}

Η προτεραιότητα, από την υψηλότερη:

  1. όσα ορίζει η καμπάνια στο Style (optional) - γράφονται inline στην κάρτα
  2. οι δικές σας τιμές --joryio-inapp-*
  3. οι προεπιλογές του SDK, που είναι χρώματα συστήματος

Έτσι μια καμπάνια που δεν ορίζει τίποτα κληρονομεί το στυλ σας, ενώ μία που ορίζει φόντο υπερισχύει μόνο για εκείνο το μήνυμα. Χωρίς !important πουθενά.

Αν πάλι χρησιμοποιήσετε τους επιλογείς, το φύλλο στυλ του SDK εισάγεται τη στιγμή της εμφάνισης και άρα βρίσκεται μετά το δικό σας, οπότε κερδίζει στις ισοπαλίες. Προσθέστε ειδικότητα - .joryio-inapp .joryio-inapp-native {…} - αντί για έναν κανόνα μίας κλάσης.

Η κατεύθυνση ρυθμίζεται αυτόματα: η κάρτα φέρει dir="auto", οπότε ένα εβραϊκό ή αραβικό μήνυμα στοιχίζεται δεξιά μέσα σε μια κατά τα άλλα αριστερόστροφη σελίδα.

Τύποι μηνυμάτων​

  1. Modal - Στο κέντρο της οθόνης με σκίαση
  2. Banner - Στο επάνω μέρος της σελίδας
  3. Slide-Up - Μικρή ειδοποίηση από κάτω
  4. Full-Screen - Μήνυμα που καταλαμβάνει την οθόνη
  5. 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 (πάντα παρόν)
Διαβάστε το αφού φορτωθεί το SDK

Με το ασύγχρονο 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_id
  • country (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);
}

Αντιμετώπιση προβλημάτων​

Τα συμβάντα δεν εμφανίζονται​

  1. Ελέγξτε το κλειδί SDK - βεβαιωθείτε ότι ξεκινά με jry_sdk_web_ (λειτουργεί και το κλειδί μιας ενσωμάτωσης καταστήματος). Το κλειδί μιας εφαρμογής κινητού (jry_sdk_ios_, jry_sdk_android_) απορρίπτεται: το SDK καταγράφει τον λόγο και μένει ανενεργό
  2. Ελέγξτε την κονσόλα - ενεργοποιήστε τη λειτουργία εντοπισμού σφαλμάτων για λεπτομερή logs
  3. Επαληθεύστε την αρχικοποίηση - βεβαιωθείτε ότι το 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()

Επόμενα βήματα​