본문으로 건너뛰기
취준생을 위한 n8n 실전 워크플로우 레시피 · 5/44시리즈 보기 →

NFC 태그를 찍으면 AI 명언 페이지가 뜨는 n8n 웹훅 — n8n을 나만의 API 서버로 쓰기

· 약 10분
Datapopcorn CEO / AI automation educator
이 글과 연결된 글 보기
7편 · 20개 연결
100%
n8n Data Table 처음 써보기 — 트렌드 3개를 합쳐 매일 아침 분석 주제 뽑는 워크플로우n8n으로 정적 웹서버 운영하기 — 수료증 발급부터 진위 확인까지, 멱등 처리로 안전하게벡터DB 없이 실시간으로 사이트를 읽는 챗봇 — 경복대학교 안내 챗봇 해부NFC 태그를 찍으면 AI 명언 페이지가 뜨는 n8n 웹훅 — n8n을 나만의 API 서버로 쓰기n8n으로 반복업무 자동화 포트폴리오 만들기구글시트에 쌓인 데이터를 인스타그램 카드뉴스로 — n8n 시트 인스타그램 자동발행서브워크플로우를 Tool로 감싸 AI Agent에게 서버 점검시키기 — 그리고 시스템 프롬프트만으로는 부족한 이유

드래그로 이동 · 휠/두 손가락으로 확대 · 방향키로 글 선택 · 0으로 맞춤. 실선: 본문 링크, 점선: 시리즈·주제의 대표 연결.

표시된 글 7편 목록
전체 글 연결 탐색

NFC 스티커에 n8n 웹훅 URL 하나를 써 두면, 스마트폰을 갖다 댈 때마다 AI가 새로 고른 명언이 카드 모양 웹페이지로 뜹니다. Webhook 노드로 요청을 받고, AI Agent와 Structured Output Parser로 답을 정해진 형태로 만들고, Respond to Webhook 노드로 HTML을 돌려주는 노드 4개짜리 흐름입니다. 이 세 가지를 손에 익히면 n8n이 "정해진 시간에 도는 자동화 도구"에서 "요청이 오면 내가 정한 응답을 돌려주는 작은 API 서버"로 바뀌고, 명언 대신 구글시트에 한 행을 쌓는 변형도 같은 뼈대로 만들 수 있습니다.

이 워크플로우 하나로 보여줄 수 있는 것​

재고 알림 편이 정해진 시간에 n8n이 스스로 도는 자동화였다면, 이 편은 밖에서 요청이 올 때 n8n이 응답하는 자동화입니다. "n8n으로 API도 만들 수 있나요?"라는 면접 질문에 "웹훅으로 요청을 받아 AI 응답을 HTML 페이지로 돌려주는 걸 만들어 NFC 태그에 붙였습니다"라고 답할 수 있게 됩니다.

  • 웹훅 엔드포인트 운영 — URL을 열면 워크플로우가 실행되는 입구를 만들고, Test URL과 Production URL을 구분해 Active까지 켜본 경험
  • AI 구조화 출력 — 모델의 답을 quote, author 두 필드로 고정해 다음 노드가 안심하고 쓰게 만든 경험
  • 응답 설계 — 요청한 쪽에 무엇을 돌려줄지(HTML 페이지, JSON, 상태 코드)를 직접 정해본 경험

세 번째가 핵심입니다. 지금까지의 워크플로우는 결과를 슬랙이나 시트로 보내고 끝났지만, 웹훅은 요청한 사람이 화면 앞에서 응답을 기다립니다. 이 감각은 챗봇, 폼 처리, 외부 서비스 연동에 그대로 쓰입니다.

배경 — 스티커 한 장에 URL 하나​

NFC 태그는 스마트폰을 가까이 대면 안에 적힌 URL을 여는 얇은 스티커입니다. 2026년 8월 기준 국내 오픈마켓에서 개당 몇백 원대이고, 한 번 써 두면 대부분의 스마트폰이 앱 없이 읽습니다. 그 URL 자리에 n8n 웹훅 주소를 넣으면 "태그를 찍는다"가 곧 "워크플로우를 실행한다"가 됩니다.

