Κέντρο βοήθειας
Chat API

Webhooks

Τελευταία ενημέρωση:

Επισκόπηση των webhook

Τα webhook επιτρέπουν στο ChatLab να ειδοποιεί τα συστήματά σας τη στιγμή ακριβώς που συμβαίνει κάτι στα chatbot σας. Αντί να κάνετε polling στο Management API ή να εξάγετε δεδομένα χειροκίνητα, δηλώνετε ένα τελικό σημείο HTTPS και το ChatLab στέλνει σε αυτό ένα υπογεγραμμένο αίτημα HTTP POST σε πραγματικό χρόνο - όταν ένας επισκέπτης αφήνει ένα lead, υποβάλλει μια φόρμα επικοινωνίας, αξιολογεί μια συνομιλία, ζητά έναν εκπρόσωπο ή όταν εκτελείται μια ενέργεια AI.

Συνήθεις χρήσεις:

  • αυτόματη προώθηση νέων lead απευθείας στο CRM σας τη στιγμή ακριβώς που καταγράφονται
  • ειδοποίηση της ομάδας σας στο Slack όταν ένας επισκέπτης ζητά live chat
  • εισαγωγή αξιολογήσεων και συνόψεων συνομιλιών στα δικά σας συστήματα αναλυτικών στοιχείων
  • παρακολούθηση της εκτέλεσης ενεργειών AI και αποστολή ειδοποιήσεων σε περίπτωση σφαλμάτων

Διαθεσιμότητα: ο λογαριασμός σας πρέπει να περιλαμβάνει τη λειτουργία Webhooks.

Πού γίνεται η ρύθμιση: στην εφαρμογή διαχείρισης, ανοίξτε την ενότητα Account settings -> Webhooks (Ρυθμίσεις λογαριασμού -> Webhook, ακριβώς δίπλα στην ενότητα Management API). Τα webhook λειτουργούν σε επίπεδο λογαριασμού - ένα τελικό σημείο μπορεί να λαμβάνει συμβάντα από όλα τα bot σας ή από ένα επιλεγμένο bot.

Ρύθμιση τελικού σημείου

  1. Ανοίξτε την ενότητα Account settings -> Webhooks (Ρυθμίσεις λογαριασμού -> Webhook) και κάντε κλικ στο Add endpoint (Προσθήκη τελικού σημείου).
  2. Συμπληρώστε τη φόρμα του τελικού σημείου:
    • Name (Όνομα) - μια ετικέτα για δική σας αναφορά, π.χ. "Συγχρονισμός CRM" ή "Ειδοποιήσεις Slack".
    • URL - η διεύθυνση HTTPS στην οποία το ChatLab θα στέλνει αιτήματα POST για τα συμβάντα.
    • Events (Συμβάντα) - επιλέξτε ποιους τύπους συμβάντων θα λαμβάνει αυτό το τελικό σημείο (δείτε τον κατάλογο παρακάτω). Επιλέξτε μόνο ό,τι χρειάζεστε - συμβάντα μεγάλου όγκου, όπως το ai_action.executed, μπορούν να δημιουργήσουν πολλή κίνηση.
    • Bot filter (Φίλτρο bot) (προαιρετικό) - επιλέξτε ένα bot ή All bots (Όλα τα bot) για όλα τα bot του λογαριασμού σας.
    • Custom form filter (Φίλτρο προσαρμοσμένης φόρμας) (προαιρετικό) - δρομολογεί τις υποβολές μιας συγκεκριμένης προσαρμοσμένης φόρμας σε αυτό το τελικό σημείο. Περιορίζει μόνο το συμβάν custom_form.submitted - κάθε άλλο συμβάν στο οποίο έχετε εγγραφεί (lead, αιτήματα επικοινωνίας, συνομιλίες, live chat, ενέργειες AI) παραδίδεται ανεξάρτητα από αυτήν τη ρύθμιση.
  3. Υποβάλετε τη φόρμα. Το μυστικό κλειδί (secret) του τελικού σημείου εμφανίζεται ακριβώς μία φορά στο παράθυρο διαλόγου επιτυχίας - αντιγράψτε το τώρα και αποθηκεύστε το με ασφάλεια. Θα το χρειαστείτε για να επαληθεύετε τις υπογραφές (δείτε την ενότητα Ασφάλεια παρακάτω). Το κείμενο δεν μπορεί να ανακτηθεί αργότερα.

