finlight Logo

Tuesday, October 20, 2026

Envía noticias a Slack o Discord con webhooks de finlight

Kevin Bartsch

Envía noticias a Slack o Discord con webhooks de finlight

La forma más rápida de poner las noticias frente a tu equipo es enviarlas al chat que ya están mirando. Con los webhooks de finlight no haces polling: finlight llama a tu endpoint en el momento en que un artículo coincide con tus filtros. Este tutorial monta un pequeño endpoint en Python que verifica el webhook y lo reenvía a Slack o Discord.

Cómo funcionan los webhooks de finlight

Creas un webhook en el panel de control, defines sus filtros (tickers, categorías, etc.) y le das a finlight la URL de tu endpoint. Cuando un artículo coincide, finlight envía ese artículo con un POST a tu endpoint y firma la petición, para que puedas confirmar que realmente vino de finlight. Cada petición lleva dos cabeceras:

  • X-Webhook-Signature — una firma HMAC-SHA256 del cuerpo.
  • X-Webhook-Timestamp — se usa para rechazar repeticiones (una ventana de tolerancia de 5 minutos).

El SDK oficial verifica ambas por ti.

El endpoint

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}"
    )

    # El incoming webhook de Slack espera {"text": ...}
    requests.post(CHAT_WEBHOOK_URL, json={"text": text})
    return "", 200

WebhookService.construct_event(...) comprueba la firma, valida el timestamp y devuelve un Article ya parseado. Si algo falla, lanza WebhookVerificationError y tú devuelves un 400.

Enviar a Discord en su lugar

Los incoming webhooks de Discord usan un campo content en vez de text. Cambia el post:

requests.post(CHAT_WEBHOOK_URL, json={"content": text})

Todo lo demás se queda igual.

Verifica siempre

La verificación importa: sin ella, cualquiera que encuentre tu URL podría publicar artículos falsos en tu canal. Pasa siempre el cuerpo crudo, sin parsear, a construct_event (no lo vuelvas a serializar antes), guarda el secreto del endpoint en una variable de entorno y responde rápido para no dejar a finlight esperando.

Enriquecido frente a crudo

finlight ofrece webhooks enriquecidos (con sentimiento y entidades) y webhooks crudos (ligeros, más rápidos). Usa el enriquecido cuando tu alerta deba mostrar el sentimiento o las empresas implicadas, y el crudo cuando solo necesites el titular lo antes posible.

A dónde ir después

Consigue tu clave de API gratis →