Home>Blog>Build a Hyperliquid Webhook Alert System in 30 Minutes
Build a Hyperliquid Webhook Alert System in 30 Minutes

Build a Hyperliquid Webhook Alert System in 30 Minutes

By @CoinMarketMan - 10-Jul-2026

30분 만에 Hyperliquid 웹훅 알림 시스템 구축하기

폴링 루프가 5분마다 실행되면서 동일한 코호트 데이터를 가져오고, 이전 스냅샷과 비교한 뒤 아무것도 바뀌지 않았다고 판단합니다. 그 사이 Money Printer 코호트는 ETH에서 순 숏으로 전환했고, $3,800 수준에서 청산 클러스터가 형성됐으며, 세 개의 Leviathan이 SOL에서 신규 롱을 열었습니다. 다음 폴링이 도착할 때쯤 이미 움직임은 가격에 반영된 후입니다.

폴링이 기본값인 이유는 가장 단순한 패턴이기 때문입니다. 인터벌을 설정하고, 엔드포인트를 호출하고, 응답을 비교하면 끝입니다. 하지만 단순함에는 대가가 따릅니다. 지연, 변화가 없는 데이터에 낭비되는 API 호출, 그리고 마지막 두 요청 사이에 중요한 일이 벌어진 게 아닐까 하는 불안감입니다. 웹훅은 이 구조를 뒤집습니다. 몇 분마다 "뭔가 바뀌었나?"라고 묻는 대신, 서버가 변화가 생기는 즉시 알려줍니다.

HyperTracker의 웹훅 전송은 Flow ($799/월) 및 Stream ($1,999/월) 티어에서 이용할 수 있습니다. URL을 등록하고 관심 있는 이벤트를 설정하면, 데이터 갱신 주기에서 이벤트가 감지되는 즉시 우리 인프라가 서명된 JSON 페이로드를 엔드포인트로 푸시합니다. 크론 작업도, 레이트 리밋 계산도, 오래된 데이터 윈도우도 없습니다. 이 가이드는 웹훅 수신, 페이로드 검증, Telegram 또는 Discord로의 알림 라우팅, 그리고 장애 처리까지 전체 설정을 다룹니다.

Polling Vs Webhook Architecture

폴링 대 푸시: 실제로 무엇을 잃고 있는가

폴링의 비용은 단순히 지연만이 아닙니다. 일반적인 통합의 수치를 살펴보겠습니다. 코호트 메트릭 엔드포인트를 5분마다 폴링하면, 단일 자산의 단일 엔드포인트 기준으로 하루 288회, 한 달 약 8,640회의 요청이 발생합니다. 자산을 다섯 개로 늘리면 43,200회입니다. 오더 플로우 스냅샷과 청산 리스크까지 더하면, 모니터링만으로 Pulse 티어의 월 50,000회 요청을 소진할 수 있으며, 온디맨드 쿼리를 위한 여유분이 전혀 남지 않습니다.

웹훅은 이를 완전히 해결합니다. 관심 있는 이벤트만 등록하면, 실제로 변화가 생겼을 때만 요청이 발생합니다. 조용한 시장은 아무 비용도 들지 않습니다. 변동성이 큰 날에는 페이로드가 집중적으로 전송되지만, 처리하고 버려야 하는 "변화 없음" 응답이 아닌 실행 가능한 정보가 담겨 있습니다.

지연 차이도 중요합니다. 5분 폴링에서 최악의 감지 지연은 5분 미만이며, 아무 변화가 없어도 요청 오버헤드를 계속 부담합니다. 웹훅은 시스템이 갱신 주기에서 이벤트를 감지하는 즉시 페이로드를 수신하며, 그 사이에 낭비되는 호출이 없습니다. 코호트 변화와 청산 급등의 경우, 폴링 오버헤드를 없애고 즉각적인 푸시 전송을 받는다는 것은 더 깔끔한 아키텍처와 빠른 대응 루프를 의미합니다.

