
매일 아침 눈뜨자마자 RSS 리더 앱을 열어 밤새 쌓인 글 목록을 훑어보는 일, 반복하다 보면 지쳐요. 관심 가는 주제는 몇 줄이면 충분한데, 그걸 골라내는 시간이 매번 들어요. 이 글은 RSS 피드를 매일 아침 8시에 읽어 최근 24시간 글만 골라 AI가 요약하고, 디스코드 채널로 보내는 n8n 워크플로 하나를 처음부터 끝까지 다뤄요.
완성하면 매일 아침 8시, 디스코드 채널에 그날의 브리핑 메시지가 하나 도착해요. 구독한 RSS 피드 중 최근 24시간 안에 올라온 글만 AI가 3~6줄로 정리한 내용이고, 새로 올라온 글이 없는 날은 그렇다고 알려주는 메시지가 와요. RSS 리더를 열어 훑어보는 대신, 디스코드 알림 하나만 확인하면 돼요.
흐름 한눈에 보기
매일 아침 실행 → 설정 → 피드 하나씩 나누기 → RSS 읽기 → 최근 글만 고르기 → AI 요약(+ Gemini 모델) → 디스코드로 보내기
매일 아침 실행: 스케줄 트리거가 매일 오전 8시에 워크플로를 깨워요.설정: RSS 주소 목록, 디스코드 웹훅 주소, 확인할 시간 범위(기본 24시간), 최대 건수(기본 12건)를 한 곳에 모아둬요.피드 하나씩 나누기: Code 노드가 설정에 적어둔 RSS 주소 배열을 낱개 아이템으로 쪼개요.RSS 읽기: RSS Feed Read 노드가 각 주소에서 글 목록을 가져와요.최근 글만 고르기: Code 노드가 지정한 시간이 지난 글과 중복 링크를 걸러내고 최신순으로 정렬해요.AI 요약(+Gemini 모델): AI 에이전트 노드가 목록을 받아 연결된 Gemini 모델로 3~6줄 브리핑을 만들어요.디스코드로 보내기: HTTP Request 노드가 완성된 브리핑을 디스코드 웹훅 주소로 POST 요청해요.