Κάθε τελικό σημείο διαθέτει επίσης:

  • Διακόπτη ενεργοποίησης/απενεργοποίησης (Enable/disable toggle) - αναστολή παραδόσεων χωρίς διαγραφή του τελικού σημείου. Τα απενεργοποιημένα τελικά σημεία απορρίπτουν σιωπηρά τα συμβάντα (δεν μπαίνουν σε ουρά για αργότερα).
  • Αποστολή δοκιμαστικού συμβάντος (Send sample event) - παραδίδει ένα υπογεγραμμένο δοκιμαστικό αίτημα στο URL σας, ώστε να μπορείτε να ελέγξετε τον δέκτη σας από άκρο εις άκρον. Μπορείτε να επιλέξετε τον τύπο συμβάντος και να επεξεργαστείτε τις τιμές του δείγματος πριν από την αποστολή, ώστε ο χειριστής σας να λάβει ρεαλιστικά δεδομένα. Η δοκιμή φτάνει ως κανονική παράδοση με το eventType να αντιστοιχεί στην επιλογή σας (ή ως webhook.test για έναν απλό έλεγχο συνδεσιμότητας).
  • Ανανέωση μυστικού κλειδιού (Roll secret) - δημιουργεί ένα νέο μυστικό κλειδί και ακυρώνει το παλιό. Χρησιμοποιήστε το εάν υπάρχει υπόνοια διαρροής του μυστικού κλειδιού. Το νέο μυστικό κλειδί εμφανίζεται και πάλι μόνο μία φορά. Για ελεγχόμενη εναλλαγή, θέστε σε παύση το τελικό σημείο, δημιουργήστε και αντιγράψτε το νέο μυστικό κλειδί, ενημερώστε τον δέκτη σας και, στη συνέχεια, ενεργοποιήστε ξανά το σημείο και στείλτε ένα δοκιμαστικό συμβάν. Τα συμβάντα κατά τη διάρκεια της παύσης δεν μπαίνουν σε ουρά. Προγραμματίστε αυτήν τη διακοπή πριν προχωρήσετε στην εναλλαγή.
  • Καταγραφή παραδόσεων (Delivery log) - μια λίστα πρόσφατων παραδόσεων ανά τελικό σημείο με χρονοσήμανση, τύπο συμβάντος, κωδικό κατάστασης HTTP που επέστρεψε ο διακομιστής σας και χρόνο απόκρισης. Οι αποτυχημένες παραδόσεις και οι παύσεις λόγω κυκλώματος προστασίας (circuit breaker) εμφανίζονται εδώ. Το αρχείο καταγραφής διατηρείται για 14 ημέρες.

Φάκελος συμβάντος

Κάθε παράδοση είναι ένα αίτημα HTTP POST με Content-Type: application/json. Το σώμα έχει πάντα την ίδια δομή φακέλου - το αντικείμενο data διαφέρει ανάλογα με τον τύπο του συμβάντος:

{
  "eventId": "9f1c1c8e-6a2b-4b9e-9d2f-3f8a1e2b4c5d",
  "eventType": "lead.created",
  "timestamp": "2026-08-13T14:22:31Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": { }
}
  • eventId - μοναδικό ανά συμβάν. Χρησιμοποιήστε το για κατάργηση διπλοτύπων εάν η επεξεργασία σας πρέπει να είναι ταυτοδύναμη.
  • eventType - ένας από τους τύπους που περιγράφονται παρακάτω - αποστέλλεται επίσης στην κεφαλίδα X-ChatLab-Event.
  • timestamp - η ώρα UTC κατά ISO 8601 κατά την οποία προετοιμάστηκε ο φάκελος παράδοσης.
  • botId / botName - το bot στο οποίο ανήκει το συμβάν.
  • conversationId / sessionId - τα συμφραζόμενα της συνομιλίας, όπου ισχύει.

Κατάλογος συμβάντων

lead.created

Ενεργοποιείται όταν ένας επισκέπτης υποβάλλει τα στοιχεία επικοινωνίας του - μέσω της φόρμας συλλογής υποψήφιων πελατών (lead collection form), της προ-φόρμας live chat ή μιας προσαρμοσμένης φόρμας που χρησιμοποιείται για συλλογή υποψήφιων πελατών.

