AI 자동화가 강력해질수록 한 가지 질문이 따라옵니다: “이걸 정말 자동으로 실행해도 되는 건가?”
고객에게 이메일을 보내거나, 결제를 처리하거나, 데이터를 삭제하는 등 되돌리기 어려운 작업은 AI가 알아서 하기보다, 사람이 한 번 확인하는 게 안전합니다. 이런 확인 절차를 “Approval Gate(승인 게이트)”라고 부릅니다.
이 글에서는 n8n과 Telegram을 활용해 실제로 운영 중인 승인 게이트 시스템의 구축 사례를 상세히 공유합니다.
어떻게 동작하는가?
흐름을 자세히 설명하면 이렇습니다:
- 워크플로우가 중요한 작업에 도달하면, 즉시 실행하지 않고 승인 요청을 생성합니다.
- MySQL에 승인 요청을 기록하고 (approval_id, 워크플로우 이름, 요약, 상태를 pending으로 저장)
- Telegram으로 승인 요청 메시지를 보냅니다. 메시지에는 “Approve”와 “Reject” 버튼이 포함됩니다.
- 워크플로우는 일시 정지됩니다 (n8n의 “Wait for Human Decision” 노드 활용).
- 담당자가 Telegram에서 Approve 또는 Reject 버튼을 누르면,
- MySQL에 결과가 반영되고 (상태를 approved/rejected로 업데이트, 결정 시간과 결정자 기록)
- 일시 정지된 워크플로우가 다시 깨어나서 승인이면 다음 단계를 실행하고, 거절이면 중단합니다.
시스템 아키텍처
이 시스템은 2개의 n8n 워크플로우와 1개의 MySQL 테이블로 구성됩니다:
Telegram Approval Gate
재사용 가능한 서브 워크플로우. 다른 워크플로우에서 “Execute Sub-Workflow” 노드로 호출합니다. 승인 요청 생성 → DB 저장 → Telegram 발송 → 대기 → 결과 처리까지 전체 흐름을 담당합니다.
Reject Reason Form
항상 활성화(Active) 상태로 유지해야 하는 워크플로우. 거절 시 사유를 입력받는 HTML 폼을 제공합니다. Telegram의 Reject 버튼을 누르면 이 워크플로우가 서빙하는 폼 페이지가 열립니다.
왜 워크플로우가 2개인가?
승인(Approve)은 단순히 버튼 하나로 끝나지만, 거절(Reject)은 “왜 거절했는지” 사유가 필요합니다. Telegram 버튼만으로는 텍스트 입력을 받을 수 없기 때문에, 거절 시 별도의 웹 폼으로 이동시키는 방식을 사용합니다.
핵심 설계 원칙: 승인은 원클릭으로 빠르게, 거절은 사유와 함께 신중하게. 이 비대칭 설계가 실무에서 효율적입니다.
MySQL 테이블 설계
모든 승인 요청의 이력은 workflow_approvals 테이블에 저장됩니다:
이 테이블 하나로 승인 요청의 전체 생명주기를 관리합니다. 누가, 언제, 왜 승인/거절했는지 모든 이력이 남습니다.
실제 데이터 예시
| approval_id | 워크플로우 | 상태 | 거절 사유 | 처리 시간 |
|---|---|---|---|---|
kmoazb2uhx |
Testing Workflow | rejected | ByeBye | 10초 |
hz7lheyit9 |
Testing Workflow | rejected | (사유 미입력) | 7초 |
dn6pju91ai |
Testing Workflow | pending | — | 대기 중 |
메인 워크플로우 상세 분석
Telegram Approval Gate 워크플로우는 총 12개의 노드로 구성됩니다. 각 노드의 역할을 하나씩 살펴봅시다.
1단계: 승인 요청 수신
Receive Approval Request 노드는 다른 워크플로우에서 “Execute Sub-Workflow”로 호출될 때 3개의 파라미터를 받습니다:
workflow_name— Telegram 메시지에 표시되는 워크플로우 이름context_summary— 승인 대상에 대한 한 줄 설명message_text— 상세 메시지 본문
2단계: 고유 코드 생성 + DB 저장
Generate approval_code 노드에서 랜덤 10자리 고유 코드를 생성합니다. 이 코드가 승인 요청의 식별자가 됩니다.
💡 설계 포인트: INSERT와 SELECT LAST_INSERT_ID()를 별도 노드로 분리했습니다. n8n의 mysql2 드라이버가 기본적으로 다중 구문 쿼리(allowMultipleStatements)를 비활성화하기 때문입니다. 하나의 executeQuery에서 INSERT … ; SELECT LAST_INSERT_ID(); 를 실행하면 오류가 발생합니다.
3단계: Telegram 메시지 조립 + 발송
Build Approval Payload 노드에서 Telegram 메시지를 조립합니다. 메시지에는 워크플로우 이름, 요약, 상세 내용이 포함되고, Approve 버튼과 Reject 버튼이 인라인 키보드로 첨부됩니다.
Approve 버튼은 n8n의 resume_url을 직접 호출하는 콜백 URL이고, Reject 버튼은 별도의 Reject Reason Form 워크플로우로 연결됩니다.
4단계: 대기 (Wait for Human Decision)
가장 핵심적인 노드입니다. n8n의 “Wait” 노드를 사용해 워크플로우를 일시 정지합니다.
Wait 노드의 2가지 출력:
Output[0] — 사람이 버튼을 눌러서 resume됐을 때 → 승인/거절 분기로 이동
Output[1] — 24시간 타임아웃 → 자동으로 “rejected” 처리 (decided_by = ‘timeout’)
타임아웃 설계가 중요합니다. 만약 타임아웃이 없으면, 아무도 응답하지 않은 승인 요청이 영원히 대기 상태로 남게 됩니다.
5단계: 분기 처리 + DB 업데이트
Check Approve or Reject 노드에서 응답을 확인하고, approved/rejected에 따라 다른 응답을 반환합니다. 동시에 MySQL의 상태를 업데이트합니다.
거절 사유 폼 (Reject Reason Form)
거절 시에는 단순히 “거절됨”으로 끝나지 않고, 왜 거절했는지를 기록해야 합니다. 이를 위해 별도의 웹 폼을 제공합니다.
동작 흐름
- Telegram에서 Reject 버튼을 누르면 브라우저가 열립니다
- Reject Reason Form 워크플로우의 웹훅이 HTML 폼을 서빙합니다
- 사용자가 거절 사유를 입력하고 Submit을 누르면
- 폼이 제출되고, 원래의 approval gate 워크플로우를 resume 시킵니다
- 거절 사유가 MySQL에 기록됩니다
이 워크플로우는 항상 Active 상태를 유지해야 합니다. 비활성화되면 Telegram의 Reject 버튼이 깨진 페이지를 보여주게 됩니다.
실전 활용 시나리오
이 승인 게이트는 재사용 가능한 서브 워크플로우로 설계되어 있어, 어떤 워크플로우에서든 호출할 수 있습니다:
- 고객에게 대량 이메일 발송 전 → 발송 내용과 대상 수를 보여주고 승인 요청
- AI가 생성한 블로그 글 발행 전 → 글 제목과 요약을 보여주고 검토 요청
- 결제/환불 처리 전 → 금액과 대상을 보여주고 승인 요청
- 서버 설정 변경 전 → 변경 내용을 보여주고 승인 요청
- 데이터 삭제/수정 전 → 영향 범위를 보여주고 확인 요청
핵심 가치: AI 자동화의 속도를 유지하면서도, 되돌리기 어려운 작업에 대해서만 사람의 판단을 개입시키는 “선택적 안전장치”입니다. 모든 것을 자동화하되, 중요한 순간에만 사람이 개입하는 것이 이상적인 AI 운영 방식입니다.
기술적 핵심 포인트
| 항목 | 설계 결정 | 이유 |
|---|---|---|
| 식별자 | 랜덤 10자리 문자열 | AUTO_INCREMENT보다 보안적으로 안전 (예측 불가) |
| DB 분리 | INSERT/SELECT 별도 노드 | mysql2 드라이버의 다중 구문 제한 우회 |
| 타임아웃 | 24시간 | 무한 대기 방지, 미응답 시 자동 거절 |
| 거절 폼 | 별도 워크플로우 | Telegram 버튼으로 텍스트 입력 불가 → 웹 폼 활용 |
| 설정 관리 | Global Config 노드 | Telegram Chat ID를 중앙에서 관리 (셀프호스팅은 $env 미지원) |
| 감사 추적 | MySQL 전체 이력 저장 | 누가, 언제, 왜 승인/거절했는지 완전한 기록 |
도입 효과
| Before | After (승인 게이트 도입) |
|---|---|
| 자동화가 실수하면 되돌릴 수 없음 | 중요 작업 전 사람이 한 번 확인 |
| 승인 이력이 남지 않음 | 모든 승인/거절 이력 DB에 영구 보관 |
| 거절 사유를 모름 | 거절 사유까지 기록, 추후 분석 가능 |
| 자동화 신뢰도가 낮아 도입 주저 | 안전장치가 있으니 적극적 자동화 가능 |
| 승인을 위해 별도 시스템 필요 | Telegram만으로 어디서든 모바일 승인 |
리소스 다운로드
이 글에서 소개한 전체 소스를 GitHub에 공개했습니다.
- Telegram_Approval_Gate.json — 메인 승인 게이트 워크플로우
- Reject_Reason_Form.json — 거절 사유 입력 폼
- workflow_approvals.sql — MySQL 테이블 스키마
설치 가이드와 전체 소스는 GitHub 저장소를 참고하세요.
직접 구축이 어렵다면
이 승인 게이트 시스템은 n8n Korea가 실제로 운영 중인 프로덕션 아키텍처입니다. 비즈니스에 맞는 승인 워크플로우를 설계하고 구축하는 것부터 기존 자동화에 안전장치를 추가하는 것까지, 전문 팀이 도와드립니다.
n8n 워크플로우 구축에 대해 더 알고 싶다면 카카오 오픈채팅에서 다른 사용자들과 정보를 나눠보세요.