Πήγαινε στο κύριο περιεχόμενο

Webhooks στο Legalesign

Τι είναι τα webhooks

Τα webhooks είναι οι URL σας όπου το Legalesign θα στέλνει ενημερώσεις κατάστασης σε πραγματικό χρόνο. Μπορείτε να δημιουργήσετε δικά σας URLs ή συστήματα αυτοματοποίησης (όπως το MS Power Automate) μπορούν να τα δημιουργήσουν για να ξεκινήσουν μια ροή εργασίας.

Για παράδειγμα, σε αυτήν την επίδειξη δημιουργούμε ένα URL με το Microsoft Power Automate. Προσθέτουμε αυτό το URL ως webhook στο Legalesign για όταν υπογράφονται έγγραφα. Η ροή του Power Automate ενεργοποιείται όταν υπογράφεται ένα έγγραφο και αποθηκεύει αυτόματα τα νέα υπογεγραμμένα PDF στο Sharepoint. Μάθετε περισσότερα για το MS Power Automate.

πληροφορίες

Σημαντική σημείωση – πρέπει να έχετε δικαιώματα Διαχειριστή της ομάδας για να λαμβάνετε γεγονότα της ομάδας στο webhook σας.

Γιατί χρειάζεστε webhooks

Τα webhooks σας επιτρέπουν να διατηρείτε ένα σύστημα βασισμένο σε γεγονότα. Τα webhooks θα σας ενημερώνουν για όλα τα γεγονότα εντός των ομάδων σας. Μπορείτε να τα χρησιμοποιήσετε για να δημιουργήσετε τον δικό σας πίνακα ζωντανών δεδομένων και/ή να τα χρησιμοποιήσετε για συγχρονισμό με τη δική σας βάση δεδομένων.

Όπως αναφέρθηκε παραπάνω, τα παραγόμενα webhooks από συστήματα αυτοματοποίησης όπως το Power Automate σας επιτρέπουν να ξεκινήσετε διαδικασίες αποθήκευσης, αποστολής email, διατήρησης αρχείων κτλ., που σε συνδυασμό με το API παρέχουν όλα όσα χρειάζεστε για αυτοματοποίηση διαδικασιών.

Εναλλακτική λύση σε πραγματικό χρόνο με websocket

Διατίθεται επίσης μια ροή συνδρομής websocket σε πραγματικό χρόνο. Αυτό μπορεί να ταιριάζει καλύτερα όταν θέλετε ζωντανές ενημερώσεις από την πλευρά του πελάτη χωρίς να αποκαλύπτετε ένα endpoint webhook. Το websocket αποκαλύπτει ένα ευρύτερο σύνολο γεγονότων από τα webhooks.

Δείτε: Γρήγορο ξεκίνημα με Websocket σε πραγματικό χρόνο

συμβουλή

Ναι, τα webhooks φαίνονται κουραστικά, αλλά αξίζουν τον κόπο και είναι εξαιρετικά για την ενσωμάτωσή σας. Συνεχίστε να διαβάζετε.

Τύποι webhook

  • Γεγονότα σε πραγματικό χρόνο
  • Όλα τα γεγονότα κάθε 6 λεπτά (παλαιά μέθοδος)
  • Μετά από [γεγονός] (παλαιά μέθοδος)

Για παλαιά webhooks δείτε: παλαιά webhooks

πληροφορίες

Τα webhooks χρησιμοποιούνται πιο συχνά για τη λήψη ενός υπογεγραμμένου PDF. Όταν δημιουργείτε το webhook, εφαρμόστε το φίλτρο γεγονότος 'Τελικό PDF δημιουργήθηκε'. Στον κώδικά σας, το εισερχόμενο request.body είναι JSON, αναλύστε το και εξάγετε documentId = ['data']['uuid']. Τώρα εκτελέστε το API αίτημα για λήψη του PDF - GET https://eu-api.legalesign.com/api/v1/pdf/${documentId}/.

Πώς να προσθέσετε ή να αφαιρέσετε ένα webhook

Προσθήκη ή αφαίρεση webhook μέσω της web εφαρμογής

Μεταβείτε στον Πίνακα ελέγχου API και κάντε κλικ στην ενότητα Webhooks. Η φόρμα διαθέτει απλούς ελέγχους για την προσθήκη ή αφαίρεση webhooks. Μπορείτε προαιρετικά να περιορίσετε τα γεγονότα webhook σε συγκεκριμένες ομάδες και/ή γεγονότα.

Screenshot Ενότητας Webhooks

κίνδυνος

Τα webhooks σας λαμβάνουν γεγονότα από όλους τους λογαριασμούς όπου είστε διαχειριστής, τόσο τους dev όσο και τους prod. Χρησιμοποιήστε το φίλτρο ομάδας για να δημιουργήσετε διαφορετικά webhooks για τις διάφορες ομάδες σας.