{
  "eventId": "9f1c1c8e-6a2b-4b9e-9d2f-3f8a1e2b4c5d",
  "eventType": "lead.created",
  "timestamp": "2026-08-13T14:22:31Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "email": "jane.doe@example.com",
    "name": "Jane Doe",
    "phone": "+1 555 0123",
    "source": "LEAD_COLLECTION_FORM",
    "formCodeName": "lead_form",
    "formName": "Lead form",
    "fields": [
      {"name": "email", "value": "jane.doe@example.com", "type": "email"},
      {"name": "company", "value": "Acme Inc.", "type": "text"},
      {"name": "topics", "value": ["Billing", "Delivery"], "type": "multichoice"},
      {"name": "attachment", "value": "https://api.chatlab.com/aichat/customform/download?key=...&token=...", "type": "file"}
    ],
    "pageUrl": "https://acme.com/pricing"
  }
}
  • source - πώς συλλέχθηκαν τα στοιχεία επικοινωνίας: LEAD_COLLECTION_FORM (φόρμα συλλογής lead), LIVE_CHAT_FORM (προ-φόρμα live chat), CONVERSATION (το AI εντόπισε τα στοιχεία κατά τη διάρκεια της συνομιλίας), ADMIN_DATA_UPDATE ή UPDATE_CLIENT_CONTEXT (τροποποιήθηκαν από την πλευρά του ChatLab). Οι υποβολές της φόρμας υποστήριξης από εκπρόσωπο δεν ενεργοποιούν ποτέ αυτό το συμβάν - ενεργοποιούν αντ' αυτού το contact_form.submitted.
  • email, name, phone - τα στοιχεία επικοινωνίας που αντιστοιχίζονται στην εγγραφή του υποψήφιου πελάτη (lead).
  • Όταν χρησιμοποιείται μια προσαρμοσμένη φόρμα για τη συλλογή υποψήφιων πελατών, κάθε πεδίο που ορίζεται σε αυτήν τη φόρμα περιλαμβάνεται στο fields, με τη σειρά της φόρμας, και τα formCodeName / formName ταυτοποιούν τη φόρμα. Με την κλασική φόρμα lead και τα δύο είναι null και το fields είναι ένας κενός πίνακας.
  • Κάθε καταχώριση στο fields είναι {name, value, type}. Το name είναι το τεχνικό όνομα του πεδίου, το οποίο παραμένει σταθερό κατά την επεξεργασία των ετικετών - χρησιμοποιήστε το για αντιστοίχιση στο CRM σας.
  • Για τα πεδία multichoice η τιμή value είναι ένας πίνακας (array) των επιλεγμένων επιλογών. Τα πεδία πλαισίου ελέγχου (checkbox) είναι μεμονωμένες καταχωρίσεις με τιμές "true" / "false".
  • Για τα πεδία file η τιμή value είναι ένας σύνδεσμος λήψης προς το μεταφορτωμένο αρχείο - το webhook δεν μεταφέρει ποτέ το περιεχόμενο των αρχείων.
  • pageUrl - η σελίδα στην οποία βρισκόταν ο επισκέπτης κατά την υποβολή.

contact_form.submitted

Ενεργοποιείται όταν ένας επισκέπτης υποβάλλει τη φόρμα επικοινωνίας με εκπρόσωπο υποστήριξης (human support contact form) ή μια προσαρμοσμένη φόρμα που χρησιμοποιείται για ανθρώπινη επικοινωνία.

{
  "eventId": "3a7b9c2d-1e4f-4a6b-8c0d-5e2f7a9b1c3d",
  "eventType": "contact_form.submitted",
  "timestamp": "2026-08-13T14:25:02Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "email": "jane.doe@example.com",
    "message": "I need help with my last invoice.",
    "source": "CUSTOM_FORM",
    "formCodeName": "contact_form",
    "formName": "Contact form",
    "fields": [
      {"name": "email", "value": "jane.doe@example.com", "type": "email"},
      {"name": "order_number", "value": "A-10293", "type": "text"},
      {"name": "message", "value": "I need help with my last invoice.", "type": "textarea"}
    ]
  }
}
  • email - η διεύθυνση που άφησε ο επισκέπτης, στην οποία θα πρέπει να απαντήσει η ομάδα υποστήριξής σας.
  • source - CUSTOM_FORM όταν η φόρμα επικοινωνίας βασίζεται σε προσαρμοσμένη φόρμα, CONTACT_FORM για την ενσωματωμένη φόρμα.
  • formCodeName / formName - ταυτοποιούν την προσαρμοσμένη φόρμα πίσω από το αίτημα - και τα δύο είναι null για την ενσωματωμένη φόρμα.
  • Όταν χρησιμοποιείται μια προσαρμοσμένη φόρμα, περιλαμβάνεται κάθε πεδίο που ορίζεται σε αυτήν τη φόρμα στο fields (στην ίδια μορφή {name, value, type} όπως στο lead.created). Με την ενσωματωμένη φόρμα επικοινωνίας συμπληρώνονται μόνο τα email και message, το fields είναι ένας κενός πίνακας και τα αναγνωριστικά της φόρμας είναι null.
  • message - το αντιστοιχισμένο πεδίο μηνύματος ή όλες οι συμπληρωμένες τιμές ενωμένες μεταξύ τους όταν η φόρμα δεν ορίζει κάποιο πεδίο μηνύματος.

custom_form.submitted

Ενεργοποιείται για κάθε υποβολή προσαρμοσμένης φόρμας, ανεξάρτητα από τον σκοπό της φόρμας. Λάβετε υπόψη ότι οι φόρμες των οποίων ο σκοπός είναι η συλλογή υποψήφιων πελατών ή η ανθρώπινη επικοινωνία ενεργοποιούν επίσης το αντίστοιχο αποκλειστικό τους συμβάν lead.created / contact_form.submitted - εγγραφείτε στο ένα ή στο άλλο ανάλογα με το αν επιθυμείτε τη γενική ή την εξειδικευμένη προβολή, αντί να δημιουργείτε διπλότυπες επιχειρηματικές ενέργειες. Οι δύο οικογένειες συμβάντων έχουν διαφορετικά αναγνωριστικά συμβάντος - ο συνδυασμός conversationId και timestamp δεν αποτελεί αξιόπιστο αναγνωριστικό υποβολής.

