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
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
  "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など)は別途料金が発生する場合があります。

ワークフロー情報
難易度
中級
ノード数9
カテゴリー2
ノードタイプ9
難易度説明

経験者向け、6-15ノードの中程度の複雑さのワークフロー

作成者
Paul Taylor

Paul Taylor

@ptylr

Senior 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.

外部リンク
n8n.ioで表示

このワークフローを共有

カテゴリー

カテゴリー: 34