준비물
- n8n(클라우드 또는 셀프호스팅): 워크플로를 실제로 실행하는 도구 자체예요. n8n 클라우드에 가입하거나 직접 서버에 설치해두면 준비가 끝나요.
- Google AI Studio의 Gemini API 키:
Gemini 모델노드가 이 키로 인증해서 요약을 만들어요. 무료로 발급받을 수 있고, 발급 절차나 한도는 바뀔 수 있으니 발급 화면에서 직접 확인하는 게 안전해요. - 디스코드 웹훅 주소: 완성된 브리핑을 보낼 채널을 정하는 값이에요. 봇을 만들거나 서버에 초대할 필요 없이, 채널 설정에서 주소 하나만 복사하면 돼요.
설치하기
- 아래 '워크플로 JSON' 절의 내용을 복사해서 n8n 캔버스에 붙여넣어요. 노드와 색깔 있는 스티키 노트 4개가 나타나면 성공이에요.
설정노드를 열어rssUrls(구독할 RSS 주소),discordWebhookUrl(디스코드 웹훅 주소),hoursBack(몇 시간 이내 글만 볼지),maxItems(최대 요약 건수) 네 값을 채워요. 저장했을 때 오류 표시가 뜨지 않으면 잘 채운 거예요.Gemini 모델노드를 클릭해 Credential에서 Google Gemini(PaLM) API 키를 새로 등록해요. 노드 테두리의 느낌표 표시가 사라지면 연결된 거예요.- 우측 상단 테스트 실행 버튼을 눌러 전체 흐름을 돌려요.
디스코드로 보내기노드까지 초록 체크가 뜨고 채널에 브리핑이 도착하면 성공이에요. - 활성화 토글을 켜요. 토글이 초록색으로 바뀌면 매일 아침 8시에 자동으로 실행돼요.
워크플로 JSON
아래 JSON을 통째로 복사해서 n8n 캔버스에 붙여넣으세요. 노드 사이사이 스티키 노트에 한국어 설치 안내가 같이 들어 있어서, 캔버스 안에서 바로 확인할 수 있어요.
{
"id": "dailyRssAiDiscord01",
"name": "매일 아침 RSS → AI 요약 → 디스코드",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 8
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
-620,
0
],
"id": "f2ea1d32-dea3-4d8e-ac3c-32401fa66bcd",
"name": "매일 아침 실행"
},
{
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "451b5ed6-527c-49d7-a002-fa9a12ded4b7",
"name": "rssUrls",
"type": "array",
"value": "=[\n 'https://feeds.bbci.co.uk/news/technology/rss.xml',\n 'https://techcrunch.com/feed/'\n]"
},
{
"id": "323b4ce1-06db-4964-a7d4-46b4f330f68f",
"name": "discordWebhookUrl",
"type": "string",
"value": "https://discord.com/api/webhooks/여기에_본인_웹훅_주소를_붙여넣으세요"
},
{
"id": "8857c0d2-51c6-441d-86b9-aba493442ef3",
"name": "hoursBack",
"type": "number",
"value": "=24"
},
{
"id": "e9435eda-30c4-40d4-a35a-0834392e27f6",
"name": "maxItems",
"type": "number",
"value": "=12"
}
]
}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-400,
0
],
"id": "3908511d-bc10-4abe-a90f-8ec066ede8fa",
"name": "설정"
},
{
"parameters": {
"jsCode": "// 설정에 적어둔 RSS 주소를 하나씩 나눠서 다음 노드로 넘깁니다.\nconst urls = $json.rssUrls || [];\nif (!urls.length) {\n throw new Error('설정 노드의 rssUrls 가 비어 있습니다. RSS 주소를 1개 이상 넣어주세요.');\n}\nreturn urls.map((u) => ({ json: { url: u } }));"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-180,
0
],
"id": "f3fb905d-f6ac-4cee-a391-d11ced9e0be1",
"name": "피드 하나씩 나누기"
},
{
"parameters": {
"url": "={{ $json.url }}",
"options": {}
},
"type": "n8n-nodes-base.rssFeedRead",
"typeVersion": 1.2,
"position": [
40,
0
],
"id": "a04ab5cf-139d-4890-b8f2-1cbfb2fee85a",
"name": "RSS 읽기"
},
{
"parameters": {
"jsCode": "// 여러 피드에서 온 글을 모아 최근 것만 고르고, 중복을 지우고, 목록 텍스트로 만듭니다.\nlet cfg = {};\ntry { cfg = $('설정').first().json; } catch (e) { /* 노드 이름이 바뀌면 아래 기본값 사용 */ }\nconst hoursBack = Number(cfg.hoursBack) || 24;\nconst maxItems = Number(cfg.maxItems) || 12;\nconst cutoff = Date.now() - hoursBack * 60 * 60 * 1000;\n\nconst seen = new Set();\nconst picked = [];\n\nfor (const item of $input.all()) {\n const j = item.json || {};\n const title = String(j.title || '').trim();\n const link = String(j.link || '').trim();\n if (!title || !link || seen.has(link)) continue;\n\n // 피드마다 날짜 필드 이름이 달라서 순서대로 확인합니다.\n const raw = j.isoDate || j.pubDate || j.date || '';\n const t = raw ? new Date(raw).getTime() : NaN;\n // 날짜를 못 읽는 피드는 버리지 않고 남깁니다(정렬만 뒤로).\n if (!Number.isNaN(t) && t < cutoff) continue;\n\n seen.add(link);\n picked.push({ title, link, t: Number.isNaN(t) ? 0 : t });\n}\n\npicked.sort((a, b) => b.t - a.t);\nconst top = picked.slice(0, maxItems);\n\nconst list = top.length\n ? top.map((a, i) => `${i + 1}. ${a.title}\\n${a.link}`).join('\\n')\n : `(최근 ${hoursBack}시간 안에 새 글이 없습니다)`;\n\nreturn [{ json: { count: top.length, hoursBack, list } }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
260,
0
],
"id": "afcacaa5-8ed2-4174-b47d-a39fc746adf0",
"name": "최근 글만 고르기"
},
{
"parameters": {
"text": "=아래는 최근 {{ $json.hoursBack }}시간 동안 올라온 글 {{ $json.count }}건입니다. 아침 브리핑으로 정리해 주세요.\n\n{{ $json.list }}",
"options": {
"systemMessage": "너는 한국어 뉴스 브리핑 편집자다. 아래 규칙을 지켜라.\n\n- 받은 글 목록만 근거로 쓴다. 목록에 없는 내용을 지어내지 않는다.\n- 제목만 보고 알 수 없는 세부 내용은 단정하지 않는다.\n- 비슷한 주제는 묶어서 한 줄로 정리한다.\n- 전체 3~6줄. 각 줄은 \"• \" 로 시작한다.\n- 맨 끝에 \"오늘 눈에 띄는 것: ...\" 한 줄을 덧붙인다.\n- 목록이 비어 있으면 \"새로 올라온 글이 없습니다.\" 한 줄만 답한다."
},
"promptType": "define"
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.9,
"position": [
480,
0
],
"id": "94362b7e-f38b-4f2a-844b-f6076cde235b",
"name": "AI 요약"
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
500,
220
],
"id": "4a8829fa-1ed9-410d-9f30-bc9ae5320ea2",
"name": "Gemini 모델"
},
{
"parameters": {
"method": "POST",
"url": "={{ $('설정').first().json.discordWebhookUrl }}",
"sendBody": true,
"contentType": "json",
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ content: \"**오늘의 브리핑** (\" + $now.toFormat('yyyy-MM-dd') + \")\\n\\n\" + $json.output.slice(0, 1800) }) }}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
760,
0
],
"id": "2e8cbab5-b86d-4a04-ac14-cdd73cebcaa7",
"name": "디스코드로 보내기"
},
{
"parameters": {
"color": 4,
"width": 460,
"height": 280,
"content": "## 이 워크플로가 하는 일\n\n매일 아침 8시에 RSS 주소들을 읽어서,\n최근 24시간 글만 골라 AI가 요약하고,\n디스코드 채널로 보냅니다.\n\n**바꿔야 하는 건 `설정` 노드 하나뿐입니다.**\n나머지는 그대로 두면 됩니다."
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-660,
-320
],
"id": "a044c048-f86a-45a5-9381-08fc7100ac6a",
"name": "설명1"
},
{
"parameters": {
"color": 3,
"width": 380,
"height": 280,
"content": "## 1) 설정 노드 채우기\n\n- **rssUrls**: 구독할 RSS 주소 (여러 개 가능)\n- **discordWebhookUrl**: 디스코드 웹훅 주소\n- **hoursBack**: 몇 시간 이내 글만 볼지\n- **maxItems**: 최대 몇 건까지 요약할지\n\n실행 시각은 `매일 아침 실행` 노드에서 바꿉니다."
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-420,
-320
],
"id": "68a13e10-538a-4ff6-bd7d-a87077c50531",
"name": "설명2"
},
{
"parameters": {
"color": 5,
"width": 420,
"height": 260,
"content": "## 2) Gemini 자격증명 연결\n\n`Gemini 모델` 노드를 클릭 →\nCredential 에서 Google Gemini(PaLM) API 키를 등록하세요.\n\nAPI 키는 Google AI Studio 에서 무료로 발급받을 수 있습니다.\n(무료 한도·정책은 바뀔 수 있으니 발급 화면에서 확인하세요)"
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
460,
400
],
"id": "6296aee2-e064-4ea0-a9f1-ef2e3300e1a8",
"name": "설명3"
},
{
"parameters": {
"color": 6,
"width": 380,
"height": 280,
"content": "## 3) 디스코드 웹훅 만들기\n\n디스코드 채널 → 채널 편집 → 연동 →\n웹후크 → 새 웹후크 → URL 복사\n\n복사한 주소를 `설정` 노드의\n**discordWebhookUrl** 에 붙여넣으세요.\n\n봇 초대나 OAuth 설정은 필요 없습니다."
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
740,
-320
],
"id": "a3f6cd96-2966-4a4b-b5a4-bb716f1b99dc",
"name": "설명4"
}
],
"connections": {
"매일 아침 실행": {
"main": [
[
{
"node": "설정",
"type": "main",
"index": 0
}
]
]
},
"설정": {
"main": [
[
{
"node": "피드 하나씩 나누기",
"type": "main",
"index": 0
}
]
]
},
"피드 하나씩 나누기": {
"main": [
[
{
"node": "RSS 읽기",
"type": "main",
"index": 0
}
]
]
},
"RSS 읽기": {
"main": [
[
{
"node": "최근 글만 고르기",
"type": "main",
"index": 0
}
]
]
},
"최근 글만 고르기": {
"main": [
[
{
"node": "AI 요약",
"type": "main",
"index": 0
}
]
]
},
"AI 요약": {
"main": [
[
{
"node": "디스코드로 보내기",
"type": "main",
"index": 0
}
]
]
},
"Gemini 모델": {
"ai_languageModel": [
[
{
"node": "AI 요약",
"type": "ai_languageModel",
"index": 0
}
]
]
}
},
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "e561ced3-e99e-4be1-9ef8-0589ac4094a5",
"meta": {
"templateCredsSetupCompleted": false
},
"tags": []
}
이렇게 바꿔 쓸 수 있어요
- 피드 바꾸기:
설정노드의rssUrls배열에 원하는 RSS 주소를 추가하거나 빼면 돼요. - 시간 바꾸기:
매일 아침 실행노드의 시각을 바꾸고,설정노드의hoursBack도 그 주기에 맞게 같이 조정해요. - 슬랙으로 보내기:
디스코드로 보내기노드를 슬랙 웹훅 URL로 바꾸면 같은 구조로 슬랙에도 보낼 수 있어요. 참고한 n8n 공식 템플릿도 슬랙으로 보내는 버전이에요.
주의할 점
이 JSON은 실제 n8n-nodes-base·langchain 2.31.4(2026-07-27 npm 설치 기준)에 임포트해서 노드 12개, 연결 7개가 그대로 들어가는 것까지 확인했어요. 다만 확인한 범위와 확인하지 않은 부분은 나눠서 밝힐게요.
- 임포트 ≠ 작동:
설정노드의 Gemini 키와 웹훅 주소는 붙여넣는다고 채워지지 않아요. 직접 넣어야 실제로 돌아가요. - 며칠 돌려본 워크플로는 아니에요: 확인한 건 구조가 온전하다는 것까지고, 매일 아침 실제로 잘 도는지는 활성화한 뒤 직접 지켜봐야 해요.
- 디스코드 노드 대신 웹훅을 쓴 이유: 참고한 디스코드로 AI 요약을 보내는 공식 템플릿은 OAuth2 인증이 필요한 Discord 노드를 쓰지만, 봇 생성과 서버 초대가 번거로워 웹훅 방식으로 바꿨어요.
- Gemini 무료 한도는 단정하지 않을게요: 무료로 발급받을 수 있다는 것까지만 확인했고, 구체적인 한도나 정책은 바뀔 수 있어서 발급 화면에서 직접 확인해야 해요.
- 다른 n8n 버전을 쓴다면: 이 글은 2.31.4 기준이라, 다른 버전에서는 노드 화면이나 파라미터 위치가 다를 수 있어요.
이 워크플로는 매일 아침 브리핑 하나를 자동으로 만드는 데까지예요. 다음 편에서는 조건 분기를 더해 특정 키워드가 포함된 글만 골라내는 방법을 다룰 계획이에요.
2026-08-01 작성 · 사실 확인이 안 된 항목은 본문에 그렇게 표시했습니다.