{
  "name": "05 - Email Reader",
  "nodes": [
    {
      "parameters": {},
      "name": "Execute Workflow Trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT access_token FROM gmail_tokens WHERE user_id = $1 AND expires_at > datetime('now')",
        "additionalFields": {
          "parameters": [
            {
              "name": "user_id",
              "value": "={{ $json.userId }}"
            }
          ]
        }
      },
      "name": "Get Access Token",
      "type": "n8n-nodes-base.sqlite",
      "typeVersion": 2.2,
      "position": [
        450,
        300
      ],
      "credentials": {
        "sqlite": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "maxResults",
              "value": "={{ $json.limit || 10 }}"
            },
            {
              "name": "labelIds",
              "value": "={{ $json.label || 'INBOX' }}"
            },
            {
              "name": "q",
              "value": "={{ $json.searchQuery ? $json.searchQuery : 'is:unread' }}"
            }
          ]
        },
        "options": {}
      },
      "name": "Fetch Email List",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        650,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Get list of message IDs\nconst messages = $input.first().json.messages || [];\n\nif (messages.length === 0) {\n  return [{ json: { noEmails: true } }];\n}\n\n// Return each message ID for processing\nreturn messages.map((msg, index) => ({\n  json: {\n    id: msg.id,\n    threadId: msg.threadId,\n    index: index + 1\n  }\n}));"
      },
      "name": "Process Message List",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        850,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ 'https://gmail.googleapis.com/gmail/v1/users/me/messages/' + $json.id }}",
        "options": {}
      },
      "name": "Fetch Full Email",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1050,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Parse Gmail message format\nconst email = $input.first().json;\n\n// Extract headers\nconst headers = {};\nemail.payload.headers.forEach(header => {\n  headers[header.name.toLowerCase()] = header.value;\n});\n\n// Extract body\nlet bodyText = '';\nlet bodyHtml = '';\n\nfunction extractBody(parts) {\n  if (!parts) return;\n  \n  parts.forEach(part => {\n    if (part.mimeType === 'text/plain' && part.body.data) {\n      bodyText = Buffer.from(part.body.data, 'base64').toString('utf-8');\n    } else if (part.mimeType === 'text/html' && part.body.data) {\n      bodyHtml = Buffer.from(part.body.data, 'base64').toString('utf-8');\n    } else if (part.parts) {\n      extractBody(part.parts);\n    }\n  });\n}\n\nif (email.payload.parts) {\n  extractBody(email.payload.parts);\n} else if (email.payload.body && email.payload.body.data) {\n  bodyText = Buffer.from(email.payload.body.data, 'base64').toString('utf-8');\n}\n\n// Parse sender\nconst fromHeader = headers.from || 'Unknown';\nconst senderMatch = fromHeader.match(/(.*)<(.*)>/);\nconst senderName = senderMatch ? senderMatch[1].trim() : fromHeader;\nconst senderEmail = senderMatch ? senderMatch[2] : fromHeader;\n\n// Check for attachments\nconst hasAttachments = email.payload.parts && email.payload.parts.some(p => p.filename && p.filename.length > 0);\nconst attachmentNames = hasAttachments \n  ? email.payload.parts.filter(p => p.filename).map(p => p.filename).join(', ')\n  : '';\n\nreturn [{\n  json: {\n    gmail_id: email.id,\n    thread_id: email.threadId,\n    sender_name: senderName,\n    sender_email: senderEmail,\n    subject: headers.subject || '(No Subject)',\n    date: headers.date,\n    snippet: email.snippet,\n    body_text: bodyText.substring(0, 10000), // Limit size\n    body_html: bodyHtml.substring(0, 10000),\n    is_read: !email.labelIds.includes('UNREAD'),\n    labels: JSON.stringify(email.labelIds),\n    has_attachments: hasAttachments,\n    attachment_names: attachmentNames,\n    history_id: email.historyId\n  }\n}];"
      },
      "name": "Parse Email Content",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1250,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT OR REPLACE INTO emails (gmail_id, thread_id, user_id, sender_name, sender_email, subject, snippet, body_text, body_html, received_at, is_read, labels, has_attachments, attachment_names, cached_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, datetime('now'))",
        "additionalFields": {
          "parameters": [
            {
              "name": "gmail_id",
              "value": "={{ $json.gmail_id }}"
            },
            {
              "name": "thread_id",
              "value": "={{ $json.thread_id }}"
            },
            {
              "name": "user_id",
              "value": "={{ $('Execute Workflow Trigger').first().json.userId }}"
            },
            {
              "name": "sender_name",
              "value": "={{ $json.sender_name }}"
            },
            {
              "name": "sender_email",
              "value": "={{ $json.sender_email }}"
            },
            {
              "name": "subject",
              "value": "={{ $json.subject }}"
            },
            {
              "name": "snippet",
              "value": "={{ $json.snippet }}"
            },
            {
              "name": "body_text",
              "value": "={{ $json.body_text }}"
            },
            {
              "name": "body_html",
              "value": "={{ $json.body_html }}"
            },
            {
              "name": "received_at",
              "value": "={{ $json.date }}"
            },
            {
              "name": "is_read",
              "value": "={{ $json.is_read }}"
            },
            {
              "name": "labels",
              "value": "={{ $json.labels }}"
            },
            {
              "name": "has_attachments",
              "value": "={{ $json.has_attachments }}"
            },
            {
              "name": "attachment_names",
              "value": "={{ $json.attachment_names }}"
            }
          ]
        }
      },
      "name": "Cache Email",
      "type": "n8n-nodes-base.sqlite",
      "typeVersion": 2.2,
      "position": [
        1450,
        300
      ],
      "credentials": {
        "sqlite": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Execute Workflow Trigger": {
      "main": [
        [
          {
            "node": "Get Access Token",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Access Token": {
      "main": [
        [
          {
            "node": "Fetch Email List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Email List": {
      "main": [
        [
          {
            "node": "Process Message List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Message List": {
      "main": [
        [
          {
            "node": "Fetch Full Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Full Email": {
      "main": [
        [
          {
            "node": "Parse Email Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Email Content": {
      "main": [
        [
          {
            "node": "Cache Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "tags": [
    "ronkbot",
    "gmail",
    "email",
    "read"
  ]
}