Cet article s'applique aux clients de l'offre Growth Voice of Customer.
Les Webhooks Contentsquare vous permettent d'être notifié lorsqu'un événement se produit, comme lorsqu'un visiteur de votre site web soumet une nouvelle réponse à une enquête. Vous configurez un "webhook" (une URL) sur votre propre site web ou sur le site web d'une entreprise partenaire, partagez ce webhook avec Contentsquare, puis recevez des charges d'événements lorsque des événements se produisent. Les Webhooks sont donc un moyen d'envoyer des données à vos systèmes en temps réel.
En termes techniques :
Vous configurez un webhook, généralement sur votre propre serveur/site web, avec une URL unique.
Dans l'interface Contentsquare, vous saisissez l'URL du webhook sur un Segment d'enquête ou de résumé.
Contentsquare envoie ensuite des requêtes POST HTTP à votre URL de webhook chaque fois qu'une nouvelle réponse à une enquête est créée, ou lorsqu'un nouveau résumé correspondant à votre segment de résumé est créé.
Pourquoi utiliser les Webhooks ?
Les Webhooks complètent l'API Contentsquare. Alors que l'API est plus utile pour l'export en masse (téléchargement), les Webhooks sont utiles pour recevoir immédiatement des réponses à des enquêtes, ou des résumés basés sur des segments de résumé au fur et à mesure de leur création. Vous devriez envisager d'utiliser les Webhooks si :
- Vous souhaitez recevoir des données immédiatement.
- Vous souhaitez envoyer des données à vos systèmes, peut-être à un entrepôt de données, sans avoir à interroger notre API.
- Un partenaire propose une intégration avec Contentsquare via les Webhooks.
Comment fonctionnent les Webhooks
Lorsqu'un événement se produit, Contentsquare enverra un message à chaque Webhook configuré :
- Le message est envoyé sous forme de requête POST HTTP à votre webhook.
- La requête sera encodée en UTF-8.
- Le type de contenu sera
application/json
. - Le corps de la requête sera donc un objet JSON avec les propriétés suivantes :
event
- chaîne. La valeur de cette propriété est le nom de l'événement. Au moment de la rédaction de cet article, il s'agira de survey_response, replay ou test_message.version
- entier. Cette propriété est réservée pour une utilisation future, actuellement elle sera toujours définie sur le nombre 1.data
- La valeur de cette propriété sera un objet JSON avec les données de l'événement. Les champs de l'objet sont spécifiques à chaque événement (voir ci-dessous).
Nous envoyons les événements dès que possible après leur survenance ; en pratique, vous devriez recevoir un message en quelques secondes seulement. Dans des circonstances exceptionnelles, les messages peuvent être retardés, mais chaque événement inclut la date et l'heure à laquelle il s'est produit, nous vous recommandons donc d'utiliser ces informations plutôt que la date et l'heure à laquelle votre webhook reçoit un message.
Contentsquare ne garantit pas que l'ordre des messages reçus correspond à l'ordre des événements survenus. Certains événements contiennent un paramètre index
qui peut être utilisé pour l'ordonnancement.
Exigences des Webhooks
Votre webhook doit respecter les exigences suivantes :
- Le webhook doit être en HTTPS (TLS).
- Le serveur doit répondre dans les 10 secondes.
- Le serveur doit répondre avec un code d'état HTTP 2XX (tout code d'état HTTP entre 200 et 299).
- Le serveur doit accepter tout type d'événement inattendu sans renvoyer d'erreur.
- Le serveur doit gérer les messages dupliqués accidentels. Bien que Contentsquare s'efforce d'envoyer un message à votre webhook une seule fois, nous ne pouvons le garantir. Votre webhook doit donc se fier à l'identifiant unique dans le message pour la déduplication.
Nouvelles tentatives
Contentsquare tentera de renvoyer l'envoi d'un webhook en cas d'erreur. Contentsquare réessaiera jusqu'à six fois, en faisant une pause entre chaque tentative :
Tentative de réessai | Délai avant de réessayer |
1 | 30 secondes |
2 | 1 minute |
3 | 2 minutes |
4 | 5 minutes |
5 | 10 minutes |
6 |
20 minutes |
Contentsquare réessayera l'envoi jusqu'à ce que l'une des situations suivantes se produise :
- Le webhook répond avec un code d'état 2XX (c'est-à-dire une réponse réussie).
- Le webhook répond avec un code d'état 410 (auquel cas Contentsquare supprimera le webhook de votre enquête ou segment de révision).
- Maximum 6 tentatives de réessai sont atteintes.
Signatures et prévention de la révision
Les webhooks de Contentsquare utilisent deux techniques de sécurité pour vous permettre de vérifier que tout contenu que vous recevez provient réellement de Contentsquare :
- Tous les contenus envoyés à vos webhooks sont signés par HMAC ; vous êtes fortement encouragé à vérifier la signature pour savoir que les données proviennent réellement de Contentsquare
- Tous les contenus incluent une horodatage pour que vous puissiez vérifier que les données ont été envoyées par Contentsquare dans les dernières minutes. Cela vous permet de lutter contre les attaques de révision car vous pouvez être sûr que Contentsquare vous a envoyé ces données dans les dernières minutes.
Vérification de la signature du contenu
La signature est envoyée à votre webhook en tant qu'en-tête personnalisé nommé com-Contentsquare-signature. Pour vérifier que la signature est valide, vous devez :
1. Générer une signature à partir du contenu que vous avez reçu
2. Vérifier si votre signature générée correspond à la signature dans l'en-tête
Vous pouvez générer une signature en utilisant HMAC-SHA3-256, le contenu (en bytes) et une clé de signature. Pour obtenir la clé de signature pour votre site Contentsquare, ouvrez les paramètres d'intégration des Webhooks dans l'application Contentsquare et cliquez sur "Voir la clé du webhook".
Une fois que vous avez généré une signature, vous pouvez la comparer à la signature envoyée dans l'en-tête com-Contentsquare-signature. Si les deux valeurs correspondent, alors la signature a été validée avec succès, si elles ne correspondent pas, vous devez rejeter le contenu et ne pas agir dessus.
Protection contre les attaques de révision
La signature HMAC vous permet de vérifier que Contentsquare a créé le contenu du webhook mais un attaquant pourrait envoyer le même contenu à plusieurs reprises et la vérification de la signature réussirait. Pour vous protéger contre ces "attaques de révision", nous envoyons également une horodatage dans le contenu, si la date et l'heure spécifiées dans l'horodatage sont trop anciennes (nous suggérons 5+ minutes dans le passé), vous devez rejeter le contenu.
Pour vérifier l'horodatage, vous devez d'abord vérifier la signature HMAC, comme décrit ci-dessus, avant de vérifier l'horodatage car un attaquant pourrait simplement envoyer un horodatage valide dans un contenu. L'horodatage est un horodatage UNIX, ce qui signifie que c'est le nombre de secondes depuis l'époque Unix. Vous pouvez voir des exemples d'horodatages dans les contenus d'exemple ci-dessous.
Contenus
Contentsquare peut ajouter des champs supplémentaires à ces contenus à l'avenir, donc votre webhook ne doit pas générer d'erreur lorsqu'un champ est présent alors que vous ne vous y attendiez pas. Notez que tout champ peut être défini sur null en plus du type indiqué.
Réponse à l'enquête
Nom de l'événement : survey_response
id
entier - L'identifiant unique de la réponse à l'enquête.index
entier - L'index de cette réponse à l'enquête dans l'enquête.api_id
chaîne - L'identifiant public (inclut l'UUID) faisant référence à cette réponse à l'enquête.response_url
chaîne - Le lien pour visualiser la réponse dans l'appli Hotjar.site_id
entier - L'identifiant unique du site Hotjar.survey_id
entier - L'identifiant unique de l'enquête.survey_name
chaîne - Le nom de l'enquête.survey_url
chaîne - Le lien pour visualiser l'enquête dans l'appli Hotjar.device
chaîne - Le type d'appareil utilisé pour soumettre la réponse à l'enquête. Ce sera "Tablette", "Mobile" ou "Ordinateur".browser
chaîne - Le nom du navigateur utilisé pour soumettre la réponse à l'enquête.os
chaîne - Le nom du système d'exploitation utilisé pour soumettre la réponse à l'enquête.country_code
chaîne - L'indicatif téléphonique international à partir duquel la réponse à l'enquête a été créée. Consultez les codes de pays ISO 3166 pour une liste de ces codes.country_name
chaîne - Le pays à partir duquel la réponse à l'enquête a été créée.- hotjar_user_id chaîne - L'ID utilisateur Hotjar de l'utilisateur qui a soumis la réponse à l'enquête (un UUID).
created_str
chaîne - La date et l'heure à laquelle la réponse à l'enquête a été créée sous forme de chaîne ISO 8601.created_timestamp
entier - La date et l'heure à laquelle la réponse à l'enquête a été créée en tant que timestamp UNIX.is_complete
booléen - Indicateur indiquant si la réponse à l'enquête est complétée ou non.recording_url
chaîne - Le lien vers l'enregistrement Hotjar qui contient cette réponse à l'enquête, s'il existe.response_origin_url
chaîne - L'URL du site où l'utilisateur a soumis la réponse à l'enquête.window_width
entier - La largeur de la fenêtre de l'utilisateur lors de la soumission de la réponse à l'enquête.window_height
entier - La hauteur de la fenêtre de l'utilisateur lors de la soumission de la réponse à l'enquête.user_attributes
objet - Les attributs de l'utilisateur tels que fournis par l'API Identify de Hotjar. Chaque clé et valeur dans l'objet représentent ce qui suit :clé
chaîne de caractères - Le nom de l'attribut de l'utilisateur.valeur
chaîne de caractères/entier/décimal/booléen/date et heure - La valeur de l'attribut de l'utilisateur.questions
array/liste - Les questions et réponses de l'enquête. Chaque élément a les champs suivants :question_id
entier - L'identifiant unique de la question.question_text
chaîne de caractères - Le texte de la question.question_type
chaîne de caractères - Le type de question. Il s'agira de l'un des suivants :réaction
,texte-long
,texte-court
,option-simple
,option-multiple
,e-mail
,évaluation 1-5
,évaluation 1-7
,nps
ouinconnu
.réponses
array/liste - Les réponses à la question. Chaque réponse a les champs suivants :réponse
chaîne de caractères - La réponse donnée par l'utilisateur.commentaire
chaîne de caractères - Le commentaire laissé par l'utilisateur (le cas échéant).
Veuillez noter que les questions auxquelles l'utilisateur n'a pas répondu ne sont pas incluses dans la charge utile.
exemple
chaîne - Toujours défini sur la chaîne "données".
Exemples de charges utiles
Réponse à l'enquête
{ "event": "survey_response", "data": { "id": 42, "index": 1, "api_id": "response_f8ccb724-8110-48d0-8715-2138be7a9c06", "response_url": "https://insights.hotjar.com/link/goes/here", "site_id": 42, "survey_id": 42, "survey_name": "Enquête de test", "survey_url": "https://insights.hotjar.com/link/goes/here", "device": "Ordinateur", "browser": "Chrome", "os": "Windows", "country_code": "MT", "country_name": "Malte", "hotjar_user_id": "90fc1180-90b4-463c-9d1f-3415477f0168", "created_str": "2023-06-07T11:13:05.193076Z", "created_timestamp": 1686136385, "is_complete": false, "recording_url": "https://insights.hotjar.com/r?site=14&recording=12345", "response_origin_url": "https://www.example.com", "window_width": 1280, "window_height": 1024, "user_attributes": { "test_ua_one": "valeur", "test_ua_two": true }, "questions": [ { "question_id": 1, "questiom_text": "Question 1", "question_type": "texte-court", "answers": [ { "answer": "Réponse à la question 1 va ici", "comment": null } ] }, { "question_id": 2, "questiom_text": "Question 2", "question_type": "texte-long", "answers": [ { "answer": "Réponse à la question 2 va ici\n\n nouvelle ligne", "comment": null } ] }, { "question_id": 3, "questiom_text": "Question 3", "question_type": "e-mail", "answers": [ { "answer": "support@hotjar.com", "comment": null } ] }, { "question_id": 4, "questiom_text": "Question 4", "question_type": "option-simple", "answers": [ { "answer": "bouton radio?", "comment": "commentaire" } ] }, { "question_id": 5, "questiom_text": "Question 5", "question_type": "option-multiple", "answers": [ { "answer": "ceci", "comment": "commentaire" }, { "answer": "cela", "comment": "commentaire" } ] }, { "question_id": 6, "questiom_text": "Question 6", "question_type": "évaluation-1-5", "answers": [ { "answer": "3", "comment": null } ] }, { "question_id": 7, "questiom_text": "Question 7", "question_type": "évaluation-1-7", "answers": [ { "answer": "3", "comment": null } ] }, { "question_id": 8, "questiom_text": "Question 8", "question_type": "nps", "answers": [ { "answer": "3", "comment": null } ] }, { "question_id": 9, "questiom_text": "Question 9", "question_type": "réaction", "answers": [ { "answer": "3", "comment": null } ] }, { "question_id": 10, "questiom_text": "Question 10", "question_type": "texte-court", "answers": [ { "answer": "", "comment": null } ] } ] }, "version": 1,
"timestamp": 473385600 }