Προσθήκη ή αφαίρεση webhook μέσω του REST API

Δείτε την ενότητα 'webhook' στο κάτω μέρος του αριστερού πλοηγού στην τεκμηρίωση API: REST API webhooks

Προσθήκη ή αφαίρεση webhook μέσω GraphQl

Νέο! Εάν χρησιμοποιείτε την πιστοποίηση SRP και το περιβάλλον GraphQL, έχετε πλήρη δικαιώματα CRUD. Δοκιμάστε το Legalesign GraphiQL Explorer. Τα webhooks μπορούν να εμφανίζονται ως ιδιότητα του τύπου User και υπάρχουν μεταλλάξεις για createWebhook, updateWebhook και deleteWebhook.

Τι περιέχει ένα webhook;

Ο ταχύτερος τρόπος να ελέγξετε τα δεδομένα σας είναι να προσθέσετε ένα webhook, να στείλετε/υπογράψετε/απορρίψετε κάποια δοκιμαστικά έγγραφα στην web εφαρμογή και μετά να δείτε το αρχείο καταγραφής webhooks στον Πίνακα API του Legalesign.

Εάν χρειάζεστε προσωρινό URL webhook για δοκιμές, δοκιμάστε το ngrok.

Γρήγορος οδηγός για το ngrok: μόλις κατεβάσετε το ngrok, ξεκινήστε το τερματικό με ./ngrok http 80 και θα σας δώσει μια διεύθυνση https. Εισάγετε την ως το webhook σας. Τώρα ανοίξτε το http://127.0.0.1:4040. Αυτό ήταν, θα αρχίσετε να βλέπετε όλα τα webhooks και τα δεδομένα τους. Αρχίστε να στέλνετε και να υπογράφετε δοκιμαστικά έγγραφα. Σημείωση: Το Ngrok μπορεί να επιστρέψει σφάλμα 5XX, οπότε περιμένετε να δείτε πολλαπλές προσπάθειες και μηνύματα σφάλματος, καθώς το σύστημα θα θεωρήσει το καθεστώς 5XX ως αποτυχημένη προσπάθεια.

πληροφορίες

Βεβαιωθείτε ότι ο κώδικας που λαμβάνει το webhook επιστρέφει απάντηση επιτυχίας 2XX. Εάν έχετε πολλές πιθανές εξαιρέσεις στον κώδικά σας, επιστρέψτε διαφορετικούς κωδικούς κατάστασης 5XX. Τα αρχεία καταγραφής webhook στον πίνακα API θα σας πουν ποια εξαίρεση ενεργοποιήθηκε.

Η μορφή του webhook σε πραγματικό χρόνο

Η μορφή των δεδομένων μπορεί να είναι σε ένα από δύο σχήματα, είτε σχήμα 'document' είτε σχήμα 'recipient'. Εξετάστε την ιδιότητα 'object' για να προσδιορίσετε με ποιο σχήμα ασχολείστε.

Και τα δύο σχήματα έχουν επίσης την ιδιότητα 'event'. Μπορείτε να φιλτράρετε κατά αντικείμενο και προαιρετικά κατά γεγονός όταν δημιουργείτε το webhook.

Πίνακας όλων των πιθανών αντικειμένων και γεγονότων παρακάτω. Αυτή η εικόνα απεικονίζει ένα αντικείμενο εγγράφου (για γεγονός 'created'). Τα πλήρη JSON σχήματα επισυνάπτονται στο τέλος αυτού του άρθρου.

δεδομένα εγγράφου στο ngrok

Τα αιτήματα φτάνουν ως αίτημα POST που περιέχει JSON. Παρακαλούμε σημειώστε, το περιεχόμενο του 'data' μπορεί να επεκταθεί για να περιλάβει περισσότερα πεδία με την πάροδο του χρόνου.

συμβουλή

Χρησιμοποιήστε τις ιδιότητες 'tag'. Μπορείτε να ορίσετε έως και 3 ετικέτες κατά τη δημιουργία ενός εγγράφου. Χρησιμοποιώντας τις ετικέτες, ενδεχομένως να μην χρειαστεί να αποθηκεύετε τα IDs του Legalesign. Μπορείτε επίσης να χρησιμοποιήσετε την ετικέτα για να αποθηκεύσετε ένα μυστικό για επαλήθευση του εισερχόμενου αιτήματος (ευχαριστούμε τον Themis για την πρόταση).

Πίνακας πιθανών συνδυασμών για 'object' και 'event':

αντικείμενογεγονός
documentcreated
documentrejected
documentfinalPdfCreated
recipientcompleted
recipientrejected
recipientemailOpened
recipientvisiting
recipientbounced
recipientautoReminderEmail
recipientemailNotification