{
  "eventId": "6c1d8e3f-2a5b-4c7d-9e0f-1a4b6c8d0e2f",
  "eventType": "custom_form.submitted",
  "timestamp": "2026-08-13T14:27:45Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "formCodeName": "warranty_claim",
    "formName": "Warranty claim",
    "fields": [
      {"name": "order_number", "value": "A-10293", "type": "text"},
      {"name": "issue", "value": "Damaged on arrival", "type": "textarea"},
      {"name": "photo", "value": "https://api.chatlab.com/aichat/customform/download?key=...&token=...", "type": "file"}
    ],
    "purpose": "STANDALONE"
  }
}
  • formCodeName - το σταθερό τεχνικό όνομα της φόρμας, το οποίο παραμένει αμετάβλητο όταν μετονομάζετε τη φόρμα - χρησιμοποιήστε το για τη δρομολόγηση των υποβολών στο δικό σας σύστημα. Το formName είναι η ετικέτα εμφάνισης που βλέπουν οι επισκέπτες.
  • Το fields χρησιμοποιεί τις ίδιες καταχωρίσεις {name, value, type} όπως το lead.created: οι τιμές πολλαπλής επιλογής είναι πίνακες, οι τιμές αρχείων είναι σύνδεσμοι λήψης.
  • purpose - STANDALONE, LEAD_COLLECTION ή HUMAN_CONTACT, ανάλογα με τον τρόπο σύνδεσης της φόρμας στο chatbot.

conversation.started

Ενεργοποιείται όταν ένας επισκέπτης στέλνει το πρώτο μήνυμα μιας νέας συνομιλίας.

{
  "eventId": "8e2f0a4b-3c6d-4e8f-a1b2-2c5d7e9f1a3b",
  "eventType": "conversation.started",
  "timestamp": "2026-08-13T14:20:11Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "firstMessage": "Do you ship to Canada?",
    "chatSource": "WIDGET",
    "byAdmin": false,
    "countryCode": "PL",
    "ipAddress": "83.12.44.7"
  }
}
  • firstMessage - το ακριβές κείμενο του αρχικού μηνύματος του επισκέπτη. null εάν η συνομιλία άνοιξε χωρίς περιεχόμενο μηνύματος.
  • chatSource - το κανάλι μέσω του οποίου προήλθε η συνομιλία: WIDGET, WHATSAPP, MESSENGER, VOICE, VOICE_PHONE, API, BOOKING, AIRBNB ή IDOBOOKING.
  • byAdmin - true όταν η συνομιλία προέρχεται από την προεπισκόπηση του chatbot μέσα στον πίνακα διαχείρισης του ChatLab αντί για πραγματικό επισκέπτη. Χρησιμοποιήστε το για να εξαιρέσετε τις δικές σας δοκιμαστικές συνομιλίες από το CRM σας.
  • countryCode - κωδικός χώρας ISO που εντοπίστηκε από τη διεύθυνση IP του επισκέπτη, null όταν δεν ήταν δυνατός ο προσδιορισμός του.
  • ipAddress - η διεύθυνση IP του επισκέπτη όπως καταγράφηκε από το ChatLab, null όταν δεν είναι διαθέσιμη. Χειριστείτε την ως δεδομένα προσωπικού χαρακτήρα βάσει του GDPR και αποθηκεύστε την μόνο εάν έχετε νόμιμη βάση.

conversation.rated

Ενεργοποιείται όταν ένας επισκέπτης υποβάλλει θετική ή αρνητική αξιολόγηση συνομιλίας (βλ. Conversation rating (Αξιολόγηση συνομιλίας)).

{
  "eventId": "1b4c6d8e-5f0a-4b2c-8d3e-4f7a9b1c3d5e",
  "eventType": "conversation.rated",
  "timestamp": "2026-08-13T14:31:09Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "rating": "POSITIVE"
  }
}
  • rating - POSITIVE ή NEGATIVE. Η εκκαθάριση μιας αξιολόγησης δεν ενεργοποιεί το συμβάν, επομένως δεν λαμβάνετε ποτέ ουδέτερη τιμή.

conversation.summarized

Ενεργοποιείται όταν το ChatLab δημιουργεί μια σύνοψη μιας ολοκληρωμένης συνομιλίας.

