---
title: Notifications
description: Résumés par e-mail et webhooks pour les conversations qui demandent de l'attention, avec vérification de la signature.
---

Hearl peut prévenir votre équipe dès qu'une conversation demande de l'attention. Configurez-le sur la page **Notifications**. Seuls les propriétaires et les administrateurs peuvent modifier ces paramètres.

## Quand les notifications sont envoyées [#when]

Hearl vérifie toutes les 15 minutes. Une conversation est incluse quand :

- son statut de plateforme est **Sans réponse** ou **L'utilisateur a relancé**
- son avancement est encore **Non commencé**
- l'IA l'a jugée concernée par votre produit, sans réponse incertaine
- sa priorité est égale ou supérieure au minimum que vous avez défini : tout, Moyenne et plus, ou Élevée uniquement

Chaque conversation est notifiée une seule fois par statut. Si elle a été notifiée comme **Sans réponse** et que l'utilisateur relance ensuite, elle est notifiée de nouveau comme **L'utilisateur a relancé**.

## E-mail [#email]

Activez **Envoyer un e-mail** et ajoutez des destinataires. Laissez la liste vide pour écrire à tous les membres de l'espace de travail. Toute adresse convient, par exemple une boîte de support partagée, jusqu'à 20 destinataires.

Chaque vérification envoie un seul résumé qui liste jusqu'à 10 conversations, avec un lien vers les autres dans la boîte de réception. Choisissez l'anglais ou le chinois sous **Langue**.

## Webhook [#webhook]

Saisissez un **Point de terminaison**. Il doit s'agir d'une URL `https` publique. Hearl reconnaît les bots de messagerie courants à leur adresse et envoie le format de message qu'ils attendent :

| Adresse | Envoyé comme |
| --- | --- |
| `hooks.slack.com` | Message Slack |
| `feishu.cn`, `larksuite.com` | Message texte Feishu |
| `qyapi.weixin.qq.com` | Message Markdown WeCom |
| `oapi.dingtalk.com` | Message Markdown DingTalk |
| `discord.com`, `discordapp.com` | Message Discord |
| Toute autre URL | JSON générique (ci-dessous) |

La page indique le type détecté. **Envoyer un test** envoie un exemple, et la page affiche le résultat du dernier envoi. Une requête qui dépasse 8 secondes est considérée comme expirée.

### JSON générique [#json]

```json
{
  "event": "conversations.needs_attention",
  "workspace": { "id": "org_123", "name": "Acme" },
  "text": "*2 conversations need attention* · Acme\n• [reddit] Sync stopped working after 2.3 — No reply yet <https://…>",
  "conversations": [
    {
      "id": "c_8f2a",
      "platform": "reddit",
      "product": "Acme",
      "title": "Sync stopped working after 2.3",
      "author": "some_user",
      "url": "https://www.reddit.com/r/…",
      "status": "待回复",
      "priority": "高",
      "category": "故障",
      "inbox_url": "https://hearl.org/app?c=c_8f2a"
    }
  ],
  "sent_at": "2026-11-08T09:15:00.000Z"
}
```

| Champ | Description |
| --- | --- |
| `event` | `conversations.needs_attention`, ou `test` pour **Envoyer un test**. |
| `workspace` | Le `id` et le `name` de l'espace de travail. |
| `text` | Un résumé prêt à publier. Slack ne lit que ce champ. |
| `conversations` | Toutes les conversations de cet envoi. |
| `sent_at` | Le moment où l'envoi a eu lieu, au format ISO 8601. |

`platform` vaut `x`, `reddit` ou `hn`. `status`, `priority` et `category` sont des codes stables en chinois, pour que votre code puisse les comparer quelle que soit la langue de votre espace de travail :

| Champ | Code | Signification |
| --- | --- | --- |
| `status` | `待回复` | Sans réponse |
| `status` | `用户有新回复` | L'utilisateur a relancé |
| `priority` | `高` / `中` / `低` | Élevée / Moyenne / Faible |
| `category` | `故障` | Bug |
| `category` | `求助` | Question |
| `category` | `功能建议` | Demande de fonctionnalité |
| `category` | `价格` | Tarifs |
| `category` | `负面反馈` | Critique |
| `category` | `正面反馈` | Éloge |
| `category` | `购买咨询` | Achat |
| `category` | `其他` | Autre |

### Vérifier la signature [#signature]

Quand vous enregistrez un point de terminaison webhook, Hearl crée pour lui un **Secret de signature**. Vous pouvez l'afficher ou le renouveler sur la page Notifications. La requête contient cet en-tête :

```txt
X-Hearloop-Signature: sha256=<hex>
```

`<hex>` est le HMAC-SHA256 du corps brut de la requête, calculé avec votre secret de signature, en hexadécimal minuscule. Calculez-le sur les octets exacts reçus, avant d'analyser le JSON, et comparez en temps constant.

```js Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
import express from "express";

const app = express();
const secret = process.env.HEARL_WEBHOOK_SECRET;

app.post("/hearl", express.raw({ type: "application/json" }), (req, res) => {
  const expected = "sha256=" + createHmac("sha256", secret).update(req.body).digest("hex");
  const received = req.get("x-hearloop-signature") ?? "";
  const ok =
    received.length === expected.length &&
    timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  if (!ok) return res.status(401).end();

  const payload = JSON.parse(req.body.toString("utf8"));
  console.log(payload.event, payload.conversations.length);
  res.status(200).end();
});

app.listen(3000);
```

```python Python
import hashlib
import hmac
import json
import os

from flask import Flask, abort, request

app = Flask(__name__)
SECRET = os.environ["HEARL_WEBHOOK_SECRET"].encode()


@app.post("/hearl")
def hearl():
    body = request.get_data()
    expected = "sha256=" + hmac.new(SECRET, body, hashlib.sha256).hexdigest()
    received = request.headers.get("X-Hearloop-Signature", "")
    if not hmac.compare_digest(received, expected):
        abort(401)

    payload = json.loads(body)
    print(payload["event"], len(payload["conversations"]))
    return "", 200
```

Renvoyez n'importe quel statut `2xx` pour accuser réception de l'envoi.