웹훅 엔드포인트 설정

수신자는 POST 요청을 받아 페이로드를 검증하고 즉시 200 상태 코드를 반환하는 HTTP 서버입니다. 재시도 로직이 트리거되지 않도록 엔드포인트는 몇 초 이내에 응답해야 합니다. 전송이 실패하면 지수 백오프로 재시도됩니다. 지속적인 실패가 발생하면 대시보드에서 다시 활성화할 때까지 웹훅이 일시 중지됩니다.

다음은 Express를 사용한 최소한의 Node.js 수신자입니다:

import express from 'express';
import crypto from 'crypto';

const app = express();
app.use(express.json());

const WEBHOOK_SECRET = process.env.HT_WEBHOOK_SECRET;

function verifySignature(payload, signature) {
  const expected = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(JSON.stringify(payload))
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

app.post('/webhooks/hypertracker', (req, res) => {
  const signature = req.headers['x-ht-signature'];

  if (!signature || !verifySignature(req.body, signature)) {
    console.error('Invalid webhook signature');
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Acknowledge immediately, process async
  res.status(200).json({ received: true });

  // Handle the event
  processEvent(req.body);
});

app.listen(3000, () => console.log('Webhook receiver on :3000'));

세 가지를 유의하세요. 첫째, 서명 검증은 선택 사항이 아닙니다. 없으면 엔드포인트 URL을 발견한 누구든 가짜 페이로드를 보낼 수 있습니다. HMAC-SHA256 검사는 페이로드가 HyperTracker에서 발송됐음을 확인합니다. 둘째, 처리 전에 먼저 응답하세요. 200을 즉시 보내고 비즈니스 로직은 비동기로 처리하세요. 알림 라우팅이 느린 다운스트림 서비스(Telegram API 지연, 데이터베이스 쓰기)에 걸리더라도 웹훅 전송이 타임아웃되어 재시도를 트리거하지 않도록 해야 합니다. 셋째, 서명 비교에는 timingSafeEqual을 사용해 타이밍 공격을 방지하세요.

로컬 서버 외부 노출

개발 중에는 로컬호스트가 인터넷에서 접근할 수 없습니다. 터널을 사용해 외부에 노출하세요:

# Option 1: ngrok
ngrok http 3000

# Option 2: Cloudflare Tunnel
cloudflared tunnel --url http://localhost:3000

생성된 HTTPS URL을 복사해 HyperTracker 웹훅 설정에 붙여 넣으세요. 프로덕션에서는 안정적인 HTTPS 엔드포인트를 제공하는 클라우드 공급자에 배포하세요. 월 $5짜리 VPS로도 웹훅 수신자로 충분합니다.

Webhook Event Flow

구독할 이벤트 선택

모든 이벤트가 알림을 받을 가치가 있는 것은 아닙니다. 알림 채널을 망치는 가장 빠른 방법은 노이즈로 가득 채워 모든 것을 무시하게 만드는 것입니다. 시그널이 높은 이벤트 집합부터 시작하고, 볼륨에 익숙해진 후 확장하세요.

Hyperliquid를 모니터링하는 트레이더를 위한 실용적인 초기 설정:

| 이벤트 유형 | 발동 조건 | 중요한 이유 | | --- | --- | --- | | cohort.shift | PnL 코호트가 특정 자산에서 순 롱/숏으로 전환 | Money Printer 또는 Smart Money의 반전은 높은 확신도의 시그널 | | liquidation.cluster | 청산 리스크 점수가 임계값 초과 | 클러스터 구간은 가격을 끌어당기며, 특히 변동성이 큰 세션에서 그렇습니다 | | position.large | 명목 임계값 이상의 포지션이 열리거나 닫힘 | Whale의 진입과 청산은 Hyperliquid 시장을 움직입니다 | | order_flow.spike | 5분 윈도우의 오더 플로우 볼륨이 Z-점수 임계값을 초과 | 갑작스러운 플로우 급등은 종종 방향성 움직임에 선행합니다 |

이 항목들은 HyperTracker 대시보드의 설정 > 웹훅 또는 웹훅 관리 엔드포인트를 통해 프로그래밍 방식으로 설정할 수 있습니다. 각 이벤트 유형은 선택적 필터를 허용합니다: 자산 심볼, 코호트 ID, 최소 명목 규모, 임계값. 수신자에서 필터링하는 것보다 소스에서 필터링하는 것이 항상 낫습니다. 페이로드 볼륨을 줄이고 처리 로직을 깔끔하게 유지하기 때문입니다.

Telegram으로 알림 라우팅

Telegram은 빠르고, 풍부한 서식을 지원하며, 모든 기기에서 실행되기 때문에 크립토 트레이더들의 기본 알림 채널입니다. 라우팅 함수는 검증된 웹훅 페이로드를 받아 Telegram 채팅 또는 그룹에 서식이 지정된 메시지를 전송합니다.

async function sendTelegramAlert(event) {
  const TELEGRAM_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
  const CHAT_ID = process.env.TELEGRAM_CHAT_ID;

  const message = formatMessage(event);

  await fetch(
    `https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage`,
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        chat_id: CHAT_ID,
        text: message,
        parse_mode: 'HTML',
      }),
    }
  );
}

