RECIPE 042
FAQ 키워드 매칭 → 자동 답변 발송
- ▸긴 문서(PDF, Docs, 텍스트)를 OpenAI로 자동 요약할 수 있다
- ▸문서 길이에 따라 청크(chunk) 분할 처리를 할 수 있다
- ▸요약 결과를 1페이지 브리핑 형식으로 Notion 또는 이메일로 발송할 수 있다
✅사전 준비
- □OpenAI API 자격증명 연결 완료
- □요약 소스 결정 (Google Drive PDF / Notion 페이지 / Webhook 텍스트 수신)
- □Notion 또는 Gmail 자격증명 연결 완료 (결과 저장용)
텍스트 청크 분할 — Code 노드
const text = $input.first().json.content ?? '';
const chunkSize = 3000; // 토큰 절약을 위해 3000자씩
const chunks = [];
for (let i = 0; i < text.length; i += chunkSize) {
chunks.push(text.slice(i, i + chunkSize));
}
return chunks.map((chunk, idx) => ({
json: { chunk, index: idx, total: chunks.length }
}));청크별 요약 — OpenAI 프롬프트
Model: gpt-4o-mini
Prompt:
다음 텍스트(전체 {{ $json.total }}개 파트 중 {{ $json.index + 1 }}번째)의
핵심 내용을 3~5줄로 한국어 요약해줘.
텍스트:
{{ $json.chunk }}청크 요약 합치기 — Code 노드
const summaries = $input.all().map(i => i.json.message.content);
const combined = summaries.join('\n\n');
return [{ json: {
partialSummaries: combined,
chunkCount: summaries.length,
} }];최종 1페이지 브리핑 — OpenAI 프롬프트
Model: gpt-4o
Prompt:
다음은 긴 문서의 파트별 요약입니다.
이를 바탕으로 경영진이 읽을 1페이지 브리핑 보고서를 작성해줘.
형식:
## 핵심 요약 (3줄)
## 주요 내용
## 시사점 및 액션아이템
파트별 요약:
{{ $json.partialSummaries }}💡 TIPgpt-4o의 컨텍스트 윈도우는 128K 토큰입니다. 문서가 10만자 이하라면 청크 분할 없이 한 번에 보내는 것이 더 품질이 좋습니다. 청크 분할은 그보다 긴 문서에만 적용하세요.
⚡
워크플로우 JSON
아래 JSON을 복사해 n8n에 바로 임포트하세요
📥 n8n 임포트 방법
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
{
"recipeId": "recipe042",
"title": "FAQ 키워드 매칭 → 자동 답변 발송",
"chapter": 4,
"category": "고객 응대 자동화",
"difficulty": "⭐⭐",
"estimatedTime": "30분",
"description": "이메일 내용과 구글 시트 FAQ 키워드를 대조하여 매칭되면 자동 답변을 발송하고, 매칭되지 않으면 담당자에게 수동 답변 필요 알림을 보냅니다.",
"apps": [
"Gmail",
"Google Sheets",
"Slack"
],
"nodes": [
{
"id": "trigger_gmail",
"type": "trigger",
"name": "Gmail Trigger - 새 문의 이메일 감지",
"service": "gmail",
"config": {
"event": "newEmail",
"filter": {
"to": "={{ $env.SUPPORT_EMAIL }}"
}
}
},
{
"id": "sheets_faq",
"type": "action",
"name": "Google Sheets - FAQ 목록 읽기",
"service": "googleSheets",
"config": {
"operation": "readAllRows",
"documentId": "={{ $env.FAQ_SHEET_ID }}",
"sheetName": "FAQ"
}
},
{
"id": "function_match",
"type": "function",
"name": "Function - 키워드 매칭",
"code": "const emailText = $node['trigger_gmail'].json['text'];\nconst faqList = $input.all();\nconst matched = faqList.find(row =>\n row.json['키워드'].split(',').some(kw => emailText.includes(kw.trim()))\n);\nreturn [{ json: { matched: !!matched, answer: matched ? matched.json['답변'] : null, emailFrom: $node['trigger_gmail'].json['from'] } }];"
},
{
"id": "if_matched",
"type": "condition",
"name": "키워드 매칭 여부",
"config": {
"conditions": [
{
"field": "={{ $json[\"matched\"] }}",
"operator": "equals",
"value": true
}
]
}
},
{
"id": "gmail_auto_reply",
"type": "action",
"name": "Gmail - 자동 답변 발송",
"service": "gmail",
"config": {
"to": "={{ $json[\"emailFrom\"] }}",
"subject": "Re: 문의 주셔서 감사합니다",
"body": "안녕하세요!\n\n문의해 주신 내용에 대한 답변입니다.\n\n{{ $json[\"answer\"] }}\n\n추가 문의사항이 있으시면 언제든지 연락 주세요.\n감사합니다."
}
},
{
"id": "slack_manual",
"type": "action",
"name": "Slack - 수동 답변 필요 알림",
"service": "slack",
"config": {
"channel": "={{ $env.SLACK_CS_CHANNEL }}",
"message": "📨 수동 답변이 필요한 이메일이 있어요!\n발신: {{ $json[\"emailFrom\"] }}\n→ FAQ에서 매칭되지 않은 문의입니다."
}
}
],
"connections": [
{
"from": "trigger_gmail",
"to": "sheets_faq"
},
{
"from": "sheets_faq",
"to": "function_match"
},
{
"from": "function_match",
"to": "if_matched"
},
{
"from": "if_matched",
"to": "gmail_auto_reply",
"branch": "true"
},
{
"from": "if_matched",
"to": "slack_manual",
"branch": "false"
}
],
"envVars": [
{
"key": "SUPPORT_EMAIL",
"description": "고객 응대 전용 이메일 주소"
},
{
"key": "FAQ_SHEET_ID",
"description": "FAQ 구글 시트 ID"
},
{
"key": "SLACK_CS_CHANNEL",
"description": "CS팀 Slack 채널 ID"
}
],
"qrCodeUrl": "https://www.koreaaitimes.com/books/n8n-vol2/recipe042"
}