Tuesday, October 20, 2026

Отправляйте новости в Slack или Discord через webhooks finlight

Kevin Bartsch

Отправляйте новости в 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 (лёгкие, более быстрые). Используйте обогащённые, когда оповещение должно показывать тональность или задействованные компании, и сырые — когда вам просто нужен заголовок как можно быстрее.

Что дальше

Получите бесплатный API-ключ →