원본은 데이터팝콘 n8n 인스턴스에 2025년 4월에 만들어져 이 글을 쓰는 시점에도 Active 상태인 워크플로우입니다. 스티키 노트에는 "NFC로 태깅할 때마다 새로운 명언을 보여주는 기능"이라는 한 줄과 함께 트리거는 "NFC 태그에 웹훅 링크를 연결", 도착지는 "유저에게 웹페이지를 띄우기"라고 적혀 있습니다. 태스크 칸은 비어 있는데 캔버스에서는 AI Agent가 그 자리를 채웁니다. 명언 주제가 '죽음'인 건 프롬프트가 그렇기 때문이고, 따라 만들 때는 바꾸면 됩니다.

설치와 기본 노드는 n8n으로 반복업무 자동화 포트폴리오 만들기에 있으니, 여기서는 웹훅과 응답에만 집중합니다.

구조 — Trigger / Task / Target​

  • Trigger — 웹훅 URL로 GET 요청이 들어올 때. NFC 태그가 폰 브라우저를 여는 순간입니다
  • Task — AI가 명언과 저자를 JSON으로 만들고, HTML 템플릿의 빈칸에 끼움
  • Target — 요청한 브라우저에 HTML 페이지로 응답

재고 알림 편과 결정적으로 다른 점은 Target이 "요청을 보낸 바로 그 브라우저"라는 것이고, 그래서 마지막 노드가 무엇을 돌려주는지가 설계의 중심입니다.

만들기​

1. Webhook — GET으로 받고, 응답은 Respond 노드에 맡기기​

Webhook 노드를 추가하고 HTTP Method를 GET, Path를 quote로 둡니다. 브라우저가 URL을 여는 요청은 GET이라 NFC 태그용 웹훅은 GET이어야 합니다. 이 노드에서 제일 중요한 설정은 Respond인데, 선택지 세 개가 공식 문서 기준으로 이렇게 다릅니다.

  • Immediately — 요청을 받자마자 응답 코드와 "Workflow got started" 메시지를 돌려주고 워크플로우는 뒤에서 돕니다. 기본값입니다
  • When Last Node Finishes — 마지막 노드의 출력 JSON을 그대로 돌려줍니다
  • Using 'Respond to Webhook' Node — 응답 내용을 Respond to Webhook 노드에서 따로 정합니다

원본은 세 번째입니다. 기본값으로 두면 브라우저에 "Workflow got started"만 뜨고 명언은 오지 않고, 두 번째면 JSON이 그대로 보입니다. HTML 페이지를 돌려주려면 형식과 내용을 직접 정하는 Respond 노드가 필요합니다.

URL은 두 개입니다. Test URL(/webhook-test/quote)은 Listen for test event를 누르고 있는 동안만 살아 있고, Production URL(/webhook/quote)은 Active로 켠 뒤에 등록됩니다. NFC 태그에는 반드시 Production URL을 씁니다. 원본 워크플로우의 이름에는 이 URL이 통째로 들어 있는데, export나 공유 때 그대로 따라가니 권하지 않고 이 글에서도 실제 주소는 적지 않습니다.

2. AI Agent + Structured Output Parser — 명언을 두 필드로 고정​

AI Agent 노드에서 Source for Prompt를 Define으로 두고 Prompt에는 지침에 따라 답변하기 한 줄만 넣습니다. Chat Model에는 Google Gemini Chat Model을 연결했고 모델은 기본값 그대로입니다. Require Specific Output Format을 켜고 Structured Output Parser를 붙인 뒤, Schema Type을 Define Below로 두고 JSON Schema를 적습니다.

{
"type": "object",
"properties": {
"quote": { "type": "string", "description": "죽음을 주제로 한 짧고 인상 깊은 한글 명언" },
"author": { "type": "string", "description": "명언을 남긴 사람의 이름" }
},
"required": ["quote", "author"]
}

System Message는 다음과 같습니다.

당신은 죽음에 관한 깊이 있는 명언을 선별하여 삶의 소중함을 일깨워주는 철학자입니다.

'죽음'을 주제로 삶을 되돌아보게 하는 명언 하나를 골라, 반드시 **한글로 번역**해서 내용(quote)과 저자(author)를 제공하세요.

프롬프트가 짧은 대신 "짧고 인상 깊은 한글 명언"이라는 조건이 스키마의 description에 들어가 있습니다. 파서를 쓰면 이렇게 프롬프트와 스키마가 역할을 나눠 갖고, 다음 노드는 {{ $json.output.quote }}와 {{ $json.output.author }}가 반드시 있다고 믿고 설계할 수 있습니다. 원본의 System Message 칸에는 위 문장이 {"role": "system", "content": "..."} JSON으로 감싸진 채 들어 있는데, 동작은 하지만 따라 만들 때는 content 안의 문장만 넣으면 됩니다.

