Saltar al contenido
Hearl
Esc
↑↓navegar↵abrir⌘Jvista previa
En esta página

Notificaciones

Resúmenes por correo y webhooks para las conversaciones que necesitan atención, con verificación de firma.

Hearl puede avisar a tu equipo en cuanto una conversación necesita atención. Configúralo en la página Notificaciones. Solo los propietarios y administradores pueden cambiar esta configuración.

Cuándo se envían las notificaciones

Hearl comprueba cada 15 minutos. Una conversación se incluye cuando:

  • su estado de plataforma es Sin respuesta o El usuario respondió de nuevo
  • su progreso sigue en Sin empezar
  • la IA la juzgó como relacionada con tu producto, sin respuestas inciertas
  • su prioridad es igual o superior al mínimo que definiste: todas, Media o superior, o solo Alta

Cada conversación se notifica una vez por estado. Si se notificó como Sin respuesta y después el usuario vuelve a escribir, se notifica de nuevo como El usuario respondió de nuevo.

Correo

Activa Enviar correo y añade destinatarios. Deja la lista vacía para enviar el correo a todos los miembros del espacio de trabajo. Sirve cualquier dirección, como una bandeja de soporte compartida, hasta 20 destinatarios.

Cada comprobación envía un solo resumen con hasta 10 conversaciones, con un enlace al resto en la bandeja de entrada. Elige inglés o chino en Idioma.

Webhook

Escribe un Endpoint. Debe ser una URL https pública. Hearl reconoce los bots de chat más comunes por su dirección y envía el formato de mensaje que esperan:

Dirección Se envía como
hooks.slack.com Mensaje de Slack
feishu.cn, larksuite.com Mensaje de texto de Feishu
qyapi.weixin.qq.com Mensaje Markdown de WeCom
oapi.dingtalk.com Mensaje Markdown de DingTalk
discord.com, discordapp.com Mensaje de Discord
Cualquier otra URL JSON genérico (abajo)

La página muestra qué tipo detectó. Enviar prueba envía un ejemplo, y la página muestra el resultado del último envío. Una solicitud que tarda más de 8 segundos cuenta como tiempo de espera agotado.

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 Descripción
event conversations.needs_attention, o test para Enviar prueba.
workspace El id y el name del espacio de trabajo.
text Un resumen listo para publicar. Slack lee solo este campo.
conversations Todas las conversaciones de este envío.
sent_at Cuándo se envió, en ISO 8601.

platform es x, reddit o hn. status, priority y category son códigos estables en chino, para que tu código pueda compararlos sea cual sea el idioma de tu espacio de trabajo:

Campo Código Significado
status 待回复 Sin respuesta
status 用户有新回复 El usuario respondió de nuevo
priority 高 / 中 / 低 Alta / Media / Baja
category 故障 Error
category 求助 Pregunta
category 功能建议 Solicitud de función
category 价格 Precios
category 负面反馈 Crítica
category 正面反馈 Elogio
category 购买咨询 Compra
category 其他 Otro

Verificar la firma

Cuando guardas un endpoint de webhook, Hearl crea para él un Secreto de firma. Puedes mostrarlo o rotarlo en la página Notificaciones. La solicitud incluye este encabezado:

X-Hearloop-Signature: sha256=<hex>

<hex> es el HMAC-SHA256 del cuerpo sin procesar de la solicitud, con tu secreto de firma como clave, en hexadecimal en minúsculas. Calcúlalo sobre los bytes exactos que recibiste, antes de analizar el JSON, y compara en tiempo 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 "", 200

Devuelve cualquier estado 2xx para confirmar el envío.

¿Te ha resultado útil esta página?