{
  "eventId": "4d7e9f1a-6b2c-4d4e-9f0a-5b8c0d2e4f6a",
  "eventType": "conversation.summarized",
  "timestamp": "2026-08-13T14:45:00Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "summary": "Visitor asked about shipping to Canada and delivery times. The bot confirmed availability and quoted 5-7 business days. Visitor left satisfied.",
    "language": "en_US"
  }
}
  • summary - το κείμενο της σύνοψης που δημιουργήθηκε. Η δημιουργία σύνοψης είναι ασύγχρονη και εξαρτάται από τις ρυθμίσεις σύνοψης του bot και το πρόγραμμα επεξεργασίας - μην υποθέτετε σταθερό χρόνο παράδοσης.
  • language - το εσωτερικό locale του bot που διαβιβάστηκε για τη δημιουργία της σύνοψης, για παράδειγμα en_US - μην υποθέτετε ότι αυτό αντιστοιχεί στη γλώσσα συνομιλίας του επισκέπτη.

client.summarized

Ενεργοποιείται όταν το ChatLab ανανεώνει το προφίλ AI ενός πελάτη. Το προφίλ αναδομείται από το προηγούμενο προφίλ συν τη σύνοψη της συνομιλίας που μόλις ολοκληρώθηκε, και ενδέχεται να παραχθεί μετά το conversation.summarized. Η σειρά παράδοσης δεν είναι εγγυημένη. Το ωφέλιμο φορτίο (payload) περιλαμβάνει email όταν αυτό είναι γνωστό, αλλά το ChatLab μπορεί επίσης να διατηρεί πελάτες χωρίς email.

{
  "eventId": "b5d8f1a3-7c2e-4d9b-a6f0-1e3c5a7b9d2f",
  "eventType": "client.summarized",
  "timestamp": "2026-08-18T09:12:04Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "clientEmail": "jane.doe@example.com",
    "client": {
      "email": "jane.doe@example.com",
      "name": "Jane Doe",
      "phone": "+1 555 0123",
      "countryCode": "PL",
      "ipAddress": "83.12.44.7"
    },
    "clientSummary": "Returning customer interested in international shipping. Asked about delivery times to Canada twice and about return costs once."
  }
}
  • clientEmail - το αναγνωριστικό για την αντιστοίχιση του πελάτη στο δικό σας CRM. Είναι null για ανώνυμους επισκέπτες που δεν άφησαν ποτέ διεύθυνση, και το συμβάν εξακολουθεί να ενεργοποιείται για αυτούς - παραλείψτε αυτές τις παραδόσεις εάν η ενσωμάτωσή σας βασίζεται σε e-mail.
  • client - η καρτέλα επαφής που διατηρεί το ChatLab για αυτό το άτομο: email, name, phone, countryCode και ipAddress. Κάθε κλειδί είναι πάντα παρόν - οι άγνωστες τιμές είναι null.
  • clientSummary - το πλήρες κείμενο του προφίλ ως απλό κείμενο, όχι διαφορά (diff). Αντικαθιστά οποιαδήποτε προηγούμενη σύνοψη υπήρχε, επομένως αποθηκεύστε το ως αντικατάσταση αντί να το προσαρτάτε.
  • Το προφίλ αναδομείται μόνο για bot με ενεργοποιημένη τη μνήμη συνομιλίας (chat memory), και μόνο για συνομιλίες που παρέμειναν ανενεργές για αρκετό διάστημα ώστε να συνοψιστούν - αναμένετε αυτό το συμβάν λίγα λεπτά μετά τη λήξη της συνομιλίας και όχι αμέσως.

live_chat.requested

Ενεργοποιείται όταν το AI μεταβιβάζει τη συνομιλία στο Live Chat, είτε επειδή ο επισκέπτης ζήτησε εκπρόσωπο είτε επειδή το bot έκρινε ότι χρειαζόταν ανθρώπινη παρέμβαση.

{
  "eventId": "7a0b2c4d-8e3f-4a5b-b0c1-6d9e1f3a5b7c",
  "eventType": "live_chat.requested",
  "timestamp": "2026-08-13T14:33:20Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "requestedBy": "AI"
  }
}
  • requestedBy - προς το παρόν είναι πάντα AI, επειδή η μεταβίβαση εκκινείται πάντα από την ενέργεια live chat του bot, ακόμη και όταν ο επισκέπτης τη ζητά ρητά με δικά του λόγια. Αντιμετωπίστε το ως ανοιχτό enum: διαχειριστείτε άγνωστες τιμές αντί να επιβάλλετε αυστηρό έλεγχο αποκλειστικά για AI.
  • Αυτό το συμβάν καλύπτει την ενέργεια AI που ζητά μεταβίβαση και όχι κάθε πιθανό τρόπο με τον οποίο ένας επισκέπτης μπορεί να ανοίξει το live chat. Δεν αποδεικνύει ότι συνδέθηκε κάποιος εκπρόσωπος.

live_chat.started

