본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 27. 22:40

웹훅(Webhook)이 무엇인지 몰랐을 때, 내 에이전트가 고장 났다

요약

n8n과 Telegram을 활용해 자율형 트레이딩 에이전트를 구축하는 과정에서 발생한 웹훅(Webhook) 설정 오류와 디버깅 경험을 다룹니다. 로컬 터널링 도구 간의 충돌로 인해 웹훅 URL이 예기치 않게 변경되어 에이전트가 응답하지 않았던 기술적 문제를 설명합니다.

핵심 포인트

  • 웹훅은 특정 이벤트 발생 시 데이터를 전달하는 URL 주소임
  • 웹훅 URL 오류 시 에러 메시지 없이 침묵 상태가 지속될 수 있음
  • n8n 재시작 시 터널링 도구(loca.lt 등)가 URL을 자동 덮어쓸 수 있음
  • 에이전트 구축 시 안정적인 고정 웹훅 URL 확보가 필수적임

어느 날이었습니다. 똑같은 문제였죠. 에러 메시지도 없었습니다. 그저 침묵뿐이었습니다.

제 Telegram 봇이 응답하지 않았습니다. "analyze AAPL" 같은 명령어를 보내도 아무런 응답이 돌아오지 않았습니다. n8n을 확인해 보았습니다. 모든 것이 정상적으로 보였습니다. 워크플로우(Workflow)는 활성화되어 있었고, 노드(Nodes)들도 연결되어 있었습니다. 제가 알 수 있는 한, 깨진 것은 아무것도 없었습니다.

저는 웹훅(Webhook)이 무엇인지 몰랐습니다. 봇(Bot)이 무엇인지조차 겨우 알고 있었습니다. 이것은 저의 생애 첫 프로젝트였습니다. 코드를 단 한 줄도 작성하기 전에 n8n으로 구축한 자율형 Solana 트레이딩 에이전트, Cerberus였습니다. 그리고 무언가 보이지 않는 것이 제가 보내는 모든 메시지를 잡아먹고 있었습니다.

그 문제는 제가 그 이후로 본 그 어떤 튜토리얼보다 인터넷이 실제로 어떻게 작동하는지에 대해 더 많은 것을 가르쳐 주었습니다.

웹훅(Webhook)이란 실제로 무엇인가

무엇이 고장 났는지 설명하기 전에, 당시 제가 이해하지 못했던 부분을 말씀드리겠습니다.

웹훅(Webhook)은 그저 URL일 뿐입니다. 그게 전부입니다. 어떤 일이 발생했을 때 서비스(제 경우에는 Telegram)가 데이터를 보낼 수 있는 주소입니다. 여러분이 봇에게 메시지를 보내면, Telegram은 봇이 "새 메시지 있나요?"라고 물어볼 때까지 기다리지 않습니다. 즉시 URL을 핑(Ping)하고 "여기 메시지가 있습니다"라고 말합니다.

만약 그 URL이 틀렸거나, 죽어 있거나, 완전히 다른 곳을 가리키고 있다면 어떻게 될까요? 여러분의 봇은 아무것도 받지 못합니다. 에러도 없습니다. 경고도 없습니다. 그저 침묵뿐입니다. 메시지는 어딘가로 갔지만, 여러분의 봇이 듣고 있는 곳이 아니었을 뿐입니다.

그 침묵 때문에 초보자들에게 웹훅(Webhook) 문제는 디버깅(Debugging)하기가 매우 어렵습니다. 봇이 고장 난 것이 아닙니다. 코드도 고장 난 것이 아닙니다. 봇이 등록된 주소가 틀린 것입니다.

계속해서 저를 배신했던 설정

Cerberus를 처음 만들었을 때, 저는 고장 난 n8n 템플릿으로 시작했습니다. Merge 노드(Merge node)가 제대로 작동하지 않았고, 웹훅(Webhook)은 계속 실패했습니다. 저는 그것들을 고쳤고, 작동하게 만들었습니다. 그러자 진짜 문제가 시작되었습니다.

n8n이 재시작될 때마다, Telegram 봇이 응답을 멈추는 것이었습니다.

새로운 것을 만드는 데 한 시간을 보냅니다. 테스트를 하러 갑니다. 침묵. 모든 것을 확인합니다. 명백하게 잘못된 것은 없습니다. 결국 웹훅(Webhook) URL이 변경되었다는 사실을 알아냅니다. 수동으로 수정합니다. 봇이 다시 작동합니다. 내일 n8n을 재시작합니다. 다시 침묵입니다.

