Tuesday, October 20, 2026
Отправляйте новости в Slack или Discord через webhooks finlight
Отправляйте новости в Slack или Discord через webhooks finlight
Самый быстрый способ донести новости до команды — отправить их в тот чат, который она и так уже наблюдает. С webhooks finlight вам не нужно опрашивать API: finlight вызывает ваш эндпоинт в тот момент, когда статья совпадает с вашими фильтрами. В этом руководстве мы настроим небольшой Python-эндпоинт, который проверяет webhook и пересылает его в Slack или Discord.
Как работают webhooks finlight
Вы создаёте webhook в панели управления, задаёте его фильтры (тикеры, категории и так далее) и передаёте finlight URL вашего эндпоинта. Когда статья совпадает, finlight делает POST-запрос со статьёй на ваш эндпоинт и подписывает запрос, чтобы вы могли убедиться, что он действительно пришёл от finlight. Каждый запрос несёт два заголовка:
X-Webhook-Signature— подпись HMAC-SHA256 от тела запроса.X-Webhook-Timestamp— используется для отклонения повторов (окно допуска 5 минут).
Официальный SDK проверяет оба за вас.
Эндпоинт
import os
import requests
from flask import Flask, request
from finlight_client import WebhookService, WebhookVerificationError
app = Flask(__name__)
WEBHOOK_SECRET = os.environ["FINLIGHT_WEBHOOK_SECRET"]
CHAT_WEBHOOK_URL = os.environ["CHAT_WEBHOOK_URL"]
@app.route("/finlight-webhook", methods=["POST"])
def finlight_webhook():
raw_body = request.get_data(as_text=True)
signature = request.headers.get("X-Webhook-Signature")
timestamp = request.headers.get("X-Webhook-Timestamp")
try:
article = WebhookService.construct_event(
raw_body, signature, WEBHOOK_SECRET, timestamp
)
except WebhookVerificationError:
return "", 400
text = (
f"*{article.title}*\n"
f"{article.sentiment} · {article.source}\n"
f"{article.link}"
)
# Slack incoming webhook ожидает {"text": ...}
requests.post(CHAT_WEBHOOK_URL, json={"text": text})
return "", 200
WebhookService.construct_event(...) проверяет подпись, валидирует временную метку и возвращает
разобранный Article. Если что-то не проходит проверку, он выбрасывает WebhookVerificationError, и
вы возвращаете 400.
Отправка в Discord
Incoming webhook в Discord использует поле content, а не text. Замените вызов post:
requests.post(CHAT_WEBHOOK_URL, json={"content": text})
Всё остальное остаётся без изменений.
Всегда проверяйте
Проверка важна: без неё любой, кто узнает ваш URL, сможет отправлять поддельные статьи в ваш канал.
Всегда передавайте в construct_event сырое, неразобранное тело запроса (не сериализуйте его заново),
храните секрет эндпоинта в переменной окружения и возвращайте ответ быстро, чтобы finlight не ждал.
Обогащённые и сырые webhooks
finlight предлагает обогащённые webhooks (с тональностью и сущностями) и сырые webhooks (лёгкие, более быстрые). Используйте обогащённые, когда оповещение должно показывать тональность или задействованные компании, и сырые — когда вам просто нужен заголовок как можно быстрее.
Что дальше
- REST, WebSocket, Webhooks и MCP, чтобы понять, когда webhooks выигрывают у стриминга.
- Полная документация по настройке webhooks, форматам данных и тестированию.