function formatMessage(event) {
  switch (event.type) {
    case 'cohort.shift':
      return [
        `<b>Cohort Shift: ${event.data.asset}</b>`,
        `${event.data.cohort_name} flipped <b>${event.data.direction}</b>`,
        `Net position: ${event.data.net_position.toFixed(2)}`,
        `Time: ${new Date(event.timestamp).toUTCString()}`,
      ].join('\n');

    case 'liquidation.cluster':
      return [
        `<b>Liquidation Cluster: ${event.data.asset}</b>`,
        `Risk score: ${event.data.risk_score}/100`,
        `Price zone: $${event.data.price_low} - $${event.data.price_high}`,
        `Estimated exposure: $${(event.data.notional / 1e6).toFixed(1)}M`,
      ].join('\n');

    default:
      return `<b>${event.type}</b>\n${JSON.stringify(event.data, null, 2)}`;
  }
}

Telegram 봇을 만들려면 Telegram에서 @BotFather에게 메시지를 보내고 /newbot을 실행한 뒤 토큰을 저장하세요. 봇을 알림 채널 또는 그룹에 추가하고, getUpdates 엔드포인트에서 채팅 ID를 가져오세요. 전체 과정은 약 2분이면 됩니다.

Discord 대안

팀이 Discord를 사용한다면 웹훅 전송이 더욱 간단합니다. Discord 채널에는 내장 웹훅 URL이 있어 봇 토큰 관리가 필요 없습니다:

async function sendDiscordAlert(event) {
  const DISCORD_WEBHOOK_URL = process.env.DISCORD_WEBHOOK_URL;

  await fetch(DISCORD_WEBHOOK_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      embeds: [{
        title: `${event.type}: ${event.data.asset}`,
        description: formatMessage(event),
        color: event.data.direction === 'long' ? 0x22c55e : 0xef4444,
        timestamp: event.timestamp,
      }],
    }),
  });
}

Alert Routing Channels

processEvent 라우터

수신자와 전송 채널이 설정되면, 라우터가 이 둘을 연결합니다. 여기서 어떤 이벤트를 어디로 보낼지 결정하고, 로컬 필터링을 적용하며, 디버깅을 위한 지속성을 추가합니다.

