finlight Logo

Tuesday, October 20, 2026

Envie notícias para o Slack ou Discord com webhooks finlight

Kevin Bartsch

Envie notícias para o Slack ou Discord com webhooks finlight

A forma mais rápida de colocar notícias diante da sua equipe é enviá-las para o chat que ela já acompanha. Com os webhooks da finlight, você não faz polling: a finlight chama o seu endpoint no instante em que um artigo corresponde aos seus filtros. Este tutorial monta um pequeno endpoint Python que verifica o webhook e o encaminha para o Slack ou Discord.

Como funcionam os webhooks da finlight

Você cria um webhook no dashboard, define seus filtros (tickers, categorias e assim por diante) e informa à finlight a URL do seu endpoint. Quando um artigo corresponde, a finlight faz POST do artigo para o seu endpoint e assina a requisição, para que você possa confirmar que ela realmente veio da finlight. Cada requisição traz dois cabeçalhos:

  • X-Webhook-Signature — uma assinatura HMAC-SHA256 do corpo.
  • X-Webhook-Timestamp — usado para rejeitar replays (uma janela de tolerância de 5 minutos).

O SDK oficial verifica os dois para você.

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

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

WebhookService.construct_event(...) verifica a assinatura, valida o timestamp e retorna um Article já parseado. Se algo falhar, ele lança WebhookVerificationError, e você retorna um 400.

Enviando para o Discord no lugar

Os incoming webhooks do Discord usam um campo content em vez de text. Troque o post:

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

Todo o resto permanece igual.

Sempre verifique

A verificação é importante: sem ela, qualquer pessoa que descobrir sua URL poderia postar artigos falsos no seu canal. Sempre passe o corpo bruto, não parseado, para construct_event (não o re-serialize antes), mantenha o segredo do endpoint em uma variável de ambiente e responda rápido para que a finlight não fique esperando.

Enriquecido vs. bruto

A finlight oferece webhooks enriquecidos (com sentimento e entidades) e webhooks brutos (leves, mais rápidos). Use o enriquecido quando seu alerta precisar mostrar sentimento ou as empresas envolvidas, e o bruto quando você só precisar da manchete o mais rápido possível.

Para onde ir agora

Obtenha sua API key gratuita →