{
  "name": "04 - Daily Gmail Summary with GPT-5.6 Luna",
  "nodes": [
    {
      "parameters": {
        "content": "## 4. Send a daily unread-email summary\n\n**Scheduled reporting stage.** At 7:00 AM, gets unread messages received in the previous 25 hours (excluding spam and trash), asks GPT-5.6 Luna for a concise HTML digest, and sends it through Gmail to the configured placeholder recipient. It does not mark messages read or alter any labels.",
        "height": 430,
        "width": 2670,
        "color": 7
      },
      "id": "s4-note",
      "name": "Stage 4 — Daily unread Gmail summary",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -160,
        1000
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 7
            }
          ]
        }
      },
      "id": "s4-trigger",
      "name": "Daily Gmail Summary at 7AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -80,
        1168
      ]
    },
    {
      "parameters": {
        "jsCode": "const recipient = 'REPLACE_WITH_YOUR_EMAIL_ADDRESS';\nconst hoursBack = 25;\nreturn [{ json: { recipient, hoursBack } }];"
      },
      "id": "s4-settings",
      "name": "Gmail Summary Settings",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        176,
        1168
      ]
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "message",
        "operation": "getAll",
        "returnAll": false,
        "limit": 100,
        "simple": true,
        "filters": {
          "includeSpamTrash": false,
          "q": "-in:spam -in:trash",
          "readStatus": "unread",
          "receivedAfter": "={{ $now.minus({ hours: $(\"Gmail Summary Settings\").first().json.hoursBack }).toISO() }}"
        },
        "options": {}
      },
      "id": "s4-get-messages",
      "name": "Get Recent Unread Gmail Messages",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        432,
        1168
      ],
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "jsCode": "const messages = $input.all().map(item => item.json).filter(message => message.id);\nconst compact = messages.map(message => ({\n  from: message.From || message.from || '',\n  subject: message.Subject || message.subject || '(no subject)',\n  date: message.Date || message.date || message.internalDate || '',\n  snippet: String(message.snippet || '').slice(0, 800),\n  labels: (message.labels || []).map(label => label.name),\n}));\nconst prompt = [\n  'Create a concise, safe HTML digest of these unread Gmail messages.',\n  'Return the finished HTML fragment in the html field of the required JSON response. Group by urgency or theme, show sender and subject, and include a one-sentence summary.',\n  'Do not invent facts, links, or actions. If there are no messages, return a short paragraph saying there were no unread messages in the period.',\n  JSON.stringify(compact),\n].join('\\n');\nreturn [{ json: { prompt, unreadCount: compact.length } }];"
      },
      "id": "s4-build-prompt",
      "name": "Build Daily Gmail Summary Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        704,
        1168
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.replicate.com/v1/models/openai/gpt-5.6-luna/predictions",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Prefer",
              "value": "wait=60"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ $json.replicateRequest }}",
        "options": {
          "timeout": 120000
        }
      },
      "id": "s4-ai",
      "name": "AI Summarizes Unread Gmail",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        976,
        1168
      ]
    },
    {
      "parameters": {
        "jsCode": "function parseStructured(value) {\n  if (value && typeof value === 'object' && !Array.isArray(value)) {\n    if (value.json_output && typeof value.json_output === 'object') return value.json_output;\n    if (value.output?.json_output && typeof value.output.json_output === 'object') return value.output.json_output;\n    if (typeof value.text !== 'string' && typeof value.output?.text !== 'string') return value;\n  }\n  const source = typeof value?.text === 'string'\n    ? value.text\n    : typeof value?.output?.text === 'string'\n      ? value.output.text\n      : value;\n  const text = Array.isArray(source)\n    ? source.map(part => typeof part === 'string' ? part : JSON.stringify(part)).join('')\n    : String(source ?? '');\n  try { return JSON.parse(text); } catch {}\n  const match = text.match(/\\{[\\s\\S]*\\}/);\n  if (!match) return {};\n  try { return JSON.parse(match[0]); } catch { return {}; }\n}\nconst response = $input.first().json;\nconst settings = $('Gmail Summary Settings').first().json;\nconst parsed = parseStructured(response.output ?? response);\nconst summary = String(parsed.html || '<p>No summary was returned.</p>');\nreturn [{ json: {\n  recipient: settings.recipient,\n  subject: 'Daily unread Gmail summary — ' + $now.toFormat('dd LLL yyyy'),\n  html: '<h1>Unread Gmail summary</h1>' + summary,\n} }];"
      },
      "id": "s4-prepare",
      "name": "Prepare Gmail Summary Email",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1248,
        1168
      ]
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "message",
        "operation": "send",
        "sendTo": "={{ $json.recipient }}",
        "subject": "={{ $json.subject }}",
        "emailType": "html",
        "message": "={{ $json.html }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "s4-send",
      "name": "Send Daily Gmail Summary",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        1520,
        1168
      ]
    },
    {
      "id": "s4-ai-request-builder",
      "name": "Build AI Summarizes Unread Gmail Request",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        752,
        1168
      ],
      "parameters": {
        "jsCode": "return $input.all().map(item => {\n  const data = item.json;\n  const prompt = data.prompt;\n  return {\n    ...item,\n    json: {\n      ...data,\n      replicateRequest: {\n        input: {\n          prompt,\n          reasoning_effort: \"low\",\n          verbosity: 'low',\n          max_completion_tokens: 4000,\n        },\n      },\n    },\n  };\n});"
      }
    }
  ],
  "connections": {
    "Daily Gmail Summary at 7AM": {
      "main": [
        [
          {
            "node": "Gmail Summary Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail Summary Settings": {
      "main": [
        [
          {
            "node": "Get Recent Unread Gmail Messages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Recent Unread Gmail Messages": {
      "main": [
        [
          {
            "node": "Build Daily Gmail Summary Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Daily Gmail Summary Prompt": {
      "main": [
        [
          {
            "node": "Build AI Summarizes Unread Gmail Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Summarizes Unread Gmail": {
      "main": [
        [
          {
            "node": "Prepare Gmail Summary Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Gmail Summary Email": {
      "main": [
        [
          {
            "node": "Send Daily Gmail Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build AI Summarizes Unread Gmail Request": {
      "main": [
        [
          {
            "node": "AI Summarizes Unread Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": false,
    "timezone": "Australia/Sydney"
  },
  "versionId": "e935cbb4-edfe-4800-88d1-1d9f3c887379",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}
