跳到内容
Hearl
Esc
↑↓导航↵打开⌘J预览
本页内容

通知

针对需要关注的讨论的邮件汇总和 Webhook,包括签名验证。

Hearl 可以在讨论需要关注时第一时间通知你的团队。在 通知 页面里设置。只有所有者和管理员可以修改这些设置。

何时发送通知

Hearl 每 15 分钟检查一次。满足以下条件的讨论会被包含进来:

  • 平台状态为 还没人回复 或 用户有新回复
  • 进度仍为 未处理
  • 自动判断认为它与你的产品有关,且没有不确定的答案
  • 优先级不低于你设置的最低优先级:全部、中及以上,或只要高

每条讨论在每种状态下只通知一次。如果它以 还没人回复 通知过,之后用户又跟进了,就会再以 用户有新回复 通知一次。

邮件

打开 发送邮件 并添加收件人。列表留空则发给工作空间的所有成员。任何邮箱地址都可以,比如共用的客服邮箱,最多 20 个收件人。

每次检查会发送一封汇总邮件,最多列出 10 条讨论,其余的附有收件箱链接。在 通知语言 下选择英文或中文。

Webhook

填写 推送地址。它必须是公开的 https 网址。Hearl 会根据地址识别常见的聊天机器人,并发送它们需要的消息格式:

地址 发送格式
hooks.slack.com Slack 消息
feishu.cn, larksuite.com 飞书文本消息
qyapi.weixin.qq.com 企业微信 Markdown 消息
oapi.dingtalk.com 钉钉 Markdown 消息
discord.com, discordapp.com Discord 消息
其他任何网址 通用 JSON(见下)

页面会显示它识别出的类型。发送测试 会发送一条示例,页面还会显示最近一次推送的结果。请求超过 8 秒算作超时。

通用 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"
}
字段 说明
event conversations.needs_attention,测试时为 test(来自 发送测试)。
workspace 工作空间的 id 和 name。
text 可直接发布的摘要。Slack 只读取这个字段。
conversations 本次推送包含的每条讨论。
sent_at 推送发送的时间,ISO 8601 格式。

platform 的值是 x、reddit 或 hn。status、priority 和 category 是固定的中文代码,所以无论工作空间使用什么语言,你的代码都可以按它们匹配:

字段 代码 含义
status 待回复 还没人回复
status 用户有新回复 用户有新回复
priority 高 / 中 / 低 高 / 中 / 低
category 故障 故障
category 求助 求助
category 功能建议 功能建议
category 价格 价格
category 负面反馈 负面反馈
category 正面反馈 正面反馈
category 购买咨询 购买咨询
category 其他 其他

验证签名

保存 Webhook 推送地址时,Hearl 会为它创建一个 签名密钥。你可以在通知页面显示或更换它。请求会带上这个请求头:

X-Hearloop-Signature: sha256=<hex>

<hex> 是用你的签名密钥对原始请求体计算的 HMAC-SHA256,以小写十六进制表示。请对收到的原始字节计算,在解析 JSON 之前进行,并用常量时间比较。

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

返回任意 2xx 状态码即表示已确认收到推送。

这个页面有帮助吗?