Notificações
Resumos por e-mail e webhooks para conversas que precisam de atenção, incluindo a verificação de assinatura.
O Hearl pode avisar sua equipe assim que uma conversa precisar de atenção. Configure na página Notificações. Só proprietários e administradores podem alterar essas configurações.
Quando as notificações são enviadas
O Hearl verifica a cada 15 minutos. Uma conversa é incluída quando:
- o status da plataforma dela é Sem resposta ainda ou Usuário respondeu de novo
- o andamento dela ainda é Não iniciado
- a IA avaliou que é sobre o seu produto, sem respostas incertas
- a prioridade dela é igual ou superior ao mínimo que você definiu: tudo, Média ou superior, ou apenas Alta
Cada conversa é notificada uma vez por status. Se ela foi notificada como Sem resposta ainda e o usuário responde de novo mais tarde, ela é notificada outra vez como Usuário respondeu de novo.
Ative Enviar e-mail e adicione os destinatários. Deixe a lista vazia para enviar e-mail a todos os membros do workspace. Qualquer endereço serve, como uma caixa de suporte compartilhada, até 20 destinatários.
Cada verificação envia um resumo que lista até 10 conversas, com um link para o restante na caixa de entrada. Escolha inglês ou chinês em Idioma.
Webhook
Informe um Endpoint. Ele precisa ser uma URL https pública. O Hearl reconhece bots de chat comuns pelo endereço e envia o formato de mensagem que eles esperam:
| Endereço | Enviado como |
|---|---|
hooks.slack.com |
Mensagem do Slack |
feishu.cn, larksuite.com |
Mensagem de texto do Feishu |
qyapi.weixin.qq.com |
Mensagem Markdown do WeCom |
oapi.dingtalk.com |
Mensagem Markdown do DingTalk |
discord.com, discordapp.com |
Mensagem do Discord |
| Qualquer outra URL | JSON genérico (abaixo) |
A página mostra qual tipo foi detectado. Enviar um teste envia um exemplo, e a página mostra o resultado do último envio. Uma requisição que demora mais de 8 segundos conta como timeout.
JSON genérico
{
"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"
}
| Campo | Descrição |
|---|---|
event |
conversations.needs_attention, ou test para Enviar um teste. |
workspace |
O id e o name do workspace. |
text |
Um resumo pronto para publicar. O Slack lê apenas este campo. |
conversations |
Todas as conversas deste envio. |
sent_at |
Quando o envio foi feito, em ISO 8601. |
platform é x, reddit ou hn. status, priority e category são códigos estáveis em chinês, para que o seu código possa compará-los qualquer que seja o idioma do seu workspace:
| Campo | Código | Significado |
|---|---|---|
status |
待回复 |
Sem resposta ainda |
status |
用户有新回复 |
Usuário respondeu de novo |
priority |
高 / 中 / 低 |
Alta / Média / Baixa |
category |
故障 |
Bug |
category |
求助 |
Dúvida |
category |
功能建议 |
Sugestão de recurso |
category |
价格 |
Preço |
category |
负面反馈 |
Crítica |
category |
正面反馈 |
Elogio |
category |
购买咨询 |
Compra |
category |
其他 |
Outro |
Verifique a assinatura
Quando você salva um endpoint de webhook, o Hearl cria um Segredo de assinatura para ele. Você pode mostrá-lo ou trocá-lo na página Notificações. A requisição traz este cabeçalho:
X-Hearloop-Signature: sha256=<hex>
<hex> é o HMAC-SHA256 do corpo bruto da requisição, com a chave sendo o seu segredo de assinatura, em hexadecimal minúsculo. Calcule sobre os bytes exatos que você recebeu, antes de interpretar o JSON, e compare em tempo constante.
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);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 "", 200Retorne qualquer status 2xx para confirmar o recebimento.