레딧 인기글을 3시간마다 슬랙으로 요약해 받기 — n8n 커뮤니티 모니터링 자동화
이 글과 연결된 글 보기
드래그로 이동 · 휠/두 손가락으로 확대 · 방향키로 글 선택 · 0으로 맞춤. 실선: 본문 링크, 점선: 시리즈·주제의 대표 연결.표시된 글 7편 목록
관심 있는 서브레딧을 정해두면, n8n이 3시간마다 그 서브레딧의 Top·Hot·New·Rising 게시글을 모두 모아 추천수 기준을 넘는 것만 골라내고, AI가 한글로 요약해 슬랙 채널에 하나씩 올려줍니다. 이미 올라간 글은 저장해둔 목록과 대조해 다시 올라오지 않고, 서브레딧 이름만 바꾸면 다른 커뮤니티 감시로도 그대로 옮길 수 있습니다.
이 워크플로우 하나로 보여줄 수 있는 것
유튜브 키워드 알림 편이 "새 영상이 올라오면 잡아낸다"는 감시였다면, 이 편은 "이미 쌓여 있는 글 중에서 기준을 넘는 것만 골라낸다"는 감시입니다. 방향은 다르지만 둘 다 관심 있는 대상을 정해두고 조건에 맞을 때만 사람을 부르는 자동화라는 점은 같습니다. 이 워크플로우 안에는 취준생이 면접에서 풀어 설명할 수 있는 역량이 세 가지 들어 있습니다.
- 여러 데이터소스 병합 — 같은 서브레딧의 리스팅 네 종류(Top·Hot·New·Rising)를 각각 따로 가져와 하나의 스트림으로 합치는 경험(Merge 노드)
- 상태를 기억하는 자동화 — 이번에 처리한 글의 ID를 어딘가에 남겨서, 다음 실행에서 같은 글을 또 올리지 않게 만드는 경험(n8n Data Table)
- AI 반복 요약과 배치 전송 — 여러 건을 하나씩 순회하며 AI로 요약하고, 슬랙에 보내는 속도까지 조절하는 경험(SplitInBatches + Wait)
이 중 두 번째가 가장 값진 역량입니다. "새 글만 걸러낸다"는 말은 쉽지만, 실제로 구현하려면 이전 실행의 결과를 어딘가에 저장해두고 이번 실행에서 대조해야 합니다. 이 저장·대조 패턴은 "반복해서 확인하되 중복은 걸러야 하는" 모든 자동화에 그대로 쓰입니다.
배경 — 커뮤니티를 매번 들어가서 훑어보는 일
관심 있는 커뮤니티가 있으면 하루에도 몇 번씩 들어가 새 글이 있는지 훑어보게 됩니다. 인기 있는 글만 보고 싶은데 정렬 기준(최신순·인기순)을 매번 바꿔가며 확인해야 하고, 어제 본 글인지 오늘 본 글인지도 기억에 의존합니다. 이 워크플로우는 그 확인 작업을 n8n으로 옮긴 것입니다. 원본 JSON에는 active: true로 표시돼 있어 데모용으로 만들어 두고 끈 것이 아니라 실제로 3시간마다 도는 상태로 남아 있습니다.
이 워크플로우가 실제로 감시하는 서브레딧은 두 곳입니다. 워크플로우 이름과 감시 대상 설정 노드는 r/n8n만 언급하지만, JSON을 열어보면 r/notebooklm을 감시하는 노드 네 개가 나란히 붙어 있습니다. 처음 r/n8n용으로 만든 구조를 그대로 복제해 관심 서브레딧을 하나 더 추가한 흔적인데, 그만큼 이 구조가 서브레딧만 바꾸면 다른 커뮤니티에도 그대로 옮겨진다는 걸 원본 스스로 보여주는 셈입니다. 설치나 기본 노드 설명은 n8n으로 반복업무 자동화 포트폴리오 만들기에 정리돼 있으니, 이 글에서는 워크플로우 자체만 다룹니다.
구조 — Trigger / Task / Target
- Trigger — 3시간 간격 스케줄(노드 이름은 "Daily Schedule"이지만 실제 간격은 하루 한 번이 아닙니다)
- Task — 리스팅 네 종류를 서브레딧마다 가져와 하나로 합치기 → 추천수 기준으로 거르기 → 이전에 이미 처리한 글 제외하기 → AI가 한글로 요약하기
- Target — 슬랙 채널에 게시글별 메시지 전송, 이번에 보낸 글은 Data Table에 기록해 다음 실행이 참조
만들기
1. Reddit API 인증
Reddit 노드를 쓰려면 reddit.com/prefs/apps에서 앱을 만들어 client ID·secret을 받고, n8n의 Reddit OAuth2 credential에 연결해야 합니다. 2026년 8월 기준으로 검색해 확인한 바로는, Reddit이 2025년 말부터 시행한 "Responsible Builder Policy" 때문에 앱 등록과 실제 데이터 접근이 분리됐습니다. 앱 등록 자체는 여전히 즉시 되지만, 데이터 접근은 별도 승인을 거쳐야 하고 개인·비상업 목적이라도 심사에 며칠에서 몇 주가 걸리거나 반려될 수 있습니다. 승인이 나면 비상업 목적 기준 OAuth 클라이언트당 분당 100회 안팎의 무료 한도 안에서 쓸 수 있다는 게 여러 정리 자료의 공통된 설명입니다. 상업적 대량 호출은 별도 유료 플랜입니다. 승인 절차·소요 기간은 계정마다 다를 수 있으니 등록 전에 해당 페이지의 최신 안내를 직접 확인하세요.
2. Set — 서브레딧과 임계값을 한 곳에 모으기
minUpvotes (>=30)이라는 이름의 Edit Fields(Set) 노드에 subreddit(문자열, 예: n8n)과 minUpvotes(숫자, 예: 30)를 정의합니다. 뒤에 나오는 Reddit 노드와 Filter 노드가 이 값을 각각 참조합니다. 값을 노드마다 따로 적지 않고 앞쪽 Set 노드 하나에 모아두면, 서브레딧이나 기준치를 바꿀 때 이 노드 하나만 고치면 됩니다.
3. Reddit — Top / Hot / New / Rising 네 번 가져오기
원본 캔버스에는 스티키 노트로 이렇게 적혀 있습니다.
## Post Type
- Top Post
- Hot Post
- New Post
- Rising Post
레딧의 리스팅 방식은 성격이 다릅니다. New는 최신순, Hot은 점수와 게시 시간을 함께 반영하는 레딧 자체 알고리즘 순위, Top은 정해진 기간 안에서 추천수가 가장 높은 글, Rising은 최근 짧은 시간에 반응이 빠르게 붙는 글입니다. 이 워크플로우는 이 중 하나만 고르지 않고 네 가지를 각각 별도의 Reddit 노드(Filters → Category를 top/hot/new/rising 중 하나로 지정)로 가져와 뒤에서 합칩니다. Hot에는 없지만 Rising에는 잡히는 글, New에는 있지만 아직 Hot에 못 오른 글까지 놓치지 않으려는 설계입니다. 서브레딧을 하나 더 감시하려면 이 네 개 노드 세트를 통째로 복제해 subreddit 값만 바꾸면 되는데, 실제로 이 워크플로우가 r/notebooklm에 그렇게 해 뒀습니다.
4. Merge — 여덟 갈래를 한 스트림으로
Merge 노드에서 Number of Inputs를 리스팅 노드 개수만큼(이 워크플로우는 8) 지정합니다. 입력을 순서대로 이어 붙이는 기본 동작이라, Merge를 통과하면 여덟 리스트가 아이템 하나짜리 스트림으로 합쳐집니다.
5. Filter — 추천수 임계값 이상만
Filter 노드에 조건 하나를 넣습니다.
- 왼쪽 값:
{{ $json.ups }} - 연산자: Number → is greater than or equal to
- 오른쪽 값:
{{ $('minUpvotes (>=30)').first().json.minUpvotes }}
오른쪽 값을 숫자로 바로 적지 않고 2번의 Set 노드를 다시 참조한 이유는, 기준치를 한 군데서만 관리하기 위해서입니다. 다만 이 워크플로우는 두 서브레딧 모두에 같은 30이라는 기준을 그대로 적용합니다. 서브레딧마다 평소 추천수 규모가 다르다면 이 부분은 뒤에서 다시 짚습니다.
6. 중복 제거 — 같은 실행 안 중복과, 실행 사이 중복
Filter를 통과한 글은 Edit Fields(Set) 노드로 필드를 subreddit, post_id, title, upvotes, comments, url, created, contents 등으로 정리한 뒤 두 단계를 거칩니다. 먼저 Remove Duplicates 노드가 같은 실행 안에서 겹치는 항목을 지웁니다. Top과 Hot 양쪽에 동시에 걸린 글이 있으면 Merge 단계에서 두 번 들어오는데, 이 노드가 그걸 하나로 줄입니다. 그다음 If row does not exist라는 이름의 Data Table 노드가 post_id 컬럼을 기준으로, 이전 실행에서 이미 처리해 저장해둔 글인지 확인해 있으면 걸러냅니다. 같은 실행 안 중복과 실행과 실행 사이의 중복은 성격이 달라서, 이렇게 단계를 나눠 처리한 것으로 보입니다.
n8n Data Table은 별도 데이터베이스 없이 n8n 안에서 바로 만들어 쓸 수 있는 표 형태 저장소입니다. 이 워크플로우는 여기에 post_id를 포함한 컬럼들을 저장해두고, 이후 실행마다 대조합니다.
7. Limit → AI Agent — 한글로 요약하기
여기까지 걸러진 글 중 최대 10건만 AI Agent로 넘깁니다(Limit 노드, Max Items: 10). AI Agent의 Chat Model에는 Kimi(kimi-k2.5, OpenAI 호환 API)가 연결돼 있고, 시스템 메시지는 이렇게 출력 형식을 못박아 둡니다.
당신은 서브레딧의 인기 게시글을 한글로 요약하는 봇입니다.
## 출력 형식
각 게시글을 다음 형식으로 요약하되, 번역 설명이나 부가 설명 없이
오직 아래 4줄만 출력:
[이모지] [한글 번역된 제목]
👤 [작성자] | 👍 [추천수] | 💬 [댓글수] | 📅 [날짜]
📝 [본문 핵심 요약 1-2문장]
🔗 [URL]
## 카테고리별 이모지 매핑
Help → 🆘, Discussion → 💡, Tutorial → 📚, Bug Report → 🐛 …
카테고리별 이모지를 미리 정해두고 "부가 설명 없이 4줄만 출력"이라고 못박은 덕분에, AI 응답을 그대로 슬랙 메시지 본문에 붙여 넣을 수 있습니다. 별도로 후처리하는 노드가 없는 걸 보면 이 프롬프트 하나로 출력 형식을 끝까지 통제하려 한 설계로 보입니다.
8. Data Table 저장 → Loop + Wait → Slack
AI Agent를 거친 글은 다시 Insert row라는 이름의 Data Table 노드로 post_id를 포함해 기록됩니다. 이 기록이 다음 실행의 6번 단계에서 "이미 처리한 글"로 잡힙니다. 그다음 SplitInBatches 노드로 5개씩 묶고, 묶음마다 Wait로 한 박자 쉰 뒤 Slack의 Send a Message 노드로 게시글 하나당 메시지 하나씩 보냅니다. 텍스트는 🔥 *{{ $json.title }}*에 이어 AI 요약 4줄을 붙이는 형태입니다. 이전 편(뉴스 메일 편)이 여러 항목을 Aggregate로 합쳐 메일 한 통으로 보냈던 것과 달리, 이 워크플로우는 항목마다 별도 메시지로 슬랙에 쌓입니다.
원본 캔버스에 남아 있는 흔적
이름과 실제 동작이 어긋나는 부분이 몇 군데 있습니다. 첫째, 트리거 노드 이름은 "Daily Schedule"이지만 실제 간격 설정은 hours 단위로 3시간입니다. 이름만 보고 "하루 한 번 도는구나" 하고 넘기면 실제 동작과 어긋납니다. 둘째, Chat Model 자리에는 Kimi 노드가 연결돼 있는데, 캔버스에는 Upstage Solar(solar-mini) 모델 노드도 하나 더 떠 있습니다. connections를 확인해보면 이 노드는 어디에도 연결돼 있지 않습니다. 다른 모델로 먼저 테스트해보고 지금 쓰는 모델로 바꾼 흔적으로 보이는데, 지우지 않고 캔버스에 남겨둔 것입니다.
한계
- 임계값이 서브레딧마다 다르지 않습니다 — 2번의 Set 노드에서
minUpvotes를 30 하나로 고정해 두 서브레딧에 똑같이 적용합니다. 평소 추천수 규모가 다른 커뮤니티를 같이 감시하려면 서브레딧별로 값을 다르게 주는 로직이 필요합니다. - 한 번에 최대 10건까지만 요약합니다 — Limit 노드가 10건에서 끊기 때문에, 짧은 시간 안에 기준을 넘는 글이 그보다 많이 나오면 나머지는 이번 실행에서 Data Table에 기록되지 않고 남습니다. 다음 3시간 뒤 실행에서 리스팅에 여전히 잡히면 그때 처리되지만, 그사이 순위에서 밀려나면 놓칠 수 있습니다.
- 채널·저장소 설정이 캔버스에 고정돼 있습니다 — 슬랙 채널이나 Data Table은 워크플로우를 열어 직접 골라야 하고, 시트 기반 워크플로우처럼 바깥에서 설정값을 바꿀 방법은 없습니다.
포트폴리오·면접 포인트
이 워크플로우가 이미 두 서브레딧을 감시하고 있다는 사실 자체가 좋은 포트폴리오 소재입니다. 실제로 관심 있는 서브레딧으로 바꿔서 돌려보고, 위에서 짚은 한계 중 하나를 고쳐본 경험을 붙이면 "따라 만든 사람"과 "구조를 이해한 사람"이 갈립니다.
면접에서 "왜 중복 제거를 Remove Duplicates와 Data Table 두 단계로 나눴나요?"라는 질문이 나올 수 있습니다. Top·Hot·New·Rising을 합치면 같은 실행 안에서 같은 글이 여러 번 들어오는 중복이 생기고, 이건 Remove Duplicates로 그 자리에서 없앨 수 있습니다. 하지만 "어제도 올렸던 글인지"는 이번 실행의 데이터만으로 알 수 없고, 이전 실행의 기록과 대조해야 합니다. 그래서 저장소(Data Table)를 따로 두고 확인한 것입니다. 중복을 한 문제로 뭉뚱그리지 않고 원인이 다른 두 문제로 나눠 설명할 수 있으면, 구조를 제대로 이해했다는 인상을 줍니다.
다음 액션
다음 편에서는 정기적으로 오는 통계 이메일 한 통을 파싱해서 슬랙 한 줄 요약으로 바꾸는 워크플로우로 넘어갑니다. 이번 편이 "여러 건을 모아 거른다"였다면, 다음 편은 "한 통에서 필요한 숫자만 뽑아낸다"는 점이 다릅니다.