3. HTML — 명언을 카드 페이지로​

HTML 노드(Generate HTML Template)의 HTML 칸에 페이지 전체를 쓰고, 명언이 들어갈 자리에 표현식을 끼웁니다. 원본은 손글씨 폰트, 카드 그림자, 공유 버튼까지 갖춘 200줄 가까운 페이지인데, 뼈대만 추리면 다음과 같습니다.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>오늘의 명언</title>
</head>
<body>
<div class="quote-card">
<p class="quote-text">{{ $json.output.quote }}</p>
<p class="quote-author">― {{ $json.output.author }}</p>
<button id="shareBtn">공유하기</button>
</div>
</body>
</html>

이 노드의 출력은 html 필드 하나입니다. 원본의 공유 버튼은 navigator.share로 폰의 공유 시트를 열고, 지원하지 않는 브라우저에서는 클립보드에 복사합니다. 카드 디자인은 직접 짤 필요 없이 AI에게 "모바일용 명언 카드 페이지 HTML을 만들어 줘"라고 시킨 뒤 명언과 저자 자리만 위 표현식으로 바꾸면 됩니다.

4. Respond to Webhook — HTML을 텍스트로 돌려주기​

Respond to Webhook 노드에서 Respond With를 Text로, Response Body를 {{ $json.html }}로 둡니다. 공식 문서에 따르면 Text 응답은 기본 Content-Type이 text/html이라 브라우저가 페이지로 렌더링합니다. 앱이나 단축어용으로 JSON을 돌려주려면 Respond With만 JSON이나 First Incoming Item으로 바꾸면 됩니다. 여기까지 만들었으면 Test URL을 브라우저에서 열어 명언 카드가 뜨는지 확인한 뒤 Active를 켭니다.

5. NFC 태그에 Production URL 쓰기​

태그는 NTAG213 같은 빈 NFC 스티커면 됩니다. 안드로이드와 아이폰 모두 앱 스토어에서 "NFC 태그 쓰기"로 검색해 나오는 앱으로 URL 레코드를 기록할 수 있고, 읽는 쪽에는 앱이 필요 없습니다. 폰을 태그에 대면 링크 알림이 뜨고, 탭하면 브라우저가 Production URL을 열면서 워크플로우가 돕니다. 흔한 실수는 Test URL을 태그에 쓰는 것이니 /webhook/ 경로인지 한 번 더 확인하세요.

같은 패턴, 다른 Target — 반려동물 돌봄 기록​

두 번째 원본은 같은 인스턴스의 EP49_pet_nfc입니다. 사료통 옆 NFC 태그를 찍으면 "누가, 무슨 활동을, 언제" 했는지 구글시트에 한 행이 쌓이는 워크플로우로, 흐름이 두 개이고 스티키 노트도 "nfc 태그 시 구글시트에 데이터 적재", "웹 접속 시 데이터 가져오기" 두 장뿐입니다.

첫 번째 흐름의 Webhook은 POST이고, Google Sheets 노드는 Append에서 세 컬럼을 직접 매핑합니다.

  • 누가: {{ $json.body.user }}
  • 활동: {{ $json.body['activity'] }}
  • 일시: {{ $now.toFormat('yyyy-MM-dd HH:mm:ss') }}

요청 본문의 user, activity가 시트 컬럼으로 들어가고, 시각은 $now로 서버에서 찍습니다. 노드 이름이 "Webhook - shortcut"인 걸 보면 이 버전은 아이폰 단축어 자동화가 태그를 인식해 본문을 POST로 보내는 구조입니다. 태그에는 URL만 들어가니 "누가" 같은 정보는 폰 쪽에서 붙여야 하기 때문입니다. 브라우저로 여는 방식이면 GET으로 바꾸고 ?user=me&activity=feed처럼 쿼리에 실어 {{ $json.query.user }}로 읽습니다.

두 번째 흐름은 GET /get-data로 시트를 읽어 오는 조회용 입구입니다. 다만 원본은 두 Webhook 모두 Respond가 기본값 Immediately라 이대로면 "Workflow got started"만 오고, 워크플로우도 아직 Active가 아닙니다. 데이터를 돌려주려면 When Last Node Finishes로 바꿔야 하는, 만들다 멈춘 상태입니다.