async function processEvent(event) {
  // Log every event for debugging and replay
  console.log(JSON.stringify({ ts: Date.now(), event }));

  // Route by event type and severity
  switch (event.type) {
    case 'cohort.shift':
      // Only alert on the high-conviction cohorts
      const alertCohorts = [
        'Money Printer', 'Smart Money', 'Leviathan', 'Tidal Whale'
      ];
      if (alertCohorts.includes(event.data.cohort_name)) {
        await sendTelegramAlert(event);
        await sendDiscordAlert(event);
      }
      break;

    case 'liquidation.cluster':
      // Adjust threshold to your risk tolerance
      if (event.data.risk_score > 75) {
        await sendTelegramAlert(event);
      }
      break;

    case 'position.large':
      await sendTelegramAlert(event);
      break;

    case 'order_flow.spike':
      // Example: z > 3 catches extreme spikes. Tune for your strategy.
      if (event.data.z_score > 3) {
        await sendTelegramAlert(event);
      }
      break;

    default:
      console.log('Unhandled event type:', event.type);
  }
}

필터링 레이어에 주목하세요. cohort.shift 핸들러는 Money Printer, Smart Money, Leviathan, Tidal Whale에 대해서만 알림을 발동합니다. 이 코호트들은 방향 전환이 가장 강한 시그널을 가집니다: 누적 수익 $1M 이상의 지갑(Money Printer), $100K~$1M(Smart Money), 그리고 가장 큰 계좌 규모($1M~$5M의 Tidal Whale, $5M 이상의 Leviathan)입니다. Shrimp나 Fish 코호트의 변화가 무의미하지는 않지만, 신뢰해야 하는 알림 채널에는 노이즈가 너무 많이 생깁니다.

이벤트 손실 없이 장애 처리하기

분산 시스템은 장애가 발생합니다. 배포 중 서버가 다운됩니다. Telegram이 변동성이 큰 한 시간 동안 레이트 리밋을 걸 수 있습니다. Discord가 30초간 502를 반환할 수 있습니다. 알림 파이프라인이 이런 장애를 처리하지 못하면, 가장 중요한 순간, 즉 혼란이 발생할 때 발동되는 이벤트를 놓치게 됩니다.

함께 잘 작동하는 두 가지 패턴:

1. 로컬 재시도 큐

전송 채널이 실패하면 이벤트를 버리는 대신 재시도 큐에 넣으세요. 낮은 볼륨의 설정에는 간단한 인메모리 배열로 충분합니다. 프로덕션에서는 Redis나 내구성 있는 큐를 사용하세요:

const retryQueue = [];

async function safeDeliver(deliverFn, event, channel) {
  try {
    await deliverFn(event);
  } catch (err) {
    console.error(`Delivery failed (${channel}):`, err.message);
    retryQueue.push({ deliverFn, event, channel, attempts: 1 });
  }
}

// Process retries every 30 seconds
setInterval(async () => {
  const batch = retryQueue.splice(0, 10);
  for (const item of batch) {
    try {
      await item.deliverFn(item.event);
    } catch {
      item.attempts++;
      if (item.attempts < 5) retryQueue.push(item);
      else console.error('Dropped after 5 retries:', item.event.type);
    }
  }
}, 30_000);

2. 재생을 위한 이벤트 로그

라우팅 전에 모든 수신 웹훅을 파일이나 데이터베이스에 기록하세요. 서식 로직의 버그를 발견하거나 전송 채널에서 누락이 생겼을 때, 로그를 재생해 알림을 보충할 수 있습니다. 위 processEvent의 JSON 로깅 줄이 가장 간단한 형태입니다. 프로덕션에서는 파일에 추가하거나 SQLite 테이블에 기록하세요.

웹훅 파이프라인 테스트

실제 시장 이벤트에 의존하기 전에 합성 페이로드로 파이프라인을 엔드투엔드로 검증하세요. 현실적인 페이로드 형식으로 로컬 엔드포인트에 테스트 POST를 전송하세요:

