finlight Logo

Tuesday, October 20, 2026

finlight Webhooks로 Slack이나 Discord에 뉴스 푸시하기

Kevin Bartsch

finlight Webhooks로 Slack이나 Discord에 뉴스 푸시하기

뉴스를 팀에게 가장 빠르게 보여주는 방법은, 팀이 이미 지켜보고 있는 채팅에 뉴스를 밀어 넣는 것입니다. finlight webhooks를 사용하면 폴링할 필요가 없습니다. 기사가 여러분의 필터에 매칭되는 순간 finlight가 여러분의 엔드포인트를 호출합니다. 이 튜토리얼에서는 webhook을 검증하고 이를 Slack이나 Discord로 전달하는 작은 Python 엔드포인트를 구축합니다.

finlight webhooks의 동작 방식

여러분은 대시보드에서 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 expects {"text": ...}
    requests.post(CHAT_WEBHOOK_URL, json={"text": text})
    return "", 200

WebhookService.construct_event(...)는 서명을 확인하고 타임스탬프를 검증한 뒤, 파싱된 Article을 반환합니다. 어느 단계든 실패하면 WebhookVerificationError를 발생시키며, 이때 여러분은 400을 반환하면 됩니다.

Discord로 대신 보내기

Discord의 incoming webhook은 text가 아니라 content 필드를 사용합니다. post 한 줄만 바꾸면 됩니다.

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

나머지는 그대로입니다.

반드시 검증하세요

검증은 중요합니다. 검증이 없으면 여러분의 URL을 발견한 누구라도 채널에 가짜 기사를 올릴 수 있습니다. 항상 가공되지 않은 원본 본문을 construct_event에 전달하고(먼저 다시 직렬화하지 마세요), 엔드포인트 시크릿은 환경 변수에 보관하며, finlight를 기다리게 하지 않도록 빠르게 응답을 반환하세요.

증강 버전 vs 원본 버전

finlight는 증강 webhook(감성과 엔터티 포함)과 원본 webhook(가볍고 더 빠름)을 제공합니다. 알림에 감성이나 관련 기업을 표시해야 한다면 증강 버전을, 헤드라인만 최대한 빨리 받으면 된다면 원본 버전을 사용하세요.

다음으로 볼 것

무료 API 키 받기 →