{
  "name": "Google Calendar 自動更新 copy",
  "nodes": [
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        -780,
        240
      ],
      "id": "587e5bf5-aa3d-445b-8266-c63a63a2e9e5",
      "name": "OpenRouter Chat Model",
      "credentials": {
        "openRouterApi": {
          "id": "V9Q0mu5I1nLi6hXD",
          "name": "OpenRouter account"
        }
      }
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1180,
        40
      ],
      "id": "92efc750-35ae-483c-9aba-0eb738ecc5fd",
      "name": "LINE Webhook",
      "webhookId": ""
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/chat/loading/start",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer "
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n    \"chatId\": \"{{ $json.body.events[0].source.userId }}\",\n    \"loadingSeconds\": 5\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -960,
        40
      ],
      "id": "190417f1-2782-45aa-aa38-bf70dd68fd63",
      "name": "LINE Loading Animation"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=請幫我把以下訊息，分析出活動的時間跟標題，並輸出成 JSON 格式\n{{ $('LINE Webhook').item.json.body.events[0].message.text }}\n\n如果沒有給年份的話，預設是 2025 年",
        "hasOutputParser": true,
        "messages": {
          "messageValues": [
            {
              "message": "=你是一個專門將活動資訊轉成 JSON 的助手。\n請根據使用者的文字，直接輸出純 JSON 陣列（不要加入說明文字或 markdown 格式）。\n格式範例如下：\n\n[\n  {\n    \"title\": \"跟楊可吃飯\",\n    \"start\": \"2025-06-21T08:00:00\",\n    \"end\": \"2025-06-21T23:00:00\"\n  }\n]\n\n\n如果輸入內容**無法被明確解析為活動資訊**（例如純數字、無意義字詞、日常對話等），請直接回傳：\n```json\n[]"
            }
          ]
        }
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.6,
      "position": [
        -740,
        40
      ],
      "id": "a759405b-155b-4fef-a248-06c33fdc17ee",
      "name": "解析活動標題&時間"
    },
    {
      "parameters": {
        "jsCode": "const rawText = $input.first().json.text;\nlet jsonText = null;\n\n// Step 1: 嘗試先抓取 ```json 區塊\nconst match = rawText.match(/```json\\s*([\\s\\S]*?)\\s*```/);\nif (match) {\n  jsonText = match[1].replace(/\\\\n/g, '').trim();\n} else {\n  // 沒有 markdown 區塊，可能是直接塞在 text 裡的 JSON 陣列字串\n  jsonText = rawText.replace(/\\\\n/g, '').trim();\n}\n\n// Step 2: 嘗試 JSON.parse\nlet events;\ntry {\n  events = JSON.parse(jsonText);\n} catch (err) {\n  return [\n    {\n      json: {\n        status: \"invalid\",\n        reason: \"JSON parsing failed: \" + err.message,\n        raw: rawText\n      }\n    }\n  ];\n}\n\n// Step 3: 判斷是否為有效事件清單\nif (!Array.isArray(events) || events.length === 0) {\n  return [\n    {\n      json: {\n        status: \"invalid\",\n        reason: \"No events found.\",\n        raw: rawText\n      }\n    }\n  ];\n}\n\n// Step 4: 回傳每一筆事件 + valid 狀態\nreturn events.map(event => ({\n  json: {\n    ...event,\n    status: \"valid\"\n  }\n}));\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -364,
        40
      ],
      "id": "1238c17d-c7b1-4669-979f-b5302d642aa8",
      "name": "解析 JSON"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "a18a10af-53e1-4e66-adf4-369e306ada7b",
              "leftValue": "={{ $json.status }}",
              "rightValue": "valid",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -144,
        40
      ],
      "id": "49c12993-0e21-4ad6-b9d1-ed299c28641c",
      "name": "判斷文字是否包含活動資訊"
    },
    {
      "parameters": {
        "calendar": {
          "__rl": true,
          "value": "",
          "mode": "list",
          "cachedResultName": ""
        },
        "start": "={{ $json.start }}",
        "end": "={{ $json.end }}",
        "additionalFields": {
          "summary": "={{ $json.title }}"
        }
      },
      "type": "n8n-nodes-base.googleCalendar",
      "typeVersion": 1.3,
      "position": [
        76,
        -60
      ],
      "id": "8ef71f16-5d60-4e8c-b1d0-8385be1a90ba",
      "name": "新增行事曆活動",
      "credentials": {
        "googleCalendarOAuth2Api": {
          "id": "FEzIETuqj5XKQvwm",
          "name": "Google Calendar account"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer "
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n    \"replyToken\":\"{{ $('LINE Webhook').item.json.body.events[0].replyToken }}\",\n    \"messages\":[\n        {\n            \"type\":\"text\",\n            \"text\":\"更新好囉！記得再去檢查一下 Google Calendar\"\n        }\n    ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        300,
        -60
      ],
      "id": "a8f5bf16-0189-4257-ad17-f578389967e7",
      "name": "回覆成功訊息！"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.line.me/v2/bot/message/reply",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer "
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n    \"replyToken\":\"{{ $('LINE Webhook').item.json.body.events[0].replyToken }}\",\n    \"messages\":[\n        {\n            \"type\":\"text\",\n            \"text\":\"Oops!你沒有上傳任何活動相關資訊喔！請再確認一次！\"\n        }\n    ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        76,
        140
      ],
      "id": "b65b1bd2-4061-41d8-8391-2f6a8264bc2e",
      "name": "回覆失敗訊息！"
    }
  ],
  "pinData": {},
  "connections": {
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "解析活動標題&時間",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "LINE Webhook": {
      "main": [
        [
          {
            "node": "LINE Loading Animation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LINE Loading Animation": {
      "main": [
        [
          {
            "node": "解析活動標題&時間",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "解析活動標題&時間": {
      "main": [
        [
          {
            "node": "解析 JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "解析 JSON": {
      "main": [
        [
          {
            "node": "判斷文字是否包含活動資訊",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "判斷文字是否包含活動資訊": {
      "main": [
        [
          {
            "node": "新增行事曆活動",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "回覆失敗訊息！",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "新增行事曆活動": {
      "main": [
        [
          {
            "node": "回覆成功訊息！",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "271086af-14e7-45ea-81fe-b1f7b8b78bd8",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "654f02c38a9b936a50db216077e5141cbd7116711543c99a1f4fe197de88ec7c"
  },
  "id": "b1eEY8OvzCJhOgTI",
  "tags": []
}