curl -X POST http://localhost:3000/webhooks/hypertracker \
  -H "Content-Type: application/json" \
  -H "x-ht-signature: test-skip-in-dev" \
  -d '{
    "event_id": "test-001",
    "type": "cohort.shift",
    "timestamp": "2026-07-10T14:30:00Z",
    "data": {
      "asset": "ETH",
      "cohort_name": "Money Printer",
      "cohort_id": 8,
      "direction": "short",
      "net_position": -1247.5
    }
  }'

Telegram 채널 또는 Discord 서버가 서식이 지정된 알림을 받는지 확인하세요. 그 다음 실패 경로를 테스트하세요: Telegram 봇 토큰을 일시적으로 비활성화하고, 다른 테스트 이벤트를 전송한 뒤, 재시도 큐에 들어가는지 확인하세요. 이 두 가지 확인, 정상 경로와 실패 경로, 가 라이브 전에 대부분의 통합 문제를 잡아냅니다.

HyperTracker 대시보드에는 웹훅 설정 페이지에 "테스트 이벤트 전송" 버튼도 있습니다. 이를 통해 프로덕션 전송 파이프라인으로 실제 페이로드 형식을 발동해, 시장 이벤트를 기다리지 않고도 엔드포인트가 접근 가능하고 올바르게 응답하는지 검증할 수 있습니다.

알림에서 자동화로

알림 파이프라인이 가동되면, 자연스러운 다음 단계는 이러한 시그널을 프로그래밍 방식으로 활용하는 것입니다. Telegram으로 라우팅하는 동일한 processEvent 함수가 거래를 트리거하거나, 포지션을 조정하거나, 대시보드를 업데이트하는 데도 쓰일 수 있습니다. BTC에서 Money Printer가 순 숏으로 전환되면 자동으로 손절 주문을 좁힐 수 있습니다. 현재 가격 위에 청산 클러스터가 형성되면 헤지를 트리거할 수 있습니다.

웹훅이 감지와 행동을 분리하기 때문에 아키텍처가 확장됩니다. 수신자는 "무언가 일어났다" 레이어를 처리합니다. 별도의 모듈이 "그것에 대해 무엇을 할 것인가" 레이어를 처리합니다. 수신자나 서명 검증을 건드리지 않고 새로운 행동(Slack에 게시, 데이터베이스에 기록, TradingView 알림 트리거)을 추가할 수 있습니다.

HyperTracker는 Hyperliquid의 모든 지갑을 16개의 행동 코호트로 분류합니다: 계좌 규모별 8개(Shrimp부터 Leviathan까지)와 누적 손익별 8개(Money Printer부터 Giga-Rekt까지). 이 분류가 집합적으로 변화할 때 웹훅이 발동됩니다. 그 변화가 자신의 포지션에 무엇을 의미하는지 판단하고 대응을 연결하는 것은 여러분의 몫입니다.

웹훅으로 빌딩 시작하기

웹훅 전송은 HyperTracker의 Flow ($799/월) 및 Stream ($1,999/월) 티어에서 이용할 수 있습니다. Flow는 웹훅과 함께 월 400,000회 API 요청 및 분당 200회 레이트 리밋을 제공합니다. Stream은 WebSocket 전송, 월 200만 회 요청, 분당 500회를 추가합니다. 두 티어 모두 이 가이드에서 다룬 알림 이벤트를 구동하는 전체 코호트 분석, 오더 플로우, 청산 리스크 엔드포인트가 포함됩니다.

HyperTracker API 티어 살펴보기

대부분의 트레이딩 인프라는 튜토리얼에서 보여주는 방식이기 때문에 폴링 루프로 시작합니다. 프로덕션 수준의 시스템을 출시하는 빌더들은 가능한 한 빨리 푸시 전송으로 이동합니다. 시그널 감지의 매분 지연이 놓친 거래와 낡은 알림으로 복리처럼 쌓이기 때문입니다. 지금 30분의 설정으로, 시장이 움직이는 새벽 3시에 불안정한 크론 잡을 디버깅하는 상황을 피할 수 있습니다.