Перейти к содержимому
Hearl
Esc
↑↓навигация↵открыть⌘Jпредпросмотр
На этой странице

Уведомления

Email-сводки и вебхуки для обсуждений, требующих внимания, включая проверку подписи.

Hearl может сообщить вашей команде, как только обсуждению потребуется внимание. Настройка находится на странице Уведомления. Менять эти настройки могут только владельцы и администраторы.

Когда отправляются уведомления

Hearl проверяет каждые 15 минут. Обсуждение включается в уведомление, если:

  • его статус платформы Без ответа или Пользователь написал снова
  • его ход работы всё ещё Не начато
  • ИИ Hearl признал, что оно относится к вашему продукту, и неуверенных ответов нет
  • его приоритет не ниже заданного вами минимума: все, Средний и выше или только Высокий

Каждое обсуждение уведомляется один раз для каждого статуса. Если оно было отправлено как Без ответа, а потом пользователь написал снова, оно будет отправлено ещё раз как Пользователь написал снова.

Email

Включите Отправлять письма и добавьте получателей. Оставьте список пустым, чтобы письма получали все участники рабочего пространства. Подойдёт любой адрес, например общий ящик поддержки, до 20 получателей.

Каждая проверка отправляет одну сводку, в которой перечислено до 10 обсуждений, со ссылкой на остальные во входящих. Выберите английский или китайский в поле Язык.

Webhook

Укажите Endpoint. Это должен быть публичный URL с https. Hearl распознаёт популярных чат-ботов по адресу и отправляет сообщение в нужном им формате:

Адрес Формат отправки
hooks.slack.com Сообщение Slack
feishu.cn, larksuite.com Текстовое сообщение Feishu
qyapi.weixin.qq.com Сообщение WeCom в Markdown
oapi.dingtalk.com Сообщение DingTalk в Markdown
discord.com, discordapp.com Сообщение Discord
Любой другой URL Обычный 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 其他 Другое

Проверьте подпись

Когда вы сохраняете endpoint вебхука, Hearl создаёт для него Секрет подписи. Его можно показать или обновить на странице Уведомления. Запрос содержит заголовок:

X-Hearloop-Signature: sha256=<hex>

<hex> это HMAC-SHA256 от необработанного тела запроса с ключом в виде вашего секрета подписи, в нижнем регистре в hex. Вычисляйте его по точным байтам, которые вы получили, до разбора 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, чтобы подтвердить получение.

Эта страница была полезной?