Ενεργοποιείται όταν δημιουργείται η συνεδρία live chat μετά την υποβολή της φόρμας μεταβίβασης του επισκέπτη. Αυτό συμβαίνει προτού κάποιος εκπρόσωπος συνδεθεί ή απαντήσει απαραίτητα - μην το εκλαμβάνετε ως απόδειξη ανθρώπινης συμμετοχής.

{
  "eventId": "0c3d5e7f-9a4b-4c6d-a1b2-7e0f2a4b6c8d",
  "eventType": "live_chat.started",
  "timestamp": "2026-08-13T14:33:55Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {}
}
  • Το data είναι σκόπιμα κενό. Όλα όσα χρειάζεστε βρίσκονται στον φάκελο μεταφοράς (envelope): το botId ταυτοποιεί το chatbot και τα conversationId / sessionId συνδέουν το συμβάν με τη συνομιλία. Ενδέχεται να το λάβετε χωρίς προηγούμενο live_chat.requested, για παράδειγμα όταν ο επισκέπτης χρησιμοποίησε το στοιχείο ελέγχου live chat του widget.

live_chat.ended

Ενεργοποιείται όταν ολοκληρώνεται η συνεδρία live chat.

{
  "eventId": "2e5f7a9b-0c5d-4e7f-b2c3-8f1a3b5c7d9e",
  "eventType": "live_chat.ended",
  "timestamp": "2026-08-13T14:52:41Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "durationSeconds": 1126
  }
}
  • durationSeconds - η διάρκεια της συνεδρίας live chat που παρήλθε, υπολογιζόμενη από τη δημιουργία της συνεδρίας, συμπεριλαμβανομένου του χρόνου αναμονής για εκπρόσωπο. Το πεδίο παραλείπεται στη σπάνια περίπτωση όπου μια συνεδρία λήγει χωρίς να έχει ξεκινήσει ποτέ.

ai_action.executed

Ενεργοποιείται κάθε φορά που το bot εκτελεί μια ενέργεια AI (AI action) - μια διαχειριζόμενη κλήση ενσωμάτωσης ή μια προσαρμοσμένη λειτουργία API. Πρόκειται για συμβάν υψηλού όγκου: ένα ενεργό bot ηλεκτρονικού εμπορίου μπορεί να εκτελεί εκατοντάδες ενέργειες την ημέρα, και μία μόνο αλληλεπίδραση επισκέπτη μπορεί να ενεργοποιήσει αρκετές. Εγγραφείτε σε αυτό σε ένα αποκλειστικό τελικό σημείο (endpoint) ή βεβαιωθείτε ότι ο παραλήπτης σας μπορεί να απορροφήσει τον όγκο.

{
  "eventId": "5f8a0b2c-1d6e-4f8a-c3d4-9a2b4c6d8e0f",
  "eventType": "ai_action.executed",
  "timestamp": "2026-08-13T14:21:03Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "actionName": "search_products",
    "status": "SUCCESS",
    "durationMs": 842,
    "errorMessage": null
  }
}
  • actionName - το όνομα της εκτελεσμένης ενέργειας όπως τη βλέπει το AI, για παράδειγμα search_products για μια διαχειριζόμενη ενσωμάτωση ή το όνομα που δώσατε σε μια προσαρμοσμένη ενέργεια API.
  • status - SUCCESS ή ERROR.
  • durationMs - πόσος χρόνος χρειάστηκε για την εκτέλεση της ενέργειας, σε χιλιοστά του δευτερολέπτου. Χρήσιμο για τον εντοπισμό μιας αργής ενσωμάτωσης προτού διαμαρτυρηθούν οι επισκέπτες.
  • errorMessage - η αιτία της αποτυχίας, η οποία συμπληρώνεται μόνο όταν το status είναι ERROR - διαφορετικά είναι null.

webhook.test

Αποστέλλεται από το κουμπί Send sample event (Αποστολή δείγματος συμβάντος) όταν εκτελείτε έναν απλό έλεγχο συνδεσιμότητας. Υπογράφεται ακριβώς όπως ένα πραγματικό συμβάν.

{
  "eventId": "9b2c4d6e-3f8a-4b0c-d5e6-0b3c5d7e9f1a",
  "eventType": "webhook.test",
  "timestamp": "2026-08-13T14:10:00Z",
  "botId": 1234,
  "botName": "Support Bot",
  "conversationId": "conv_a1b2c3",
  "sessionId": "sess_x9y8z7",
  "data": {
    "message": "Test delivery from ChatLab"
  }
}
  • message - σταθερό κείμενο, πάντα το ίδιο. Τα πεδία του φακέλου μεταφοράς περιέχουν ενδεικτικές τιμές, επομένως μην αντιμετωπίζετε ποτέ μια παράδοση webhook.test ως πραγματικά δεδομένα.
  • Αυτός είναι ο μοναδικός τύπος συμβάντος στον οποίο δεν μπορείτε να εγγραφείτε σε ένα τελικό σημείο: αποστέλλεται κατ' απαίτηση από τον πίνακα διαχείρισης και φτάνει πάντα στο τελικό σημείο στο οποίο κάνατε κλικ, ανεξάρτητα από τα συμβάντα που αυτό παρακολουθεί.

