케이스 스터디
CASE STUDY — 자동화

Telegram 승인 게이트

도입 물류 스타트업구축 3일
Telegramn8nWebhook

결재 한 건이 막히면 그 뒤 작업 전체가 멈췄습니다. 담당자는 메일함을 새로고침했고, 요청자는 "승인 되셨나요?"를 반복해서 물었습니다. 문제는 승인 자체가 아니라, 승인을 기다리는 시간이었습니다.

그래서 결재를 메일함 밖으로 꺼냈습니다. 요청이 들어오면 담당자의 텔레그램으로 카드가 날아가고, 버튼 한 번이면 워크플로우가 다음 단계를 바로 실행합니다.

telegram-approval.workflowLIVE
REQ요청 접수TGTelegram 카드승인 / 반려n8다음 단계 실행

어떻게 동작하나

워크플로우는 두 개의 트리거 체인으로 구성됩니다. 첫 번째는 결재 요청을 받고 텔레그램 카드를 보내는 발송 체인, 두 번째는 담당자의 버튼 탭을 폴링으로 받아 결과를 다운스트림으로 되돌려주는 콜백 체인입니다. 상태는 n8n의 워크플로우 정적 데이터(static data)에 잠깐 저장했다가, 콜백이 도착하면 꺼내 씁니다.

발송 체인

  1. Webhook 노드가 결재 요청을 HTTP POST로 받습니다.
  2. Edit Fields (Set) 노드로 페이로드를 정규화합니다 (requestId, title, amount, requester, approverChatId, callbackUrl).
  3. Code 노드가 워크플로우 정적 데이터에 { requestId: callbackUrl }을 저장합니다.
  4. Telegram Send Message 노드가 담당자 채팅으로 승인 카드를 보냅니다. 카드에는 callback_dataapprove:REQ-ID 또는 reject:REQ-ID 형태인 인라인 버튼 두 개가 붙습니다.
  5. Respond to Webhook 노드가 요청자에게 {"status":"pending","requestId":"..."}을 즉시 반환합니다.

콜백 체인

  1. Telegram Trigger 노드가 callback_query 업데이트를 폴링으로 받습니다. 외부에서 n8n으로 들어오는 웹훅이 필요 없어 로컬 개발 환경에서도 그대로 동작합니다.
  2. Code 노드가 callback_data에서 decisionrequestId를 파싱하고, 저장된 callbackUrl을 조회한 뒤 정적 데이터에서 제거합니다.
  3. HTTP Request 노드가 요청자가 지정한 callbackUrl{decision, requestId}를 POST합니다.
  4. Telegram: Answer Callback Query 노드가 버튼 로딩 스피너를 지우고 사용자에게 완료 알림을 보냅니다.

필요한 것

  • n8n 2.29.9 이상 (자체 호스팅 또는 Cloud). 검증은 자체 호스팅 Docker(docker.n8n.io/n8nio/n8n)에서 진행했습니다.
  • 코어 노드만 사용합니다 (Webhook · Set · Code · Telegram Send Message · Telegram Trigger · HTTP Request · Respond to Webhook · Telegram Answer Callback Query). 커뮤니티 노드 없음.
  • BotFather에서 발급한 Telegram Bot 토큰 — n8n Credentials에 Telegram API로 등록합니다.
  • 결재자의 숫자 chat ID@userinfobot에게 메시지를 보내면 알려줍니다. @username은 사용할 수 없습니다.
  • 결재자가 봇에게 최소 1회 이상 메시지를 보낸 상태여야 합니다 (Telegram 정책). 봇을 검색해서 Start 한 번 눌러 두세요.
  • 결과를 받을 다운스트림 엔드포인트 (callbackUrl). 테스트에는 webhook.site 무료 URL이면 충분합니다.
  • 발송 체인과 콜백 체인은 같은 워크플로우 안에 있어야 합니다. 워크플로우 정적 데이터($getWorkflowStaticData('global'))를 상태 저장소로 쓰기 때문입니다.
  • 잘못된 chat ID를 넣으면 Telegram Send Message 노드가 Bad Request: chat not found로 실패합니다. 실제 운영에서는 이 분기에 알림·재시도 처리를 붙이세요.
  • 정적 데이터는 워크플로우 비활성화·삭제 시 사라지는 휘발성 저장소입니다. 시간이 오래 걸리는 결재나 감사 로그가 필요한 운영 환경에서는 Postgres 등 영구 저장소로 교체하세요.

샘플 페이로드

curl -X POST http://localhost:5678/webhook/telegram-approval \
  -H "Content-Type: application/json" \
  -d '{
    "requestId": "REQ-2026-001",
    "title": "예산 승인 요청 — 3분기 마케팅",
    "amount": 1500000,
    "requester": "김지훈",
    "approverChatId": "8104222459",
    "callbackUrl": "https://webhook.site/your-uuid"
  }'
이 워크플로우는 n8n 2.29.9에서 curl → 텔레그램 카드 발송 → 담당자 버튼 탭 → callbackUrl POST → 스피너 해제까지 실제로 실행하며 검증했습니다. 마지막 검증: 2026-07-11.
6.2h → 40분
평균 승인 대기 시간
0건
누락된 결재
3일
구축 기간
출근하면서 폰으로 결재 다 끝냅니다. 사무실 도착하면 이미 다음 단계가 돌고 있어요.운영 매니저

당신의 업무도
여기 들어갈 수 있어요.

가장 반복적인 업무 하나만 알려주세요. 자동화 시나리오를 그려드립니다.