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

Webhooks

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

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

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

Τυπικές χρήσεις:

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

Διαθεσιμότητα: τα webhooks είναι διαθέσιμα από το πλάνο Standard και άνω (λειτουργία: Webhooks).

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

Ρύθμιση ενός endpoint

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

Κάθε endpoint διαθέτει επίσης:

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

Περίβλημα συμβάντος (Event envelope)

Κάθε παράδοση είναι ένα 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 - μοναδικό ανά συμβάν. Χρησιμοποιήστε το για απαλοιφή διπλοτύπων εάν η επεξεργασία σας πρέπει να είναι ταυτοδύναμη (idempotent).
  • eventType - ένας από τους τύπους που περιγράφονται παρακάτω - αποστέλλεται επίσης στην κεφαλίδα X-ChatLab-Event.
  • timestamp - ημερομηνία και ώρα UTC κατά ISO 8601 όταν συνέβη το συμβάν.
  • botId / botName - το bot στο οποίο ανήκει το συμβάν.
  • conversationId / sessionId - το πλαίσιο της συνομιλίας, όπου εφαρμόζεται.

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

lead.created

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

{
  "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.
  • Όταν χρησιμοποιείται μια προσαρμοσμένη φόρμα για συλλογή lead, κάθε πεδίο που ορίζεται σε αυτήν τη φόρμα περιλαμβάνεται στο fields, με τη σειρά της φόρμας, και τα formCodeName / formName ταυτοποιούν τη φόρμα. Με την κλασική φόρμα lead και τα δύο είναι null και το fields είναι ένας κενός πίνακας.
  • Κάθε καταχώριση στο fields έχει τη μορφή {name, value, type}. Το name είναι το τεχνικό όνομα του πεδίου, το οποίο παραμένει σταθερό μετά από αλλαγές ετικετών - χρησιμοποιήστε το για αντιστοίχιση στο CRM σας.
  • Για πεδία multichoice, το value είναι ένας πίνακας με τις επιλεγμένες επιλογές. Τα πεδία πλαισίων ελέγχου (checkbox) είναι μεμονωμένες καταχωρίσεις με τιμές "true" / "false".
  • Για πεδία file, το value είναι ένας σύνδεσμος λήψης για το αρχείο που μεταφορτώθηκε - το webhook δεν μεταφέρει ποτέ τα περιεχόμενα του αρχείου.
  • pageUrl - η σελίδα στην οποία βρισκόταν ο επισκέπτης κατά την υποβολή.

contact_form.submitted

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

{
  "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 ή η ανθρώπινη επικοινωνία ενεργοποιούν επίσης το αποκλειστικό τους συμβάν 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

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

{
  "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"
  }
}
  • summary - το παραγόμενο κείμενο σύνοψης. Οι συνόψεις δημιουργούνται λίγα λεπτά αφού η συνομιλία καταστεί ανενεργή, επομένως αυτό το συμβάν καταφθάνει αργότερα από τα υπόλοιπα συμβάντα της συνομιλίας.
  • language - κωδικός ISO της γλώσσας στην οποία συντάχθηκε η σύνοψη, ακολουθώντας τη γλώσσα της συνομιλίας.

client.summarized

Ενεργοποιείται όταν το ChatLab ανανεώνει το προφίλ AI ενός πελάτη. Το προφίλ αναδομείται από το προηγούμενο προφίλ σε συνδυασμό με τη σύνοψη της συνομιλίας που μόλις ολοκληρώθηκε, επομένως αυτό το συμβάν ακολουθεί το conversation.summarized για την ίδια συνομιλία. Οι πελάτες ταυτοποιούνται μέσω e-mail, γι' αυτό και η διεύθυνση επαναλαμβάνεται στο ανώτατο επίπεδο του αντικειμένου data.

{
  "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, ακόμη και όταν ο επισκέπτης το ζητά ρητά με δικά του λόγια. Αντιμετωπίστε το ως ανοιχτή απαρίθμηση (open enum): διαχειριστείτε άγνωστες τιμές αντί να επιβάλλετε αυστηρά την τιμή AI.
  • Το συμβάν υποδηλώνει ότι ζητήθηκε μεταβίβαση, όχι ότι την ανέλαβε κάποιος χειριστής. Περιμένετε το live_chat.started για αυτό.

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 είναι σκόπιμα κενό. Όλα όσα χρειάζεστε βρίσκονται στο περίβλημα: το botId ταυτοποιεί το chatbot και τα conversationId / sessionId συνδέουν το συμβάν με τη συνομιλία για την οποία είχατε ήδη λάβει το live_chat.requested.

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 - η διάρκεια παραμονής του χειριστή στη συνομιλία, μετρούμενη από τη στιγμή έναρξης της συνεδρίας. Το πεδίο παραλείπεται στη σπάνια περίπτωση που μια συνεδρία λήγει χωρίς να έχει ξεκινήσει ποτέ.

ai_action.executed

Ενεργοποιείται κάθε φορά που το bot εκτελεί μια ενέργεια 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 - η διάρκεια εκτέλεσης της ενέργειας, σε χιλιοστά του δευτερολέπτου (ms). Χρήσιμο για τον εντοπισμό μιας αργής ενσωμάτωσης προτού διαμαρτυρηθούν οι επισκέπτες.
  • 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 - σταθερό κείμενο, πάντα το ίδιο. Τα πεδία του περιβλήματος φέρουν δοκιμαστικές τιμές (sample values), επομένως μην αντιμετωπίζετε ποτέ μια παράδοση webhook.test ως πραγματικά δεδομένα.
  • Αυτός είναι ο μοναδικός τύπος συμβάντος στον οποίο δεν μπορείτε να εγγραφείτε σε ένα endpoint: αποστέλλεται κατ' απαίτηση από τον πίνακα διαχείρισης και φτάνει πάντα στο endpoint στο οποίο κάνατε κλικ, ανεξάρτητα από τα συμβάντα που αυτό παρακολουθεί.

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

Κάθε παράδοση περιλαμβάνει τέσσερις κεφαλίδες (headers):

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

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

Για προστασία από επιθέσεις επανάληψης (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 (!signature || !timestamp) 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 + '.' + 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 === '') {
        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 και απορρίψτε το payload. Μην επεξεργάζεστε ποτέ μη επαληθευμένες παραδόσεις - οποιοσδήποτε ανακαλύψει τη διεύθυνση URL σας μπορεί να στείλει αυθαίρετο JSON μέσω POST σε αυτήν.

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

Κατανοήστε αυτές τις εγγυήσεις προτού αναπτύξετε λειτουργίες βασισμένες σε webhooks:

  • Απαντήστε γρήγορα. Το endpoint σας πρέπει να απαντήσει εντός 3 δευτερολέπτων, διαφορετικά η παράδοση θεωρείται αποτυχημένη. Απαντήστε αμέσως με 2xx και επεξεργαστείτε το payload ασύγχρονα (τοποθετήστε το σε ουρά και, στη συνέχεια, επιβεβαιώστε τη λήψη) - μην πραγματοποιείτε κλήσεις CRM ή εγγραφές σε βάσεις δεδομένων πριν απαντήσετε.
  • Fire-and-forget, το πολύ μία φορά (at-most-once). Κάθε συμβάν λαμβάνει ακριβώς μία προσπάθεια παράδοσης - δεν υπάρχουν επαναλήψεις. Εάν το endpoint σας είναι εκτός λειτουργίας, υπερβεί το χρονικό όριο ή επιστρέψει κατάσταση μη-2xx, το συμβάν αυτό χάνεται και δεν θα παραδοθεί ξανά. Τα webhooks είναι ειδοποιήσεις, όχι ένας αντιγραμμένος χώρος αποθήκευσης δεδομένων: όταν χρειάζεστε εγγυημένη πληρότητα, κάντε διασταύρωση με το Management API ή τις εξαγωγές των lead σας.
  • Μηχανισμός διακοπής κυκλώματος (Circuit breaker). Μετά από 5 συνεχόμενες αποτυχημένες παραδόσεις για ένα bot, οι παραδόσεις για αυτό το 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).

Όρια

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

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

  • Lead collection - η φόρμα πίσω από το lead.created
  • Human Support Contact form - η φόρμα πίσω από το contact_form.submitted
  • Live Chat - η ροή πίσω από τα συμβάντα live_chat.*
  • Conversation rating - η θετική/αρνητική αξιολόγηση πίσω από το conversation.rated
  • AI Actions - οι ενσωματώσεις πίσω από το ai_action.executed
  • Chat API - callbacks του widget εντός του προγράμματος περιήγησης (το αντίστοιχο των webhooks στην πλευρά του πελάτη)
  • Management API - REST API για διαχείριση bot και δεδομένα χρήσης