{
  "updatedAt": "2026-05-14T00:01:24.692Z",
  "createdAt": "2026-03-18T20:17:45.262Z",
  "id": "QRCCdHNXZUHc2Oz4",
  "name": "Calendar to Obsidian Notes",
  "description": null,
  "active": true,
  "isArchived": false,
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1,
      "position": [
        240,
        304
      ]
    },
    {
      "parameters": {
        "operation": "getAll",
        "calendar": {
          "__rl": true,
          "value": "william.valentin.info@gmail.com",
          "mode": "list",
          "cachedResultName": "Perso"
        },
        "limit": 20,
        "options": {
          "timeMin": "={{ new Date().toISOString() }}",
          "timeMax": "={{ new Date(Date.now() + 7*24*60*60*1000).toISOString() }}",
          "singleEvents": true,
          "orderBy": "startTime"
        }
      },
      "id": "get-events",
      "name": "Get Upcoming Events",
      "type": "n8n-nodes-base.googleCalendar",
      "typeVersion": 1,
      "position": [
        464,
        304
      ],
      "credentials": {
        "googleCalendarOAuth2Api": {
          "id": "458fY4bs1z49OTeZ",
          "name": "Google Calendar account"
        }
      },
      "continueOnFail": true,
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "jsCode": "const event = $input.item.json || {};\nconst now = new Date();\nconst today = now.toISOString().slice(0, 10);\nconst hasUsableEvent = event.start && (event.summary || event.id || event.htmlLink);\nif (event.error || event.message || !hasUsableEvent) {\n  const detail = String(event.error?.message || event.message || event.error || 'Google Calendar returned no usable event; credentials may need reauthorization.').replace(/`/g, \"'\").slice(0, 1000);\n  const content = `---\ntitle: \"Google Calendar sync needs attention\"\narea: notes\ntags: [calendar, automation, degraded]\ncreated: ${today}\nupdated: ${today}\nstatus: needs-reauth\n---\n\n# Google Calendar sync needs attention\n\nThe n8n Calendar to Obsidian workflow could not read Google Calendar events.\n\nLikely cause: expired Google OAuth credentials in n8n.\n\nAction: reauthorize the Google Calendar credential used by workflow QRCCdHNXZUHc2Oz4, then run the workflow manually.\n\nLast observed detail:\n\n> ${detail}\n`;\n  return [{ json: { path: `Notes/Calendar Sync Status/${today} Google Calendar Needs Reauth.md`, content, title: 'Google Calendar sync needs attention', date: today, degraded: true } }];\n}\nconst event = $input.item.json;\nconst startRaw = event.start?.dateTime || event.start?.date || \"\";\nconst date = startRaw.split(\"T\")[0];\nconst title = (event.summary || \"Untitled Event\").replace(/[\\/\\\\?%*:|\"<>]/g, \"-\").substring(0, 80);\nconst location = event.location || \"\";\nconst description = event.description || \"\";\nconst attendees = (event.attendees || []).map(a => a.email).join(\", \");\nconst endRaw = event.end?.dateTime || event.end?.date || \"\";\nconst startTime = startRaw.includes(\"T\") ? startRaw.split(\"T\")[1].substring(0,5) : \"All day\";\nconst endTime = endRaw.includes(\"T\") ? endRaw.split(\"T\")[1].substring(0,5) : \"\";\nconst timeStr = endTime ? `${startTime} – ${endTime}` : startTime;\nconst frontmatter = `---\\ntitle: \"${title}\"\\narea: notes\\ntags: [calendar, event]\\ncreated: ${date}\\nupdated: ${date}\\nstatus: active\\nevent_date: ${date}\\nevent_time: \"${timeStr}\"\\n---`;\nconst content = `${frontmatter}\\n\\n# ${title}\\n\\n**Date:** ${date}\\n**Time:** ${timeStr}\\n${location ? `**Location:** ${location}\\n` : \"\"}${attendees ? `**Attendees:** ${attendees}\\n` : \"\"}\\n## Description\\n\\n${description || \"_No description_\"}\\n\\n## Notes\\n\\n_Add notes here_\\n`;\nreturn [{ json: { path: `Notes/${date} ${title}.md`, content, title, date, timeStr } }];"
      },
      "id": "format-note",
      "name": "Format Event Note",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        688,
        304
      ]
    },
    {
      "parameters": {
        "method": "PUT",
        "url": "=http://192.168.153.130:27123/vault/{{ encodeURIComponent($json.path).replace(/%2F/g, \"/\") }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "text/markdown",
        "body": "={{ $json.content }}",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "id": "write-to-vault",
      "name": "Write to Vault",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        912,
        304
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "465Swz2b71O2KRAK",
          "name": "Obsidian Local REST API"
        }
      }
    }
  ],
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Upcoming Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Upcoming Events": {
      "main": [
        [
          {
            "node": "Format Event Note",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Event Note": {
      "main": [
        [
          {
            "node": "Write to Vault",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  },
  "staticData": {
    "node:Schedule Trigger": {
      "recurrenceRules": [
        6
      ]
    }
  },
  "meta": null,
  "pinData": {},
  "versionId": "40b22838-7ce4-4632-b186-b78ccda438c4",
  "activeVersionId": "40b22838-7ce4-4632-b186-b78ccda438c4",
  "versionCounter": 1636,
  "triggerCount": 1,
  "shared": [
    {
      "updatedAt": "2026-03-18T20:17:45.264Z",
      "createdAt": "2026-03-18T20:17:45.264Z",
      "role": "workflow:owner",
      "workflowId": "QRCCdHNXZUHc2Oz4",
      "projectId": "WGdp8QunI1tHpjXa",
      "project": {
        "updatedAt": "2026-03-11T21:08:10.005Z",
        "createdAt": "2026-03-11T21:05:11.541Z",
        "id": "WGdp8QunI1tHpjXa",
        "name": "will will <will@wills-portal.com>",
        "type": "personal",
        "icon": null,
        "description": null,
        "creatorId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5"
      }
    }
  ],
  "tags": [
    {
      "updatedAt": "2026-03-19T04:40:29.915Z",
      "createdAt": "2026-03-19T04:40:29.915Z",
      "id": "GLr9Awuvw8uO7ZRP",
      "name": "calendar"
    },
    {
      "updatedAt": "2026-03-19T04:40:29.892Z",
      "createdAt": "2026-03-19T04:40:29.892Z",
      "id": "VfqIkUpiu2YMBSHw",
      "name": "obsidian-sync"
    }
  ],
  "activeVersion": {
    "updatedAt": "2026-05-14T00:01:24.693Z",
    "createdAt": "2026-05-14T00:01:24.693Z",
    "versionId": "40b22838-7ce4-4632-b186-b78ccda438c4",
    "workflowId": "QRCCdHNXZUHc2Oz4",
    "nodes": [
      {
        "parameters": {
          "rule": {
            "interval": [
              {
                "field": "hours",
                "hoursInterval": 6
              }
            ]
          }
        },
        "id": "schedule-trigger",
        "name": "Schedule Trigger",
        "type": "n8n-nodes-base.scheduleTrigger",
        "typeVersion": 1,
        "position": [
          240,
          304
        ]
      },
      {
        "parameters": {
          "operation": "getAll",
          "calendar": {
            "__rl": true,
            "value": "william.valentin.info@gmail.com",
            "mode": "list",
            "cachedResultName": "Perso"
          },
          "limit": 20,
          "options": {
            "timeMin": "={{ new Date().toISOString() }}",
            "timeMax": "={{ new Date(Date.now() + 7*24*60*60*1000).toISOString() }}",
            "singleEvents": true,
            "orderBy": "startTime"
          }
        },
        "id": "get-events",
        "name": "Get Upcoming Events",
        "type": "n8n-nodes-base.googleCalendar",
        "typeVersion": 1,
        "position": [
          464,
          304
        ],
        "credentials": {
          "googleCalendarOAuth2Api": {
            "id": "458fY4bs1z49OTeZ",
            "name": "Google Calendar account"
          }
        },
        "continueOnFail": true,
        "alwaysOutputData": true
      },
      {
        "parameters": {
          "jsCode": "const event = $input.item.json || {};\nconst now = new Date();\nconst today = now.toISOString().slice(0, 10);\nconst hasUsableEvent = event.start && (event.summary || event.id || event.htmlLink);\nif (event.error || event.message || !hasUsableEvent) {\n  const detail = String(event.error?.message || event.message || event.error || 'Google Calendar returned no usable event; credentials may need reauthorization.').replace(/`/g, \"'\").slice(0, 1000);\n  const content = `---\ntitle: \"Google Calendar sync needs attention\"\narea: notes\ntags: [calendar, automation, degraded]\ncreated: ${today}\nupdated: ${today}\nstatus: needs-reauth\n---\n\n# Google Calendar sync needs attention\n\nThe n8n Calendar to Obsidian workflow could not read Google Calendar events.\n\nLikely cause: expired Google OAuth credentials in n8n.\n\nAction: reauthorize the Google Calendar credential used by workflow QRCCdHNXZUHc2Oz4, then run the workflow manually.\n\nLast observed detail:\n\n> ${detail}\n`;\n  return [{ json: { path: `Notes/Calendar Sync Status/${today} Google Calendar Needs Reauth.md`, content, title: 'Google Calendar sync needs attention', date: today, degraded: true } }];\n}\nconst event = $input.item.json;\nconst startRaw = event.start?.dateTime || event.start?.date || \"\";\nconst date = startRaw.split(\"T\")[0];\nconst title = (event.summary || \"Untitled Event\").replace(/[\\/\\\\?%*:|\"<>]/g, \"-\").substring(0, 80);\nconst location = event.location || \"\";\nconst description = event.description || \"\";\nconst attendees = (event.attendees || []).map(a => a.email).join(\", \");\nconst endRaw = event.end?.dateTime || event.end?.date || \"\";\nconst startTime = startRaw.includes(\"T\") ? startRaw.split(\"T\")[1].substring(0,5) : \"All day\";\nconst endTime = endRaw.includes(\"T\") ? endRaw.split(\"T\")[1].substring(0,5) : \"\";\nconst timeStr = endTime ? `${startTime} – ${endTime}` : startTime;\nconst frontmatter = `---\\ntitle: \"${title}\"\\narea: notes\\ntags: [calendar, event]\\ncreated: ${date}\\nupdated: ${date}\\nstatus: active\\nevent_date: ${date}\\nevent_time: \"${timeStr}\"\\n---`;\nconst content = `${frontmatter}\\n\\n# ${title}\\n\\n**Date:** ${date}\\n**Time:** ${timeStr}\\n${location ? `**Location:** ${location}\\n` : \"\"}${attendees ? `**Attendees:** ${attendees}\\n` : \"\"}\\n## Description\\n\\n${description || \"_No description_\"}\\n\\n## Notes\\n\\n_Add notes here_\\n`;\nreturn [{ json: { path: `Notes/${date} ${title}.md`, content, title, date, timeStr } }];"
        },
        "id": "format-note",
        "name": "Format Event Note",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          688,
          304
        ]
      },
      {
        "parameters": {
          "method": "PUT",
          "url": "=http://192.168.153.130:27123/vault/{{ encodeURIComponent($json.path).replace(/%2F/g, \"/\") }}",
          "authentication": "genericCredentialType",
          "genericAuthType": "httpHeaderAuth",
          "sendBody": true,
          "contentType": "raw",
          "rawContentType": "text/markdown",
          "body": "={{ $json.content }}",
          "options": {
            "response": {
              "response": {
                "neverError": true
              }
            }
          }
        },
        "id": "write-to-vault",
        "name": "Write to Vault",
        "type": "n8n-nodes-base.httpRequest",
        "typeVersion": 4,
        "position": [
          912,
          304
        ],
        "credentials": {
          "httpHeaderAuth": {
            "id": "465Swz2b71O2KRAK",
            "name": "Obsidian Local REST API"
          }
        }
      }
    ],
    "connections": {
      "Schedule Trigger": {
        "main": [
          [
            {
              "node": "Get Upcoming Events",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Get Upcoming Events": {
        "main": [
          [
            {
              "node": "Format Event Note",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Format Event Note": {
        "main": [
          [
            {
              "node": "Write to Vault",
              "type": "main",
              "index": 0
            }
          ]
        ]
      }
    },
    "authors": "will will",
    "name": null,
    "description": null,
    "autosaved": false,
    "workflowPublishHistory": [
      {
        "createdAt": "2026-05-14T00:01:24.723Z",
        "id": 1466,
        "workflowId": "QRCCdHNXZUHc2Oz4",
        "versionId": "40b22838-7ce4-4632-b186-b78ccda438c4",
        "event": "activated",
        "userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5"
      },
      {
        "createdAt": "2026-05-14T00:01:24.711Z",
        "id": 1465,
        "workflowId": "QRCCdHNXZUHc2Oz4",
        "versionId": "40b22838-7ce4-4632-b186-b78ccda438c4",
        "event": "deactivated",
        "userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5"
      }
    ]
  }
}
