Tuesday, October 20, 2026
Envía noticias a Slack o Discord con webhooks de finlight
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
- REST vs WebSocket vs Webhooks vs MCP para ver cuándo los webhooks superan al streaming.
- Documentación completa sobre la configuración, los payloads y las pruebas de webhooks.