구체적인 문제: 저는 터널링 (tunneling)을 위해 loca.lt를 사용하고 있었습니다. 이는 Telegram이 로컬 머신에 접속할 수 있도록 로컬 머신을 인터넷에 노출해 주는 도구입니다. 또한 안정적이고 영구적인 URL로 사용하기 위해 Cloudflare 터널 (Cloudflare tunnel)도 설정해 두었습니다. 하지만 n8n이 시작될 때마다 loca.lt가 Telegram의 웹훅 (webhook) URL로 스스로를 등록하며, 제 Cloudflare 주소를 덮어써 버렸습니다.

n8n은 시작 시 자체적인 터널 URL을 생성하고 이를 자동으로 등록합니다. 제가 인지조차 못 하고 있던 레이스 (race)에서 loca.lt가 계속 승리하고 있었던 것입니다.

시도했지만 실패했던 모든 방법들

여기서 구체적으로 말씀드리고 싶습니다. 만약 여러분도 이 문제에 직면해 있다면, 아마 이미 이 중 몇 가지는 시도해 보셨을 것이기 때문입니다.

N8N_TUNNEL=false 환경 변수 (environment variable) — 적용되지 않았습니다. .zshrc에 추가해 보았지만 결과는 같았습니다. Cloudflare URL에 시간이 더 필요할 것이라 생각하여 30초의 재등록 지연 (re-registration delay)을 시도했습니다. 여전히 덮어씌워졌습니다. 이를 60초로 늘려보았지만, 여전히 레이스에서 패배했습니다.

n8n 설정 파일 (config files)을 파헤쳐 보았습니다. URL을 하드코딩 (hardcode)하려고 ~/.n8n/tunnel.json 파일을 생성해 보기도 했습니다. 하지만 무엇도 영구적인 해결책이 되지 못했습니다. 재시작할 때마다 loca.lt가 다시 나타났습니다.

좌절스러웠던 점은 문제 그 자체 때문이 아니었습니다. 이 문제가 제가 실제로 만들고 있던 것과는 아무런 상관이 없다는 사실 때문이었습니다. 저는 트레이딩 전략 (trading strategy)을 Telegram에 연결하는 방법을 배우려던 참이었습니다. 대신 저는 이해하지도 못하는 인프라 (infrastructure)와 싸우며 몇 시간을 허비하고 있었습니다.

마침내 유지된 해결책

왜 이런 일이 발생하는지 이해하고 나니, 해결책은 명확해졌습니다.

n8n이 시작되면 즉시 자신의 터널 URL을 Telegram에 등록합니다. 별도로 설정해 둔 저의 Cloudflare URL은 n8n이 항상 더 빨랐기 때문에 이를 덮어쓸 기회조차 없었습니다.

해결책은 시작 스크립트 (startup script)였습니다. n8n이 등록 시퀀스 (registration sequence)를 마칠 때까지 — loca.lt URL이 이미 고정될 만큼 충분히 길게 — 기다렸다가, 즉시 Telegram API를 호출하여 저의 Cloudflare URL로 덮어쓰는 방식이었습니다.

우아한 방법은 아니었습니다. 하지만 작동했습니다. 그리고 일단 작동하자, 그 상태가 유지되었습니다.

봇이 다시 응답하기 시작했습니다. 그리고 저는 그 어떤 튜토리얼에서도 직접적으로 설명해주지 않았던 사실을 배우는 데 단 하루를 소비했다는 것을 깨달았습니다. 바로 인프라 계층 (infrastructure layer)은 고장 나기 전까지는 보이지 않으며, 고장이 나면 소리 없이 발생한다는 사실입니다.

하루 동안의 침묵이 실제로 내게 가르쳐준 것

이 문제를 겪기 전까지, 저는 Telegram 봇을 하나의 '물건'이라고 생각했습니다. 하나의 봇 말이죠. 어딘가에 존재하고, 메시지에 응답하며, 만들면 작동하는 것 말입니다.

이 일을 겪은 후, 저는 그것을 하나의 '시스템'으로 이해하게 되었습니다. 메시지가 당신의 휴대폰을 떠납니다. Telegram의 서버가 이를 수신합니다. 서버는 해당 봇에 등록된 웹훅 (webhook) URL을 조회합니다. 그리고 그 URL로 메시지를 보냅니다. 해당 URL에서 실행 중인 무엇인가가 메시지를 처리하고 응답을 다시 보냅니다.

모든 단계는 잠재적인 장애 지점 (point of failure)입니다. 그리고 그러한 장애의 대부분은 외부에서 보기에 동일해 보입니다. 바로 침묵입니다.