Τα περισσότερα γεγονότα συμβαίνουν μόνο μία φορά. Οι εξαιρέσεις είναι τα visiting, bounced, emailNotification και autoReminderEmail, που μπορεί να συμβούν πολλές φορές.

προειδοποίηση

Μην ξεχνάτε να απενεργοποιήσετε την προστασία CSRF για την προβολή που λαμβάνει αυτά τα αιτήματα POST.

Ακολουθεί ένα παράδειγμα ενός αντικειμένου 'recipient', με γεγονός 'bounced':

δεδομένα παραλήπτη στο ngrok

Παρατηρήστε τις emailBounce και emailBounceMessage στο 'data'. Η 'emailBounceMessage' δείχνει τον τύπο bounce ως εξής:

  • Σοβαρό bounce: "Message hard bounced"
  • Μαλακό bounce: "Email soft bounced (either out of office or a timeout)"
  • Καθυστερημένο: "Message delayed (check email domain exists)"
πληροφορίες

Το σχήμα μπορεί να έχει νέες ιδιότητες προσθεθείσες οποιαδήποτε στιγμή.

Εντοπισμός σφαλμάτων webhooks στον πίνακα API

Όλα τα webhooks καταγράφονται και μπορείτε να εξετάσετε το περιεχόμενο και τον κωδικό κατάστασης HTTP στον πίνακα API σας. Για περισσότερες πληροφορίες δείτε το εγχειρίδιο πίνακα

Χειροκίνητη ενεργοποίηση webhook

Ενεργοποιήστε χειροκίνητα ένα webhook χρησιμοποιώντας τη φόρμα στο κάτω μέρος της σελίδας Webhooks στο Developer Portal.

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

Κωδικοί κατάστασης

Κάντε κλικ σε αυτούς τους συνδέσμους για να δείτε τον πίνακα αναφοράς για κατάσταση εγγράφου και κατάσταση παραλήπτη.

Επαλήθευση webhook

Το webhook υπογράφει το πακέτο δεδομένων με ένα ιδιωτικό κλειδί. Μπορείτε να το επαληθεύσετε με το δημόσιο κλειδί - κατεβάστε το δημόσιο κλειδί.

  • Η θέση της συμβολοσειράς υπογραφής είναι στην κεφαλίδα X-Signed-SHA256.
  • Τα δεδομένα που υπογράφονται είναι ολόκληρο το request.body (ως συμβολοσειρά).

Η ‘υπογραφή’ είναι κωδικοποιημένη σε base64. Ακολουθεί δείγμα κώδικα επαλήθευσης σε node.js:

const crypto = require('crypto');
const fs = require('fs');

const cert = fs.readFileSync('/location/of/downloadedCert.crt', 'utf8');
const c = new crypto.X509Certificate(cert);
const k = c.publicKey
let verifier = crypto.createVerify('SHA256');
let rawdata = 'sentdata' //JSON stringify data in request.body
let sha256signature = 'xxx' //value of 'X-Signed-Sha256' request header.
verifier.update(rawdata);
return verifier.verify(k, sha256signature, 'base64');

Προαιρετικά, είναι διαθέσιμη επαλήθευση βασισμένη σε HMAC. Για το HMAC, ένα μυστικό κλειδί για τα webhooks σας κοινοποιείται σε εσάς. Η υπογεγραμμένη τιμή θα φτάσει στην κεφαλίδα X-HMAC-SHA256.

Υπάρχουν πολλές διαδικτυακές πηγές που δείχνουν πώς να επαληθεύσετε μια τιμή HMAC. Δείγμα επαλήθευσης σε python θα ήταν:

import hmac, hashlib
sentdata = 'sentdata' # JSON stringify data in request.body
hmacvalue = 'xxx' # value of 'X-HMAC-Sha256' in request header.
v = hmac.new('your secret value'.encode(), 'sentdata'.encode(), hashlib.sha256)
isValid = v.hexdigest() == hmacvalue

Ή δείγμα κώδικα Apex του Salesforce για επαλήθευση HMAC είναι:

String message = 'JSONstring'; //sent in request.body
String privatekey = 'privateKey'; //shared value you have been given
String hmacvalue = 'xxx'; //value of 'X-HMAC-Sha256' in request header.
Boolean verified = Crypto.verifyHMac('HmacSHA256', Blob.valueOf(message), Blob.valueOf(privatekey), EncodingUtil.convertFromHex(hmacvalue));

Χρειάζεστε περισσότερα webhooks;

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

Αναφορά σχήματος

Υπάρχουν δύο πιθανά σχήματα, ένα για το αντικείμενο 'document' και ένα άλλο για το αντικείμενο 'recipient'. Και τα δύο σχήματα έχουν επίπεδα κλειδιά 'object' και 'event'. Εξετάστε την ιδιότητα 'object' για να προσδιορίσετε το σχήμα που χρησιμοποιείτε. Ή χρησιμοποιήστε φίλτρο webhook για να επιστραφούν μόνο αντικείμενα εγγράφου ή μόνο παραλήπτη.

