Gmail→GPT→Supabase 작업 추출기
이것은Personal Productivity, AI Summarization분야의자동화 워크플로우로, 9개의 노드를 포함합니다.주로 If, Code, Gmail, Supabase, HttpRequest 등의 노드를 사용하며. Gmail、ChatGPT-4o와 Supabase를 사용하여 이메일 작업을 추출
- •Google 계정 및 Gmail API 인증 정보
- •Supabase URL과 API Key
- •대상 API의 인증 정보가 필요할 수 있음
- •OpenAI API Key
{
"id": "8mU5BDEPNPCBrcNG",
"meta": {
"instanceId": "05cd306a73f97150c796adf49d28dcc97084b722b0b212b8c228ea8b71d87571",
"templateCredsSetupCompleted": true
},
"name": "Gmail → GPT → Supabase | Task Extractor",
"tags": [],
"nodes": [
{
"id": "60d16e90-4a70-4aca-9643-997141a65cdf",
"name": "워크플로우 트리거",
"type": "n8n-nodes-base.scheduleTrigger",
"notes": "Runs the workflow on a schedule (every X minutes) to check for new unread emails.",
"position": [
-580,
-430
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes"
}
]
}
},
"notesInFlow": true,
"typeVersion": 1.2
},
{
"id": "501a117f-93ff-43e9-8a49-5f0c58c4e496",
"name": "ChatGPT 프롬프트 준비",
"type": "n8n-nodes-base.code",
"notes": "Formats the email content into a prompt for GPT, asking it to extract a structured task in JSON format.",
"position": [
520,
-580
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "return {\n prompt: `You are an AI productivity assistant. Given the email below, extract any actionable task(s). Respond in this format:\n {\n \"task\": \"Brief title of the task\",\n \"description\": \"Expanded detail if needed\",\n \"due_date\": \"2025-07-01\" or null,\n \"estimated_minutes\": 30,\n \"deep_work\": true\n }\n If no actionable task exists, respond with null.\\n\\nEmail:\\n${$('Loop Over Items').item.json.snippet}`\n};\n"
},
"executeOnce": false,
"notesInFlow": true,
"typeVersion": 2,
"alwaysOutputData": true
},
{
"id": "cec2c062-7333-499a-b5c3-5f7831022d34",
"name": "이메일에서 작업 세부사항 추출",
"type": "@n8n/n8n-nodes-langchain.openAi",
"notes": "Sends the email to ChatGPT-4o to extract task details like title, description, due date, duration, and focus level.",
"position": [
740,
-580
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "chatgpt-4o-latest",
"cachedResultName": "CHATGPT-4O-LATEST"
},
"options": {},
"messages": {
"values": [
{
"content": "={{ $json.prompt }}"
}
]
},
"jsonOutput": true
},
"notesInFlow": true,
"typeVersion": 1.8
},
{
"id": "d708c9c3-d5ec-4b2a-8f8a-b5b123fa44ea",
"name": "Supabase에 이메일 세부사항 삽입",
"type": "n8n-nodes-base.httpRequest",
"notes": "Inserts the processed email and GPT-extracted task into the Supabase emails table. Uses upsert to avoid duplicates.",
"position": [
1116,
-505
],
"parameters": {
"url": "={{ $vars.Supabase_TaskManagement_URI + '/rest/v1/emails?on_conflict=email_id' }}",
"method": "POST",
"options": {},
"jsonBody": "={\n \"email_id\": {{ JSON.stringify( $('Get Unread Emails from Inbox').item.json.id) }},\n \"subject\": {{ JSON.stringify($('Get Unread Emails from Inbox').item.json.Subject) }},\n \"sender\": {{ JSON.stringify($('Get Unread Emails from Inbox').item.json.From) }},\n \"received_at\": {{ JSON.stringify(new Date(Number($('Get Unread Emails from Inbox').item.json.internalDate)).toISOString()) }},\n \"body\": {{ JSON.stringify($('Get Unread Emails from Inbox').item.json.snippet) }},\n \"gpt_summary\": {{ JSON.stringify($json.message.content) }},\n \"requires_deep_work\": {{ JSON.stringify($json.message.content.deep_work) }},\n \"deleted\": false\n}",
"sendBody": true,
"jsonHeaders": "={\n \"apikey\": \"{{ $vars.Supabase_TaskManagement_ANON_KEY }}\",\n \"Authorization\": \"Bearer {{ $vars.Supabase_TaskManagement_ANON_KEY }}\",\n \"Content-Type\": \"application/json\",\n \"Prefer\": \"resolution=ignore-conflict\"\n}",
"sendHeaders": true,
"specifyBody": "json",
"specifyHeaders": "json"
},
"notesInFlow": true,
"typeVersion": 4.2,
"alwaysOutputData": false
},
{
"id": "5b774acc-8e19-4576-9970-91a060d25d87",
"name": "받은편지함에서 읽지 않은 이메일 가져오기",
"type": "n8n-nodes-base.gmail",
"notes": "Fetches all unread emails from the inbox using Gmail API. These are the raw email inputs for analysis.",
"position": [
-360,
-430
],
"webhookId": "b6105761-5356-4ba7-828d-6efe96e244ba",
"parameters": {
"filters": {
"labelIds": [
"INBOX"
],
"readStatus": "unread"
},
"operation": "getAll",
"returnAll": true
},
"notesInFlow": true,
"typeVersion": 2.1,
"alwaysOutputData": false
},
{
"id": "5d856e76-d335-4a72-8807-556417a35d2d",
"name": "데이터베이스에서 이메일 가져오기",
"type": "n8n-nodes-base.supabase",
"notes": "Checks Supabase to see if this email has already been processed (by matching on email_id). Prevents duplicate GPT calls.",
"position": [
80,
-580
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "email_id",
"keyValue": "={{ $json.id }}"
}
]
},
"tableId": "emails",
"operation": "get"
},
"executeOnce": false,
"notesInFlow": true,
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "4d1d53a4-14c4-4d53-b9cb-1f29d425060b",
"name": "데이터베이스 내 이메일 존재 확인",
"type": "n8n-nodes-base.if",
"notes": "If the email does not exist in Supabase, continue with GPT processing. Otherwise, skip this email.",
"position": [
300,
-580
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "5969f38d-31d4-4ed0-ad6c-d8bb522db40f",
"operator": {
"type": "boolean",
"operation": "false",
"singleValue": true
},
"leftValue": "={{ $json.isEmpty() }}",
"rightValue": ""
}
]
},
"looseTypeValidation": true
},
"notesInFlow": true,
"typeVersion": 2.2,
"alwaysOutputData": false
},
{
"id": "9ff6b95c-9d19-4925-a718-15ca5774d81d",
"name": "항목 순환 처리",
"type": "n8n-nodes-base.splitInBatches",
"notes": "Loops through each unread email individually, allowing per-item processing (dedup, GPT, insert).",
"position": [
-140,
-430
],
"parameters": {
"options": {}
},
"notesInFlow": true,
"typeVersion": 3
},
{
"id": "a46fc69d-9711-4846-b6ff-e77394f518b5",
"name": "스티커 노트",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1680,
-640
],
"parameters": {
"width": 1000,
"height": 1840,
"content": "## 📩 Gmail → GPT → Supabase | Task Extractor\n\nThis n8n workflow automates the extraction of actionable tasks from unread Gmail messages using OpenAI's GPT API, stores the resulting task metadata in Supabase, and avoids re-processing previously handled emails.\n\n---\n\n## ✅ What It Does\n\n1. **Triggers on a schedule** to check for unread emails in your Gmail inbox.\n2. **Loops through each email individually** using `SplitInBatches`.\n3. **Checks Supabase** to see if the email has already been processed.\n4. If it's a new email:\n - Formats the email content into a structured GPT prompt\n - Calls **ChatGPT-4o** to extract structured task data\n - Inserts the result into your `emails` table in Supabase\n\n---\n\n## 🧰 Prerequisites\n\nBefore using this workflow, you must have:\n\n- An active **n8n Cloud or self-hosted instance**\n- A connected **Gmail account** with OAuth credentials in n8n\n- A **Supabase project** with an `emails` table and:\n ```sql\n ALTER TABLE emails ADD CONSTRAINT unique_email_id UNIQUE (email_id);\n ```\n- An **OpenAI API key** with access to GPT-4o or GPT-3.5-turbo\n\n---\n\n## 🔐 Required Credentials\n\n| Name | Type | Description |\n|-----------------|------------|-----------------------------------|\n| Gmail OAuth | Gmail | To pull unread messages |\n| OpenAI API Key | OpenAI | To generate task summaries |\n| Supabase API | HTTP | For inserting rows via REST API |\n\n---\n\n## 🔁 Environment Variables or Replacements\n\n- `Supabase_TaskManagement_URI` → e.g., `https://your-project.supabase.co`\n- `Supabase_TaskManagement_ANON_KEY` → Your Supabase anon key\n\nThese are used in the HTTP request to Supabase.\n\n---\n\n## ⏰ Scheduling / Trigger\n\n- Triggered using a **Schedule node**\n- Default: every X minutes (adjust to your preference)\n- Uses a Gmail API filter: **unread emails with label = INBOX**\n\n---\n\n## 🧠 Intended Use Case\n\n> Designed for productivity-minded professionals who want to extract, summarize, and store actionable tasks from incoming email — without processing the same email twice or wasting GPT API credits.\n\nThis is part of a larger system integrating GPT, calendar scheduling, and optional task platforms (like ClickUp).\n\n---\n\n## 📦 Output (Stored in Supabase)\n\nEach processed email includes:\n- `email_id`\n- `subject`\n- `sender`\n- `received_at`\n- `body` (email snippet)\n- `gpt_summary` (structured task)\n- `requires_deep_work` (from GPT logic)\n- `deleted` (initially false)"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "a7ad1235-9417-4c86-a3fd-cd72849f51dc",
"connections": {
"9ff6b95c-9d19-4925-a718-15ca5774d81d": {
"main": [
[],
[
{
"node": "5d856e76-d335-4a72-8807-556417a35d2d",
"type": "main",
"index": 0
}
]
]
},
"60d16e90-4a70-4aca-9643-997141a65cdf": {
"main": [
[
{
"node": "5b774acc-8e19-4576-9970-91a060d25d87",
"type": "main",
"index": 0
}
]
]
},
"501a117f-93ff-43e9-8a49-5f0c58c4e496": {
"main": [
[
{
"node": "cec2c062-7333-499a-b5c3-5f7831022d34",
"type": "main",
"index": 0
}
]
]
},
"5d856e76-d335-4a72-8807-556417a35d2d": {
"main": [
[
{
"node": "4d1d53a4-14c4-4d53-b9cb-1f29d425060b",
"type": "main",
"index": 0
}
]
]
},
"4d1d53a4-14c4-4d53-b9cb-1f29d425060b": {
"main": [
[
{
"node": "9ff6b95c-9d19-4925-a718-15ca5774d81d",
"type": "main",
"index": 0
}
],
[
{
"node": "501a117f-93ff-43e9-8a49-5f0c58c4e496",
"type": "main",
"index": 0
}
]
]
},
"5b774acc-8e19-4576-9970-91a060d25d87": {
"main": [
[
{
"node": "9ff6b95c-9d19-4925-a718-15ca5774d81d",
"type": "main",
"index": 0
}
]
]
},
"cec2c062-7333-499a-b5c3-5f7831022d34": {
"main": [
[
{
"node": "d708c9c3-d5ec-4b2a-8f8a-b5b123fa44ea",
"type": "main",
"index": 0
}
]
]
},
"d708c9c3-d5ec-4b2a-8f8a-b5b123fa44ea": {
"main": [
[
{
"node": "9ff6b95c-9d19-4925-a718-15ca5774d81d",
"type": "main",
"index": 0
}
]
]
}
}
}이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
중급 - 개인 생산성, AI 요약
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
Paul Taylor
@ptylrSenior product and solutions leader with deep technical expertise, commercial acumen, and proven leadership across VC- and PE-backed firms. I specialize in unifying product strategy, scaling cross-functional models, and incubating new opportunities. Skilled at crafting compelling narratives, driving GTM execution, and engaging externally with impact. I thrive on building teams and turning vision into value across the full product lifecycle.
이 워크플로우 공유