{
  "name": "Telegram \u2192 Voice/Text \u2192 Parse \u2192 Google Calendar",
  "nodes": [
    {
      "parameters": {},
      "id": "tg-trigger",
      "name": "Telegram Trigger (On message)",
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 2,
      "position": [
        -600,
        0
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "options": {
        "updates": "message"
      }
    },
    {
      "parameters": {
        "keepOnlySet": false,
        "values": {
          "string": [
            {
              "name": "chat_id",
              "value": "={{$json[\"message\"][\"chat\"][\"id\"]}}"
            }
          ]
        }
      },
      "id": "set-chat-id",
      "name": "Set chat_id",
      "type": "n8n-nodes-base.set",
      "typeVersion": 2,
      "position": [
        -400,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [],
          "number": [],
          "string": [
            {
              "value1": "={{$json[\"message\"][\"voice\"]}}",
              "operation": "isNotEmpty"
            }
          ]
        }
      },
      "id": "if-voice",
      "name": "IF (voice?)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -200,
        0
      ]
    },
    {
      "parameters": {
        "resource": "file",
        "operation": "download",
        "fileId": "={{$json[\"message\"][\"voice\"][\"file_id\"]}}"
      },
      "id": "tg-download",
      "name": "Telegram \u2192 Download file",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 2,
      "position": [
        0,
        -180
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "command": "ffmpeg -y -i \"={{$json[\"data\"][\"filePath\"]}}\" -ar 16000 -ac 1 \"C:\\n8n-stt\\in.wav\"",
        "options": {
          "shell": "powershell"
        }
      },
      "id": "exec-ffmpeg",
      "name": "Execute Command (ffmpeg \u2192 wav 16k mono)",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        230,
        -180
      ]
    },
    {
      "parameters": {
        "command": "python C:\\n8n-stt\\transcribe.py \"C:\\n8n-stt\\in.wav\" \"C:\\vosk\\vosk-model-small-ru-0.22\"",
        "options": {
          "shell": "powershell",
          "includeStdErr": false
        }
      },
      "id": "exec-vosk",
      "name": "Execute Command (Vosk STT)",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        460,
        -180
      ]
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "message_text",
              "value": "={{($json[\"stdout\"] || \"\").trim()}}"
            }
          ]
        }
      },
      "id": "set-from-stdout",
      "name": "Set message_text (from STT)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 2,
      "position": [
        690,
        -180
      ]
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "message_text",
              "value": "={{$json[\"message\"][\"text\"]}}"
            }
          ]
        }
      },
      "id": "set-from-text",
      "name": "Set message_text (from text)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 2,
      "position": [
        0,
        180
      ]
    },
    {
      "parameters": {
        "functionCode": "const input = (item.json.message_text || \"\").toLowerCase().trim();\nconst weekdays = { \"\u043f\u043d\":1,\"\u0432\u0442\":2,\"\u0441\u0440\":3,\"\u0447\u0442\":4,\"\u043f\u0442\":5,\"\u0441\u0431\":6,\"\u0432\u0441\":0,\n  \"\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\":1,\"\u0432\u0442\u043e\u0440\u043d\u0438\u043a\":2,\"\u0441\u0440\u0435\u0434\u0430\":3,\"\u0447\u0435\u0442\u0432\u0435\u0440\u0433\":4,\"\u043f\u044f\u0442\u043d\u0438\u0446\u0430\":5,\"\u0441\u0443\u0431\u0431\u043e\u0442\u0430\":6,\"\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435\":0 };\nfunction nextWeekday(dow){ const d=new Date(); const diff=(dow-d.getDay()+7)%7||7; d.setDate(d.getDate()+diff); return d; }\nlet date = new Date();\nif (input.includes(\"\u0437\u0430\u0432\u0442\u0440\u0430\")) date.setDate(date.getDate()+1);\nelse {\n  for (const [n,v] of Object.entries(weekdays)) { if (input.includes(n)) { date = nextWeekday(v); break; } }\n}\nlet h=9,m=0; const mt=input.match(/(\\d{1,2})(?:[:\\.](\\d{2}))?/); if(mt){h=parseInt(mt[1]); m=parseInt(mt[2]||\"0\");}\nlet title=input; const idx=input.indexOf(\" \u0432 \"); if(idx>0) title=input.slice(0,idx).trim();\ndate.setHours(h,m,0,0);\nconst startISO = date.toISOString();\nconst endISO = new Date(date.getTime()+30*60000).toISOString();\nreturn [{ json: { title: title || \"\u0417\u0430\u0434\u0430\u0447\u0430\", startISO, endISO } }];"
      },
      "id": "fn-parse",
      "name": "Function (parse title/date/time)",
      "type": "n8n-nodes-base.function",
      "typeVersion": 2,
      "position": [
        920,
        -10
      ]
    },
    {
      "parameters": {
        "operation": "create",
        "title": "={{$json[\"title\"]}}",
        "start": "={{$json[\"startISO\"]}}",
        "end": "={{$json[\"endISO\"]}}",
        "options": {
          "timezone": "Europe/Warsaw"
        }
      },
      "id": "gcal-create",
      "name": "Google Calendar \u2192 Create Event",
      "type": "n8n-nodes-base.googleCalendar",
      "typeVersion": 1,
      "position": [
        1150,
        -10
      ],
      "credentials": {
        "googleOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "sendMessage",
        "chatId": "={{$json[\"chat_id\"]}}",
        "text": "\u2705 \u0414\u043e\u0431\u0430\u0432\u0438\u043b: {{$json[\"title\"]}}\\n\ud83d\uddd3\ufe0f {{$json[\"startISO\"]}} \u2192 {{$json[\"endISO\"]}}"
      },
      "id": "tg-send",
      "name": "Telegram \u2192 Send Message",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 2,
      "position": [
        1380,
        -10
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Telegram Trigger (On message)": {
      "main": [
        [
          {
            "node": "Set chat_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set chat_id": {
      "main": [
        [
          {
            "node": "IF (voice?)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF (voice?)": {
      "main": [
        [
          {
            "node": "Telegram \u2192 Download file",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set message_text (from text)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram \u2192 Download file": {
      "main": [
        [
          {
            "node": "Execute Command (ffmpeg \u2192 wav 16k mono)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Command (ffmpeg \u2192 wav 16k mono)": {
      "main": [
        [
          {
            "node": "Execute Command (Vosk STT)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Command (Vosk STT)": {
      "main": [
        [
          {
            "node": "Set message_text (from STT)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set message_text (from STT)": {
      "main": [
        [
          {
            "node": "Function (parse title/date/time)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set message_text (from text)": {
      "main": [
        [
          {
            "node": "Function (parse title/date/time)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function (parse title/date/time)": {
      "main": [
        [
          {
            "node": "Google Calendar \u2192 Create Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Calendar \u2192 Create Event": {
      "main": [
        [
          {
            "node": "Telegram \u2192 Send Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}