Σημείωση: το σχήμα μπορεί να λάβει νέες ιδιότητες οποιαδήποτε στιγμή (αλλά δεν μειώνονται).

1. JSON Σχήμα για το αντικείμενο 'document'

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"version": {
"type": "string",
"default": "1.0.0"
},
"object": {
"type": "string",
"default": "document"
},
"created": {
"type": "integer",
"description": "unix timestamp"
},
"id": {
"type": "string",
"format": "uuid"
},
"event": {
"type": "string",
"pattern": "^(created|rejected|finalPdfCreated)$"
},
"data": {
"type": "object",
"properties": {
"tag1": {
"type": "string"
},
"recipients": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"uuid": {
"type": "string",
"format": "uuid"
},
"email": {
"type": "string",
"format": "email"
},
"order": {
"type": "integer"
},
"status": {
"type": "integer"
"pattern": "^(4|5|10|15|20|30|35|39|40|50|60)$"
},
"lastname": {
"type": "string"
},
"roleText": {
"type": "string",
"pattern": "^(signer|approver|witness)$"
},
"firstname": {
"type": "string"
},
"statusText": {
"type": "string",
"pattern": "^(unsent|scheduled|sent|email opened|visited|fields complete|fields complete excluding signature|witnessing required|completed|download final document|rejected|withdrawn)$"
},
"resourceUri": {
"type": "string",
"format": "uri-reference"
},
"rejectReason": {
"type": "string"
}
},
"required": [
"uuid",
"email",
"order",
"status",
"lastname",
"roleText",
"firstname",
"statusText",
"resourceUri",
"rejectReason"
]
}
]
},
"groupResourceUri": {
"type": "string",
"format": "uri-reference"
},
"statusText": {
"type": "string",
"pattern": "^(available|fields complete|completed|removed|rejected|unknown)$"
},
"name": {
"type": "string"
},
"tag": {
"type": "string"
},
"resourceUri": {
"type": "string",
"format": "uri-reference"
},
"uuid": {
"type": "string",
"format": "uuid"
},
"tag2": {
"type": "string"
},
"group": {
"type": "string"
},
"status": {
"type": "integer",
"pattern": "^(10|20|30|40|50)$"
}
},
"required": [
"tag1",
"recipients",
"groupResourceUri",
"statusText",
"name",
"tag",
"resourceUri",
"uuid",
"tag2",
"group",
"status"
]
}
},
"required": [
"version",
"object",
"data",
"created",
"id",
"event"
]
}

2. JSON σχήμα για το αντικείμενο 'recipient'

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"version": {
"type": "string",
"default": "1.0.0"
},
"object": {
"type": "string",
"default": "recipient"
},
"created": {
"type": "integer",
"format": "date-time"
},
"id": {
"type": "string",
"format": "uuid"
},
"event": {
"type": "string",
"pattern": "^(emailOpened|bounced|visiting|rejected|completed|autoReminderEmail|emailNotification)$"
},
"data": {
"type": "object",
"properties": {
"tag": {
"type": "string"
},
"tag1": {
"type": "string"
},
"tag2": {
"type": "string"
},
"uuid": {
"type": "string",
"format": "uuid"
},
"email": {
"type": "string",
"format": "email"
},
"group": {
"type": "string",
"format": "uuid"
},
"order": {
"type": "integer"
},
"status": {
"type": "integer",
"pattern": "^(4|5|10|15|20|30|35|39|40|50|60|70)$"
},
"document": {
"type": "string"
},
"documentName": {
"type": "string"
},
"lastname": {
"type": "string"
},
"roleText": {
"type": "string"
},
"firstname": {
"type": "string"
},
"statusText": {
"type": "string",
"pattern": "^(unsent|scheduled|sent|email opened|visited|fields complete|fields complete excluding signature|witnessing required|completed|download final document|rejected|withdrawn)$"
},
"emailBounce": {
"type": "integer"
},
"resourceUri": {
"type": "string",
"format": "uri-reference"
},
"rejectReason": {
"type": "string"
},
"groupResourceUri": {
"type": "string",
"format": "uri-reference"
},
"emailBounceMessage": {
"type": "string"
},
"documentResourceUri": {
"type": "string",
"format": "uri-reference"
}
},
"required": [
"tag",
"tag1",
"tag2",
"uuid",
"email",
"group",
"order",
"status",
"document",
"documentName",
"lastname",
"roleText",
"firstname",
"statusText",
"emailBounce",
"resourceUri",
"rejectReason",
"groupResourceUri",
"emailBounceMessage",
"documentResourceUri"
]
}
},
"required": [
"version",
"object",
"data",
"created",
"id",
"event"
]
}