이것은 입문할 때 아무도 말해주지 않는 사실입니다. 어려운 문제는 AI 부분이 아닙니다. 어려운 문제는 배관 (plumbing) 작업입니다. 즉, 데이터가 한 곳에서 다른 곳으로 이동하는 부분이며, 무언가를 디버깅 (debug)하기 전에 그 과정이 정확히 어떻게 작동하는지 반드시 이해해야 하는 부분입니다.

웹훅 (Webhooks)은 현대의 자동화 어디에나 존재합니다. n8n 워크플로 (workflow)가 외부 이벤트에 의해 트리거 (trigger)될 때마다 웹훅이 관여합니다. 모든 Telegram 봇, 모든 결제 프로세서 알림, 푸시 (push)에 반응하는 모든 GitHub 액션 (action)이 그러합니다. 웹훅은 인터넷의 실시간 계층을 잇는 결합 조직이며, 무언가 잘못되었을 때 아무런 소리 없이 작동을 멈춥니다.

나중에야 보였던 더 큰 패턴

실제 구축 단계에 도달하기도 전에 인프라가 나를 이긴 것이 이번이 마지막은 아니었습니다.

로컬에서는 작동하지만 운영 환경 (production)에서 깨지는 OAuth. 두 개의 Python 환경이 일으킨 소리 없는 실패 — 제 코드는 .venv에서 실행되고 있었지만, 제가 설치한 패키지들은 .venv311에 있었습니다. telegram_bot.py에 있는 단 한 줄의 필터가 /remember를 포함하여 제가 보낸 모든 명령어를 소리 없이 삼켜버리고 있었고, 저는 왜 메모리 시스템이 아무것도 저장하지 못하는지 이유를 찾아낼 수 없었습니다.

문제는 달랐지만 패턴은 같았습니다. 당신과 당신이 만들고 있는 대상 사이에 보이지 않는 무언가가 있었습니다. 에러 메시지도 없었습니다. 그저 말이 안 되는 결과가 나타날 뿐이었습니다.

제가 실제로 기르고 있었던 기술은 코딩이 아니었습니다. 그것은 시스템들이 서로 어떻게 연결되는지에 대한 멘탈 모델 (Mental Model)이었습니다. 일단 그 모델을 갖게 되면 — 메시지가 당신의 휴대폰에서 에이전트 (Agent)로 갔다가 다시 돌아오는 경로를 머릿속에 그릴 수 있게 되면 — 어디에서 문제가 발생하는지 추론할 수 있습니다.

그 모델이 없다면, 당신은 그저 추측만 할 뿐입니다.

지금 시작하는 사람에게 해주고 싶은 말

만약 당신이 첫 번째 봇 (Bot)이나 첫 번째 에이전트 (Agent)를 만들고 있는데, 명확한 이유 없이 무언가가 작동을 멈춘다면, 코드를 확인하기 전에 인프라 (Infrastructure)를 먼저 확인하세요.

구체적으로는: 만약 Telegram 봇을 사용 중이라면, 등록된 웹훅 (Webhook) URL을 확인하십시오. 이는 직접적인 API 호출을 통해 수행할 수 있습니다:

curl https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getWebhookInfo

이 명령어 하나가 저의 그날 하루 대부분을 아껴주었을 것입니다. 이 명령은 Telegram이 당신의 봇이 어디에 등록되어 있다고 생각하는지 정확한 URL을 보여줍니다. 만약 그것이 당신의 URL이 아니라면, 그것이 바로 문제의 원인입니다.

그리고 만약 터널 (Tunnel)을 사용하여 n8n을 로컬에서 실행 중이라면, n8n이 자체적으로 터널 등록을 관리한다는 점을 알아두어야 합니다. n8n은 수동적이지 않습니다. 시작 시점에 Telegram에 메시지를 어디로 보낼지 능동적으로 알려줍니다. 만약 사용하고자 하는 별도의 안정적인 URL이 있다면, n8n이 시작되기 전이 아니라, 시작된 후에 n8n의 등록 정보를 덮어써야 합니다.

웹훅 (Webhook)은 마법이 아닙니다. 그것은 그저 주소일 뿐입니다. 주소를 올바르게 설정하면 그 하위의 모든 것이 작동합니다. 주소를 잘못 설정하면, 당신의 완벽한 코드가 왜 아무것도 하지 못하는지 고민하며 하루를 허비하게 될 것입니다.

그 교훈을 얻기 위해 저는 하루를 허비했습니다. 부디 당신은 10분만 쓰게 되기를 바랍니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0