Ασφάλεια: επαλήθευση παραδόσεων

Κάθε παράδοση φέρει τέσσερις κεφαλίδες:

Header Value
X-ChatLab-Signature sha256=<hex hmac> - Υπογραφή HMAC-SHA256 του ωφέλιμου φορτίου
X-ChatLab-Timestamp Ώρα Unix σε δευτερόλεπτα όταν υπογράφηκε η παράδοση
X-ChatLab-Event Ο τύπος του συμβάντος, π.χ. lead.created
X-ChatLab-Delivery Μοναδικό αναγνωριστικό παράδοσης, ίσο με το eventId του σώματος

Η υπογραφή υπολογίζεται ως HMAC-SHA256 πάνω στη συμβολοσειρά {timestamp}.{rawBody} χρησιμοποιώντας το μυστικό του τελικού σημείου σας, όπου {timestamp} είναι η τιμή του X-ChatLab-Timestamp και {rawBody} είναι το ανεπεξέργαστο, μη αναλυμένο σώμα του αιτήματος. Επαληθεύετε πάντα έναντι των ανεπεξέργαστων (raw) byte - η εκ νέου σειριοποίηση του αναλυμένου JSON θα αλλάξει την ακολουθία των byte και θα καταστήσει την υπογραφή άκυρη.

Για προστασία από επιθέσεις επανάληψης (replay attacks), απορρίψτε παραδόσεις των οποίων το X-ChatLab-Timestamp είναι παλαιότερο των 5 λεπτών.

Node.js

const crypto = require('crypto');

function verifyChatLabSignature(req, secret) {
    const signature = req.headers['x-chatlab-signature'];
    const timestamp = req.headers['x-chatlab-timestamp'];
    if (typeof signature !== 'string' || typeof timestamp !== 'string') return false;
    if (!/^\d+$/.test(timestamp) || !Number.isSafeInteger(Number(timestamp))) return false;
    if (!Buffer.isBuffer(req.rawBody)) return false;

    // Reject stale deliveries (older than 5 minutes)
    const ageSeconds = Math.abs(Date.now() / 1000 - Number(timestamp));
    if (ageSeconds > 300) return false;

    // rawBody must be the raw request body bytes, not re-serialized JSON.
    // With Express: app.use(express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }))
    const expected = 'sha256=' + crypto
        .createHmac('sha256', secret)
        .update(timestamp + '.')
        .update(req.rawBody)
        .digest('hex');

    const a = Buffer.from(signature);
    const b = Buffer.from(expected);
    return a.length === b.length && crypto.timingSafeEqual(a, b);
}

PHP

<?php
function verifyChatLabSignature(string $secret): bool
{
    $signature = $_SERVER['HTTP_X_CHATLAB_SIGNATURE'] ?? '';
    $timestamp = $_SERVER['HTTP_X_CHATLAB_TIMESTAMP'] ?? '';
    if ($signature === '' || $timestamp === '' || !ctype_digit($timestamp)) {
        return false;
    }

    // Reject stale deliveries (older than 5 minutes)
    if (abs(time() - (int) $timestamp) > 300) {
        return false;
    }

    $rawBody = file_get_contents('php://input');
    $expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);

    return hash_equals($expected, $signature);
}

Εάν η επαλήθευση αποτύχει, απαντήστε με 401 και απορρίψτε το ωφέλιμο φορτίο. Μην επεξεργάζεστε ποτέ μη επαληθευμένες παραδόσεις - οποιοσδήποτε ανακαλύψει το URL σας μπορεί να στείλει αυθαίρετο JSON με μέθοδο POST σε αυτό.

Συμπεριφορά παράδοσης

