{"updatedAt":"2026-03-14T03:38:14.066Z","createdAt":"2026-03-13T01:51:25.806Z","id":"bfcydMHNKz8KQ045","name":"[7.1.1] 텍스트 데이터 정제","description":null,"active":true,"isArchived":false,"nodes":[{"parameters":{"path":"news","responseMode":"responseNode","options":{}},"id":"webhook1","name":"뉴스 요청","type":"n8n-nodes-base.webhook","typeVersion":2,"position":[0,304],"webhookId":"news-briefing"},{"parameters":{"url":"=https://news.google.com/rss/search?q={{ encodeURIComponent($json.query.keyword || '최신뉴스') }}&hl=ko&gl=KR&ceid=KR:ko","options":{}},"id":"rss1","name":"RSS 뉴스 수집","type":"n8n-nodes-base.rssFeedRead","typeVersion":1,"position":[240,304]},{"parameters":{"maxItems":"={{ Number($('뉴스 요청').first().json.query.count) || 5 }}"},"id":"limit1","name":"기사 수 제한","type":"n8n-nodes-base.limit","typeVersion":1,"position":[480,304]},{"parameters":{"textsWithManipulations":{"textsWithManipulationsValues":[{"dataSources":{"dataSource":[{"readOperation":"fromJSON","sourceKey":"content","destinationKey":"본문_태그제거"}]},"manipulations":{"manipulation":[{"action":"replace","replaceMode":"predefinedRule"}]}}]}},"id":"tm1","name":"HTML 태그 제거","type":"n8n-nodes-text-manipulation.textManipulation","typeVersion":1,"position":[720,304]},{"parameters":{"textsWithManipulations":{"textsWithManipulationsValues":[{"dataSources":{"dataSource":[{"readOperation":"fromJSON","sourceKey":"본문_태그제거","destinationKey":"본문_정제"}]},"manipulations":{"manipulation":[{"action":"replace","substring":"&nbsp;"},{"action":"replace","substring":"   ","value":" "},{"action":"replace","substring":"  ","value":" "},{"action":"trim"}]}}]}},"id":"tm2","name":"공백 정리","type":"n8n-nodes-text-manipulation.textManipulation","typeVersion":1,"position":[960,304]},{"parameters":{"assignments":{"assignments":[{"id":"r1","name":"제목","value":"={{ $json.title.split(' - ').slice(0, -1).join(' - ') }}","type":"string"},{"id":"r2","name":"출처","value":"={{ $json.title.split(' - ').pop() }}","type":"string"},{"id":"r3","name":"발행일","value":"={{ $json.isoDate }}","type":"string"},{"id":"r4","name":"본문","value":"={{ $json.본문_정제 }}","type":"string"},{"id":"r5","name":"URL","value":"={{ $json.link }}","type":"string"}]},"options":{}},"id":"set1","name":"정제 결과","type":"n8n-nodes-base.set","typeVersion":3.4,"position":[1200,304]},{"parameters":{"jsCode":"const items = $input.all();\nconst keyword = $('뉴스 요청').first().json.query.keyword || '최신뉴스';\nconst count = items.length;\nconst now = new Date();\nconst dateStr = now.toLocaleDateString('ko-KR', {\n  year: 'numeric', month: 'long', day: 'numeric', weekday: 'long'\n});\n\nconst cards = items.map((item, i) => {\n  const d = item.json;\n  const pubDate = new Date(d['발행일']).toLocaleDateString('ko-KR', {\n    month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit'\n  });\n  return `<div class=\"card\" data-i=\"${i}\" ${i > 0 ? 'style=\"display:none\"' : ''}>\n    <div class=\"meta\"><span class=\"badge\">${d['출처']}</span><time>${pubDate}</time></div>\n    <h2>${d['제목']}</h2>\n    <p>${d['본문']}</p>\n    <a href=\"https://www.google.com/search?q=${encodeURIComponent(d['제목'])}\" target=\"_blank\" rel=\"noopener\">원문 검색 →</a>\n  </div>`;\n}).join('\\n');\n\nconst html = `<!DOCTYPE html>\n<html lang=\"ko\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${keyword} 뉴스 브리핑</title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:-apple-system,'Noto Sans KR',sans-serif;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);min-height:100vh;display:flex;justify-content:center;padding:40px 20px}\n.wrap{max-width:620px;width:100%}\nheader{text-align:center;margin-bottom:28px;color:#fff}\nheader h1{font-size:1.7rem;font-weight:700}\nheader p{opacity:.8;margin-top:6px;font-size:.9rem}\n.card{background:#fff;border-radius:18px;padding:28px 26px;box-shadow:0 4px 24px rgba(0,0,0,.12);animation:fadeIn .35s ease}\n.card .meta{display:flex;align-items:center;gap:10px;margin-bottom:14px}\n.card .badge{background:linear-gradient(135deg,#ff6b35,#f7931e);color:#fff;padding:4px 12px;border-radius:20px;font-size:.78rem;font-weight:600}\n.card time{color:#999;font-size:.82rem}\n.card h2{font-size:1.15rem;line-height:1.7;color:#1a1a2e;margin-bottom:16px;word-break:keep-all}\n.card p{color:#555;font-size:.92rem;line-height:1.85;margin-bottom:20px;word-break:keep-all}\n.card a{color:#667eea;text-decoration:none;font-weight:600;font-size:.9rem;transition:.2s}\n.card a:hover{color:#764ba2}\n.nav{display:flex;justify-content:center;align-items:center;gap:20px;margin-top:24px}\n.nav button{width:44px;height:44px;border-radius:50%;border:none;background:rgba(255,255,255,.9);font-size:1.1rem;cursor:pointer;transition:.2s;box-shadow:0 2px 8px rgba(0,0,0,.1)}\n.nav button:hover:not(:disabled){background:#fff;transform:scale(1.1)}\n.nav button:disabled{opacity:.3;cursor:default;transform:none}\n.nav .pg{color:rgba(255,255,255,.9);font-size:.88rem}\n.nav .pg b{font-size:1.05rem}\n@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}\nfooter{text-align:center;margin-top:32px;color:rgba(255,255,255,.5);font-size:.75rem}\n</style>\n</head>\n<body>\n<div class=\"wrap\">\n<header><h1>📰 \"${keyword}\" 뉴스 브리핑</h1><p>${dateStr} · ${count}건</p></header>\n${cards}\n<nav class=\"nav\">\n<button id=\"P\" onclick=\"go(-1)\" disabled>◀</button>\n<span class=\"pg\"><b id=\"C\">1</b> / ${count}</span>\n<button id=\"N\" onclick=\"go(1)\">▶</button>\n</nav>\n<footer>Powered by n8n · Google News RSS · Text Manipulation</footer>\n</div>\n<script>\nlet c=0,t=${count};\nfunction go(d){\n  document.querySelector('[data-i=\"'+c+'\"]').style.display='none';\n  c+=d;\n  const el=document.querySelector('[data-i=\"'+c+'\"]');\n  el.style.display='block';\n  el.style.animation='none';\n  el.offsetHeight;\n  el.style.animation='fadeIn .35s ease';\n  document.getElementById('C').textContent=c+1;\n  document.getElementById('P').disabled=c===0;\n  document.getElementById('N').disabled=c===t-1;\n}\n</script>\n</body></html>`;\n\nreturn [{json:{html}}];"},"id":"code1","name":"HTML 페이지 생성","type":"n8n-nodes-base.code","typeVersion":2,"position":[1440,304]},{"parameters":{"respondWith":"text","responseBody":"={{ $json.html }}","options":{"responseHeaders":{"entries":[{"name":"Content-Type","value":"text/html; charset=utf-8"}]}}},"id":"respond1","name":"뉴스 페이지 응답","type":"n8n-nodes-base.respondToWebhook","typeVersion":1.1,"position":[1680,304]}],"connections":{"뉴스 요청":{"main":[[{"node":"RSS 뉴스 수집","type":"main","index":0}]]},"RSS 뉴스 수집":{"main":[[{"node":"기사 수 제한","type":"main","index":0}]]},"기사 수 제한":{"main":[[{"node":"HTML 태그 제거","type":"main","index":0}]]},"HTML 태그 제거":{"main":[[{"node":"공백 정리","type":"main","index":0}]]},"공백 정리":{"main":[[{"node":"정제 결과","type":"main","index":0}]]},"정제 결과":{"main":[[{"node":"HTML 페이지 생성","type":"main","index":0}]]},"HTML 페이지 생성":{"main":[[{"node":"뉴스 페이지 응답","type":"main","index":0}]]}},"settings":{"executionOrder":"v1","saveDataErrorExecution":"all","saveDataSuccessExecution":"all","saveManualExecutions":true,"saveExecutionProgress":true,"callerPolicy":"workflowsFromSameOwner","availableInMCP":false},"staticData":null,"meta":null,"pinData":{},"versionId":"3baf0c9b-a6de-4edf-bbab-4bd4cd69234a","activeVersionId":"3dd2962e-497b-4885-a9db-be13bec05a55","versionCounter":54,"triggerCount":1,"shared":[{"updatedAt":"2026-03-13T01:51:25.809Z","createdAt":"2026-03-13T01:51:25.809Z","role":"workflow:owner","workflowId":"bfcydMHNKz8KQ045","projectId":"HOjkcE7iYuEpXRNR","project":{"updatedAt":"2025-11-24T05:13:19.424Z","createdAt":"2025-09-19T06:56:46.826Z","id":"HOjkcE7iYuEpXRNR","name":"Dante Kwak <dantelabs.pro@gmail.com>","type":"personal","icon":null,"description":null,"creatorId":"102ca187-1fa0-4d33-a606-5a0bb96a0fe3"}}],"tags":[],"activeVersion":{"updatedAt":"2026-03-13T12:16:27.130Z","createdAt":"2026-03-13T12:16:27.130Z","versionId":"3dd2962e-497b-4885-a9db-be13bec05a55","workflowId":"bfcydMHNKz8KQ045","nodes":[{"id":"webhook1","name":"뉴스 요청","type":"n8n-nodes-base.webhook","typeVersion":2,"position":[0,304],"parameters":{"httpMethod":"GET","path":"news","responseMode":"responseNode","options":{}},"webhookId":"news-briefing"},{"id":"rss1","name":"RSS 뉴스 수집","type":"n8n-nodes-base.rssFeedRead","typeVersion":1,"position":[240,304],"parameters":{"url":"=https://news.google.com/rss/search?q={{ encodeURIComponent($json.query.keyword || '최신뉴스') }}&hl=ko&gl=KR&ceid=KR:ko","options":{}}},{"id":"limit1","name":"기사 수 제한","type":"n8n-nodes-base.limit","typeVersion":1,"position":[480,304],"parameters":{"maxItems":"={{ Number($('뉴스 요청').first().json.query.count) || 5 }}"}},{"id":"tm1","name":"HTML 태그 제거","type":"n8n-nodes-text-manipulation.textManipulation","typeVersion":1,"position":[720,304],"parameters":{"textsWithManipulations":{"textsWithManipulationsValues":[{"dataSources":{"dataSource":[{"readOperation":"fromJSON","sourceKey":"content","writeOperation":"toJSON","destinationKey":"본문_태그제거"}]},"manipulations":{"manipulation":[{"action":"replace","replaceMode":"predefinedRule","predefinedRule":"tags"}]}}]}}},{"id":"tm2","name":"공백 정리","type":"n8n-nodes-text-manipulation.textManipulation","typeVersion":1,"position":[960,304],"parameters":{"textsWithManipulations":{"textsWithManipulationsValues":[{"dataSources":{"dataSource":[{"readOperation":"fromJSON","sourceKey":"본문_태그제거","writeOperation":"toJSON","destinationKey":"본문_정제"}]},"manipulations":{"manipulation":[{"action":"replace","replaceMode":"substring","substring":"&nbsp;","value":"","replaceAll":true},{"action":"replace","replaceMode":"substring","substring":"   ","value":" ","replaceAll":true},{"action":"replace","replaceMode":"substring","substring":"  ","value":" ","replaceAll":true},{"action":"trim","trimType":"both"}]}}]}}},{"id":"set1","name":"정제 결과","type":"n8n-nodes-base.set","typeVersion":3.4,"position":[1200,304],"parameters":{"assignments":{"assignments":[{"id":"r1","name":"제목","value":"={{ $json.title.split(' - ').slice(0, -1).join(' - ') }}","type":"string"},{"id":"r2","name":"출처","value":"={{ $json.title.split(' - ').pop() }}","type":"string"},{"id":"r3","name":"발행일","value":"={{ $json.isoDate }}","type":"string"},{"id":"r4","name":"본문","value":"={{ $json.본문_정제 }}","type":"string"},{"id":"r5","name":"URL","value":"={{ $json.link }}","type":"string"}]},"options":{}}},{"id":"code1","name":"HTML 페이지 생성","type":"n8n-nodes-base.code","typeVersion":2,"position":[1440,304],"parameters":{"jsCode":"const items = $input.all();\nconst keyword = $('뉴스 요청').first().json.query.keyword || '최신뉴스';\nconst count = items.length;\nconst now = new Date();\nconst dateStr = now.toLocaleDateString('ko-KR', {\n  year: 'numeric', month: 'long', day: 'numeric', weekday: 'long'\n});\n\nconst cards = items.map((item, i) => {\n  const d = item.json;\n  const pubDate = new Date(d['발행일']).toLocaleDateString('ko-KR', {\n    month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit'\n  });\n  return `<div class=\"card\" data-i=\"${i}\" ${i > 0 ? 'style=\"display:none\"' : ''}>\n    <div class=\"meta\"><span class=\"badge\">${d['출처']}</span><time>${pubDate}</time></div>\n    <h2>${d['제목']}</h2>\n    <p>${d['본문']}</p>\n    <a href=\"https://www.google.com/search?q=${encodeURIComponent(d['제목'])}\" target=\"_blank\" rel=\"noopener\">원문 검색 →</a>\n  </div>`;\n}).join('\\n');\n\nconst html = `<!DOCTYPE html>\n<html lang=\"ko\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${keyword} 뉴스 브리핑</title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:-apple-system,'Noto Sans KR',sans-serif;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);min-height:100vh;display:flex;justify-content:center;padding:40px 20px}\n.wrap{max-width:620px;width:100%}\nheader{text-align:center;margin-bottom:28px;color:#fff}\nheader h1{font-size:1.7rem;font-weight:700}\nheader p{opacity:.8;margin-top:6px;font-size:.9rem}\n.card{background:#fff;border-radius:18px;padding:28px 26px;box-shadow:0 4px 24px rgba(0,0,0,.12);animation:fadeIn .35s ease}\n.card .meta{display:flex;align-items:center;gap:10px;margin-bottom:14px}\n.card .badge{background:linear-gradient(135deg,#ff6b35,#f7931e);color:#fff;padding:4px 12px;border-radius:20px;font-size:.78rem;font-weight:600}\n.card time{color:#999;font-size:.82rem}\n.card h2{font-size:1.15rem;line-height:1.7;color:#1a1a2e;margin-bottom:16px;word-break:keep-all}\n.card p{color:#555;font-size:.92rem;line-height:1.85;margin-bottom:20px;word-break:keep-all}\n.card a{color:#667eea;text-decoration:none;font-weight:600;font-size:.9rem;transition:.2s}\n.card a:hover{color:#764ba2}\n.nav{display:flex;justify-content:center;align-items:center;gap:20px;margin-top:24px}\n.nav button{width:44px;height:44px;border-radius:50%;border:none;background:rgba(255,255,255,.9);font-size:1.1rem;cursor:pointer;transition:.2s;box-shadow:0 2px 8px rgba(0,0,0,.1)}\n.nav button:hover:not(:disabled){background:#fff;transform:scale(1.1)}\n.nav button:disabled{opacity:.3;cursor:default;transform:none}\n.nav .pg{color:rgba(255,255,255,.9);font-size:.88rem}\n.nav .pg b{font-size:1.05rem}\n@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}\nfooter{text-align:center;margin-top:32px;color:rgba(255,255,255,.5);font-size:.75rem}\n</style>\n</head>\n<body>\n<div class=\"wrap\">\n<header><h1>📰 \"${keyword}\" 뉴스 브리핑</h1><p>${dateStr} · ${count}건</p></header>\n${cards}\n<nav class=\"nav\">\n<button id=\"P\" onclick=\"go(-1)\" disabled>◀</button>\n<span class=\"pg\"><b id=\"C\">1</b> / ${count}</span>\n<button id=\"N\" onclick=\"go(1)\">▶</button>\n</nav>\n<footer>Powered by n8n · Google News RSS · Text Manipulation</footer>\n</div>\n<script>\nlet c=0,t=${count};\nfunction go(d){\n  document.querySelector('[data-i=\"'+c+'\"]').style.display='none';\n  c+=d;\n  const el=document.querySelector('[data-i=\"'+c+'\"]');\n  el.style.display='block';\n  el.style.animation='none';\n  el.offsetHeight;\n  el.style.animation='fadeIn .35s ease';\n  document.getElementById('C').textContent=c+1;\n  document.getElementById('P').disabled=c===0;\n  document.getElementById('N').disabled=c===t-1;\n}\n</script>\n</body></html>`;\n\nreturn [{json:{html}}];"}},{"id":"respond1","name":"뉴스 페이지 응답","type":"n8n-nodes-base.respondToWebhook","typeVersion":1.1,"position":[1680,304],"parameters":{"respondWith":"text","responseBody":"={{ $json.html }}","options":{"responseHeaders":{"entries":[{"name":"Content-Type","value":"text/html; charset=utf-8"}]}}}}],"connections":{"뉴스 요청":{"main":[[{"node":"RSS 뉴스 수집","type":"main","index":0}]]},"RSS 뉴스 수집":{"main":[[{"node":"기사 수 제한","type":"main","index":0}]]},"기사 수 제한":{"main":[[{"node":"HTML 태그 제거","type":"main","index":0}]]},"HTML 태그 제거":{"main":[[{"node":"공백 정리","type":"main","index":0}]]},"공백 정리":{"main":[[{"node":"정제 결과","type":"main","index":0}]]},"정제 결과":{"main":[[{"node":"HTML 페이지 생성","type":"main","index":0}]]},"HTML 페이지 생성":{"main":[[{"node":"뉴스 페이지 응답","type":"main","index":0}]]}},"authors":"Dante Kwak","name":null,"description":null,"autosaved":false,"workflowPublishHistory":[{"createdAt":"2026-03-13T12:16:27.179Z","id":181,"workflowId":"bfcydMHNKz8KQ045","versionId":"3dd2962e-497b-4885-a9db-be13bec05a55","event":"activated","userId":"102ca187-1fa0-4d33-a606-5a0bb96a0fe3"},{"createdAt":"2026-03-13T12:16:27.166Z","id":180,"workflowId":"bfcydMHNKz8KQ045","versionId":"3dd2962e-497b-4885-a9db-be13bec05a55","event":"deactivated","userId":"102ca187-1fa0-4d33-a606-5a0bb96a0fe3"}]}}