Уведомления
Email-сводки и вебхуки для обсуждений, требующих внимания, включая проверку подписи.
Hearl может сообщить вашей команде, как только обсуждению потребуется внимание. Настройка находится на странице Уведомления. Менять эти настройки могут только владельцы и администраторы.
Когда отправляются уведомления
Hearl проверяет каждые 15 минут. Обсуждение включается в уведомление, если:
- его статус платформы Без ответа или Пользователь написал снова
- его ход работы всё ещё Не начато
- ИИ Hearl признал, что оно относится к вашему продукту, и неуверенных ответов нет
- его приоритет не ниже заданного вами минимума: все, Средний и выше или только Высокий
Каждое обсуждение уведомляется один раз для каждого статуса. Если оно было отправлено как Без ответа, а потом пользователь написал снова, оно будет отправлено ещё раз как Пользователь написал снова.
Включите Отправлять письма и добавьте получателей. Оставьте список пустым, чтобы письма получали все участники рабочего пространства. Подойдёт любой адрес, например общий ящик поддержки, до 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, чтобы подтвердить получение.