RECIPE 003
매주 월요일 주간 일정 자동 공유
- ▸HTTP Request 노드로 외부 웹페이지를 주기적으로 가져올 수 있다
- ▸HTML Extract 노드로 원하는 요소를 추출할 수 있다
- ▸이전 값과 비교해 변경이 있을 때만 알림을 보낼 수 있다
✅사전 준비
- □모니터링할 페이지 URL과 감지할 CSS 셀렉터 확인
- □Google Sheets 자격증명 연결 완료 (이전 값 저장용)
- □Gmail 또는 Slack 자격증명 연결 완료 (알림용)
HTML Extract 노드 — CSS 셀렉터 예시
가격 추출: .price, [class*="price"]
공지사항 제목: .notice-list li:first-child
특정 텍스트 영역: #content > p:first-childCode 노드 — 이전 값과 비교
const current = $input.first().json.extractedText;
const previous = $('Google Sheets').first().json.lastValue;
if (current === previous) {
return [{ json: { changed: false } }];
}
return [{ json: { changed: true, current, previous } }];Gmail 노드 — 변경 감지 알림 제목
[변경 감지] {{ $json.url }} 페이지가 업데이트되었습니다💡 TIP동적으로 렌더링되는 사이트(React, Vue 등)는 HTTP Request만으로 내용을 가져오기 어렵습니다. 이런 경우엔 해당 사이트의 공식 API나 RSS 피드를 먼저 찾아보세요.
⚡
워크플로우 JSON
아래 JSON을 복사해 n8n에 바로 임포트하세요
📥 n8n 임포트 방법
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
{
"name": "recipe003_weekly_schedule_share",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtWeekDay": [
1
],
"triggerAtHour": 8,
"triggerAtMinute": 30
}
]
}
},
"id": "schedule-003-01",
"name": "매주 월요일 오전 8시 30분",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
200,
400
]
},
{
"parameters": {
"resource": "event",
"operation": "getAll",
"calendarId": {
"__rl": true,
"mode": "id",
"value": "primary"
},
"timeMin": "={{ $now.startOf('week').toISO() }}",
"timeMax": "={{ $now.endOf('week').toISO() }}",
"options": {
"orderBy": "startTime",
"singleEvents": true
},
"returnAll": true
},
"id": "gcal-003-02",
"name": "이번 주 일정 가져오기",
"type": "n8n-nodes-base.googleCalendar",
"typeVersion": 1.3,
"position": [
420,
400
]
},
{
"parameters": {
"jsCode": "const items = $input.all();\nconst weekStart = $now.startOf('week').setLocale('ko').toFormat('M월 d일');\nconst weekEnd = $now.endOf('week').setLocale('ko').toFormat('M월 d일');\nconst dayMap = ['일', '월', '화', '수', '목', '금', '토'];\n\nif (items.length === 0) {\n return [{ json: { message: `📅 *${weekStart} ~ ${weekEnd} 주간 일정*\\n\\n이번 주 등록된 일정이 없어요.` } }];\n}\n\nconst lines = items.map(item => {\n const ev = item.json;\n const start = ev.start?.dateTime || ev.start?.date || '';\n const dt = new Date(start);\n const day = dayMap[dt.getDay()];\n const time = ev.start?.dateTime\n ? `${String(dt.getHours()).padStart(2,'0')}:${String(dt.getMinutes()).padStart(2,'0')}`\n : '종일';\n const title = ev.summary || '(제목 없음)';\n return `• ${day}요일 ${time} — ${title}`;\n}).join('\\n');\n\nreturn [{\n json: {\n message: `🗓 *${weekStart} ~ ${weekEnd} 주간 일정*\\n\\n${lines}\\n\\n좋은 한 주 시작해요! 💪`\n }\n}];"
},
"id": "code-003-03",
"name": "주간 일정 메시지 포맷",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
640,
400
]
},
{
"parameters": {
"resource": "message",
"operation": "post",
"channel": "#weekly-schedule",
"text": "={{ $json.message }}",
"otherOptions": {}
},
"id": "slack-003-04",
"name": "Slack 주간 일정 공유",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
860,
400
]
}
],
"connections": {
"매주 월요일 오전 8시 30분": {
"main": [
[
{
"node": "이번 주 일정 가져오기",
"type": "main",
"index": 0
}
]
]
},
"이번 주 일정 가져오기": {
"main": [
[
{
"node": "주간 일정 메시지 포맷",
"type": "main",
"index": 0
}
]
]
},
"주간 일정 메시지 포맷": {
"main": [
[
{
"node": "Slack 주간 일정 공유",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"timezone": "Asia/Seoul"
},
"meta": {
"chapter": 1,
"recipe": "003",
"title": "매주 월요일 주간 일정 자동 공유",
"difficulty": "⭐",
"estimatedTime": "20분",
"apps": [
"Google Calendar",
"Slack"
],
"workflowUrl": "www.koreaaitimes.com/books/n8n-vol2/recipe003"
}
}