본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 15. 07:26

n8n으로 프리랜서 구직 자동화 시스템을 구축하며 배운 모든 것

요약

n8n과 Groq API를 활용하여 프리랜서 구직 과정을 자동화하는 시스템 구축 사례를 소개합니다. 일자리 스캔, AI 기반 점수 산정, 제안서 생성 및 텔레그램 알림까지 이어지는 전체 워크플로우와 기술 스택을 다룹니다.

핵심 포인트

  • n8n과 Groq API를 결합한 저비용 고효율 자동화 시스템 구축
  • AI를 활용한 맞춤형 제안서 생성 및 A/B 테스트 수행
  • n8n 사용 시 JSON 내 키릴 문자 처리 및 노드 병합 주의사항
  • Supabase와 Telegram을 활용한 데이터 관리 및 알림 체계

저는 룩셈부르크에서 온 17세 IT 학생입니다. 몇 달 전, 저는 Upwork, Malt, Freelancer를 매일 2~3시간씩 수동으로 뒤지며 프로젝트를 찾는 것에 지쳤습니다.

그래서 저를 대신해 24시간 내내 Raspberry Pi 3에서 작동하는 자동화 시스템을 구축했습니다.

이 시스템이 무엇을 하는지, 어떻게 구축했는지, 그리고 그 과정에서 배운 모든 고통스러운 교훈들을 소개합니다.

시스템 기능

  • 30분마다 Upwork, Malt, Freelancer 스캔
  • 내 프로필을 기반으로 AI를 사용하여 각 일자리에 0~100점 점수 부여
  • 영어, 프랑스어, 독일어로 제안서 (proposals) 생성
  • 가장 적합한 일자리를 인라인 A/B 버튼과 함께 Telegram으로 전송
  • 어떤 제안서 스타일이 더 많은 답장을 받는지 추적
  • 일일 통계 및 주간 시장 트렌드 보고서 전송
  • 3일 후 후속 조치 (follow up)를 하도록 알림 전송

기술 스택 (The stack)

  • n8n — 셀프 호스팅 워크플로우 자동화 (Raspberry Pi 3 상의 Docker)
  • Groq API (Llama 3.1-8b-instant) — AI 점수 산정 및 제안서 생성
  • Supabase — 일자리, 제안서, 클라이언트를 위한 PostgreSQL 데이터베이스
  • SerpAPI — Google을 통한 채용 게시판 검색
  • Apify — Upwork 리스팅 스크래핑 (scraping)
  • Telegram Bot API — 알림 및 봇 명령
  • Cloudflare Tunnel — 웹훅 (webhooks)을 위한 HTTPS

총 운영 비용: 월 약 $5.

7가지 워크플로우

01 - 일자리 발견 (Job Discovery) — 30분마다 실행되며 10개 이상의 소스를 검색하고, Supabase의 URL 고유 제약 조건(unique constraint)을 통해 중복을 제거합니다.

02 - 제안서 생성기 (Proposal Generator) — AI가 일자리에 점수를 매기고, 두 가지 제안서 변형(격식 있는 스타일 vs 후크 우선 스타일)을 생성하여 A/B 버튼과 함께 Telegram으로 전송합니다.

03 - 후속 조치 알림 (Follow-up Reminders) — 답장이 없는 제안서가 있는지 3일마다 Supabase를 확인합니다.

04 - Telegram을 통한 CRM — 봇 명령(/jobs, /stats, /clients)을 통해 전체 클라이언트 관리를 수행합니다.

05 - 시장 정보 (Market Intelligence) — 일일 보고서: 발견된 일자리 수, 평균 점수, 주요 플랫폼.

06 - 트렌드 분석 (Trend Analysis) — 자동화 분야에서 어떤 기술이 트렌드인지에 대한 주간 보고서.

07 - 리드 생성 (Lead Generation) — n8n으로 전환할 의사가 있을 법한, Zapier나 Make를 활발히 사용하는 기업들을 찾아냅니다.

배운 교훈 (어렵게 깨달은 것들)

1. 키릴 문자(Cyrillic text)가 JSON body 노드를 조용히 깨뜨립니다
줄바꿈이 포함된 JSON body 필드에 키릴 문자가 있으면, n8n은 "Bad control character" 에러를 발생시킵니다. 모든 내용을 한 줄로 유지하거나, 실제 줄바꿈 대신 \n을 사용하세요.

2. Code 노드에 여러 입력을 넣으려면 먼저 Merge 노드가 필요합니다
두 개의 HTTP Request 노드가 하나의 Code 노드로 연결될 때는, 그 사이에 Merge 노드(Combine by Position 방식)를 사용하세요. 그렇지 않으면 $('NodeName') 호출 시 "hasn't been executed" 에러가 발생합니다.

3. Cloudflare 터널 URL은 재시작할 때마다 변경됩니다
이로 인해 모든 Telegram 웹후크(webhook)가 작동하지 않게 됩니다. 저는 cloudflared를 재시작하고 docker-compose의 WEBHOOK_URL 환경 변수를 자동으로 업데이트하는 systemd 서비스를 통해 이 문제를 해결했습니다.

4. 중복 제거(Deduplication)는 n8n이 아니라 데이터베이스에서 처리해야 합니다
Supabase의 jobs.url에 UNIQUE 제약 조건을 추가하고, insert 노드를 "Continue on Fail"로 설정하는 것이 워크플로우 내부에서 중복을 확인하려고 시도하는 것보다 훨씬 깔끔합니다.

5. Code 노드는 항상 아이템을 반환해야 합니다
Code 노드가 아무것도 반환하지 않으면(빈 배열 또는 undefined), 워크플로우는 하위 노드로 더미 데이터를 조용히 전달합니다. 항상 [] 또는 적절한 아이템을 반환하세요.

6. LLM은 "JSON으로만 응답하라"는 지시를 무시합니다
Groq은 계속해서 JSON을

markdown 블록으로 감싸서 반환했습니다. 해결 방법: 파싱하기 전에 백틱(backticks)을 제거하거나, JSON 대신 구분자(separator) 기반의 출력을 사용하세요.

...

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0