명언 편과 나란히 놓으면 Trigger는 똑같이 Webhook 노드이고 바뀐 건 Target뿐입니다. 웹훅 패턴 하나로 Target만 갈아 끼우면 다른 프로젝트가 됩니다.

원본 캔버스에 남아 있는 흔적​

운영 데이터는 따로 없어서, 대신 캔버스에 남은 흔적 세 가지를 옮깁니다.

첫째, 본 흐름과 연결되지 않은 OpenAI Chat Model 노드가 떠 있고 모델 이름이 solar-mini입니다. Upstage Solar를 OpenAI 호환 방식으로 붙여 본 흔적으로 보이고, 최종 흐름에는 Gemini가 연결돼 있습니다. AI Agent는 모델이 서브노드라 이렇게 갈아 끼우며 비교하기 쉽습니다.

둘째, 스티키 노트에는 노드보다 훨씬 긴 프롬프트가 남아 있습니다. "죽음 주제", "한 문장", "출처 제시", "한글로만" 네 조건에 quote, author, original, translated 네 필드짜리 JSON 예시까지 있는데, 실제 노드는 HTML이 쓰는 두 필드로 좁혀졌습니다. 원문을 함께 보여주고 싶으면 긴 버전을 쓰고 스키마에 original을 추가하면 됩니다.

셋째, HTML 노드 안에 예시 명언을 넣어 보는 함수가 주석 처리된 채 남아 있습니다. 페이지를 n8n 밖에서 먼저 완성하고 표현식으로 갈아 끼운 순서가 보이는데, 실제로 그 순서가 편합니다.

한계​

  • 인증이 없습니다 — URL을 아는 사람은 누구나 호출할 수 있고, 호출마다 LLM 비용이 듭니다. 태그가 브라우저를 여는 구조라 헤더 인증은 못 붙입니다. 쿼리에 비밀값을 실어 IF 노드로 거르거나, 시트에 호출 횟수를 세어 하루 상한을 두는 정도가 현실적이고, 시트에 쓰는 반려동물 버전은 특히 신경 써야 합니다
  • 응답이 올 때까지 흰 화면입니다 — 모델이 답을 내기 전까지 브라우저는 빈 화면입니다. 명언을 스케줄로 미리 만들어 시트에 쌓아 두고 웹훅은 한 줄 꺼내기만 하게 나누면 즉시 응답이 됩니다
  • 같은 명언이 또 나올 수 있습니다 — 이전 결과를 기억하지 않습니다. 시트에 기록하고 프롬프트에 "이 목록은 제외"를 넣는 게 가장 단순합니다
  • 실패하면 그냥 에러 화면입니다 — 모델 호출이 실패하면 사용자는 n8n 에러를 봅니다. 에러 분기에서 "잠시 후 다시 시도해 주세요" 페이지를 돌려주는 구조는 Error Trigger 편과 이어집니다

포트폴리오·면접 포인트​

두 원본을 합치면 응용이 바로 나옵니다. 회의실 문 앞 태그를 찍으면 예약 현황 페이지가 뜨는 것, 명함에 태그를 넣어 포트폴리오 페이지를 띄우면서 방문 기록을 시트에 남기는 것. 둘 다 Target만 바꾼 것입니다. 포트폴리오에는 캔버스 스크린샷보다 태그에 폰을 대고 페이지가 뜨는 10초짜리 영상이 잘 통합니다.

면접에서는 "Immediately로 두면 어떻게 되나요?"나 "인증 없는 웹훅을 공개해도 되나요?" 같은 질문이 올 수 있습니다. 앞의 답은 "Workflow got started 메시지만 가고 응답 내용은 못 정한다", 뒤의 답은 "명언 정도는 괜찮지만 쓰기 작업이면 비밀값과 호출 상한이 필요하다"입니다. 노드 사용법이 아니라 응답과 보안을 설계한 사람으로 보입니다.

다음 액션​

이 편의 웹훅은 GET으로 받아 텍스트를 돌려주는 가장 단순한 형태였습니다. 다음 편은 웹훅으로 사진을 받아 AI가 판별하고 습관 체크 시트에 표시하는 워크플로우입니다. 입력이 이미지로 바뀌지만 Webhook 노드가 받고 Target에 남기는 뼈대는 같습니다.