Κατανοήστε αυτούς τους κανόνες παράδοσης πριν ξεκινήσετε την υλοποίηση με webhooks:

  • Απαντήστε γρήγορα. Το endpoint σας πρέπει να απαντήσει εντός 3 δευτερολέπτων, διαφορετικά η παράδοση θεωρείται αποτυχημένη. Επαληθεύστε την υπογραφή, τοποθετήστε το συμβάν με ασφάλεια σε ουρά (queue) και επιβεβαιώστε με κωδικό 2xx εντός αυτού του χρονικού παραθύρου. Εκτελέστε τις πιο αργές κλήσεις CRM και την επιχειρησιακή επεξεργασία ασύγχρονα.
  • Fire-and-forget, το πολύ μία φορά (at-most-once). Τα αντίστοιχα ενεργοποιημένα endpoints λαμβάνουν το πολύ μία προσπάθεια παράδοσης - δεν υπάρχουν νέες προσπάθειες (retries). Τα endpoints σε παύση και τα ανοιχτά κυκλώματα προστασίας (open circuits) μπορούν να αποτρέψουν ακόμα και αυτή την προσπάθεια. Εάν το endpoint σας είναι εκτός λειτουργίας, εξαντλήσει το χρονικό όριο ή επιστρέψει κατάσταση διαφορετική από 2xx, το συμβάν αυτό χάνεται και δεν θα παραδοθεί ξανά. Τα webhooks είναι ειδοποιήσεις και όχι χώρος αποθήκευσης αντιγράφων δεδομένων: χρησιμοποιήστε τα endpoints συνομιλιών του Bot Talk API ή εξαγωγές υποψήφιων πελατών (leads) για τον συγχρονισμό των διατηρούμενων δεδομένων όπου υποστηρίζεται. Το Management API καλύπτει τις ρυθμίσεις και τη χρήση του bot, όχι ένα πλήρες αρχείο συμβάντων. Ορισμένα συμβάντα δεν μπορούν να ανακατασκευαστούν μέσω αυτών των διεπαφών.
  • Μηχανισμός διακοπής κυκλώματος (Circuit breaker). Μετά από 5 συνεχόμενες αποτυχημένες παραδόσεις για έναν συνδυασμό endpoint/bot, οι παραδόσεις για αυτόν τον συνδυασμό τίθενται σε παύση για 5 λεπτά. Τα συμβάντα που προκύπτουν κατά τη διάρκεια της παύσης απορρίπτονται και το αρχείο καταγραφής παραδόσεων εμφανίζει εγγραφές CIRCUIT_OPEN για την ταυτοποίηση των προσπαθειών που αποτράπηκαν. Οι παραδόσεις που παραλείπονται λόγω ανοιχτού κυκλώματος δεν προσμετρώνται στην αυτόματη απενεργοποίηση.
  • Αυτόματη απενεργοποίηση. Ο έλεγχος εκτελείται τη στιγμή που αποτυγχάνει μια παράδοση, ποτέ με χρονοδιακόπτη. Εάν μια παράδοση αποτύχει και δεν έχει υπάρξει καμία επιτυχής παράδοση για 7 ημέρες - υπολογίζοντας από την τελευταία επιτυχία ή από την ημερομηνία δημιουργίας του endpoint εάν δεν είχε ποτέ καμία επιτυχία - το endpoint απενεργοποιείται και λαμβάνετε μια ειδοποίηση μέσω email. Ένας μεμονωμένος κωδικός 2xx οποιαδήποτε στιγμή μηδενίζει αυτόν τον μετρητή. Ένα endpoint που δεν δέχεται κίνηση δεν απενεργοποιείται ποτέ, επειδή τίποτα δεν αποτυγχάνει. Επανενεργοποιήστε το από το Account settings (Ρυθμίσεις λογαριασμού) μόλις διορθωθεί ο δέκτης σας. Ο μετρητής αποτυχιών και η ένδειξη αυτόματης απενεργοποίησης εκκαθαρίζονται μόλις το ενεργοποιήσετε ξανά, ενώ τα συμβάντα που χάθηκαν κατά τη διάρκεια της απενεργοποίησης δεν αναπληρώνονται αναδρομικά.
  • 410 Gone. Εάν το endpoint σας απαντήσει με HTTP 410 Gone, το ChatLab το απενεργοποιεί αμέσως. Χρησιμοποιήστε το για να αποσύρετε μέσω προγραμματισμού ένα endpoint από την πλευρά του παραλήπτη.
  • Idempotency (Ισοδυναμία). Δεν αναμένονται διπλότυπες παραδόσεις υπό κανονική λειτουργία, αλλά εάν η επεξεργασία σας πρέπει να είναι αυστηρά ισοδύναμη, αφαιρέστε τα διπλότυπα με βάση το eventId (διαθέσιμο επίσης στην κεφαλίδα X-ChatLab-Delivery).

Η σειρά παράδοσης δεν είναι εγγυημένη. Αποθηκεύστε το αναγνωριστικό συμβάντος και διασφαλίστε ότι η επιχειρησιακή επεξεργασία είναι ισοδύναμη (idempotent). Διατηρήστε τις δικές σας πολιτικές διατήρησης και ελέγχους πρόσβασης για τα δεδομένα των webhooks, τα οποία ενδέχεται να περιέχουν προσωπικά δεδομένα και συνδέσμους λήψης αρχείων.

Τα παραδείγματα υπογραφής χρησιμοποιούν το crypto του Node.js και τη συνάρτηση hash_equals της PHP. Καταγράψτε το αρχικό σώμα του αιτήματος (raw request body) πριν το αναλύσετε.

Όρια

  • Έως 10 endpoints webhooks ανά λογαριασμό.
  • Διατήρηση αρχείου καταγραφής παραδόσεων: 14 ημέρες. Οι παλαιότερες εγγραφές αφαιρούνται αυτόματα.

Σχετικά άρθρα