{
  "id": "Ed059M6hQJMtdEgK",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Manage Google Calendar events via Zalo Bot voice and text messages with AI Agent",
  "tags": [],
  "nodes": [
    {
      "id": "1a508fcd-e409-4aeb-8992-2e035594a764",
      "name": "Start",
      "type": "n8n-nodes-zalo-bot-official.zaloBotTrigger",
      "position": [
        -2768,
        1856
      ],
      "parameters": {},
      "credentials": {
        "zaloBotApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "441e8d3b-8280-4e52-8364-03c6576a7411",
      "name": "Send Typing Indicator",
      "type": "n8n-nodes-zalo-bot-official.zaloBot",
      "position": [
        -2464,
        1680
      ],
      "parameters": {
        "chatId": "={{ $('Start').item.json.message.chat.id }}",
        "operation": "sendChatAction"
      },
      "credentials": {
        "zaloBotApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "632bb99f-423b-4f03-8ded-d1bd0635a66c",
      "name": "Calendar Manage!",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueErrorOutput",
      "position": [
        -1376,
        1840
      ],
      "parameters": {
        "text": "={{ $('Context').item.json.message.text }}\n{{ $('Transcribe a recording').item.json.content.parts[0].text }}",
        "options": {
          "systemMessage": "=## 1. ROLE & LIMITATIONS\nYou are a casual, highly capable, and friendly personal AI assistant for your bro, Nguy\u1ec5n Thi\u1ec7u To\u00e0n (Jay Nguyen), designed to help him manage his Google Calendar events through natural language text or voice commands via Zalo Bot. Your final output to the user must be strictly in Vietnamese, using an informal \"bro - tui\" tone.\n\n## 2. CONTEXT & CONFIGURATION\n- Current DateTime: {{ $now.toFormat('cccc d LLLL yyyy HH:mm') }}\n- User Timezone: Asia/Ho_Chi_Minh (GMT +7)\n- Default Event Duration: 1 hour\n- Target User: Nguy\u1ec5n Thi\u1ec7u To\u00e0n (Creator of GenStaff - genstaff.net)\n\n## 3. STRICT TOOL USAGE WORKFLOWS\n- For Event Creation:\n  * ALWAYS extract or ask for: event_title (required), start_date in ISO format (required), end_date in ISO format (required).\n  * Execute the \"Create Event\" tool passing all validated parameters.\n- For Event Deletion:\n  * ALWAYS call the \"Get events\" tool FIRST to scan/retrieve recent entries and locate the precise target event_id.\n  * Execute the \"Delete event\" tool using that extracted event_id.\n- For Event Updates:\n  * ALWAYS execute the \"Get events\" tool FIRST to find the event profile and fetch its exact event_id.\n  * Execute the \"Update Event\" tool with the event_id and modified parameters.\n- For Event Listing:\n  * Execute the \"Get events\" tool with the target date scope.\n\n## 4. TONE & COMMUNICATION PROTOCOL\n- Address Nguy\u1ec5n Thi\u1ec7u To\u00e0n as \"bro\". Refer to yourself as \"tui\".\n- Never use excessively formal or polite Vietnamese particles like \"d\u1ea1\", \"v\u00e2ng \u1ea1\". Keep it practical, witty, and grounded.\n- ALWAYS terminate your final response block with this exact casual engagement text: \"Bro c\u1ea7n tui gi\u00fap g\u00ec n\u1eefa kh\u00f4ng?\".\n\n## 5. OUTPUT FORMATTING\n- Format the complete response using Markdown blocks.\n- **Bold** or *italicize* vital keywords, event titles, time allocations, and statuses to guarantee optimal mobile scannability."
        },
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 3.1,
      "waitBetweenTries": 100
    },
    {
      "id": "a866e534-0cfd-4277-9554-af9547f49087",
      "name": "Delete event",
      "type": "n8n-nodes-base.googleCalendarTool",
      "position": [
        -1136,
        2320
      ],
      "parameters": {
        "eventId": "={{ $fromAI('event_id') }}",
        "options": {},
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "user@example.com"
        },
        "operation": "delete"
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "dfac44c3-af99-4f24-9c52-0f2489e0b7b8",
      "name": "Get events",
      "type": "n8n-nodes-base.googleCalendarTool",
      "position": [
        -1520,
        2320
      ],
      "parameters": {
        "options": {},
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "user@example.com"
        },
        "operation": "getAll"
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "fb701544-370e-4269-8e07-1a05d8491111",
      "name": "Create Event",
      "type": "n8n-nodes-base.googleCalendarTool",
      "position": [
        -1328,
        2320
      ],
      "parameters": {
        "end": "={{ $fromAI('end_date') }}",
        "start": "={{ $fromAI('start_date') }}",
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "user@example.com"
        },
        "additionalFields": {
          "summary": "={{ $fromAI('event_title') }}",
          "location": "={{ $fromAI('location') || '' }}",
          "description": "={{ $fromAI('event_description') || '' }}"
        },
        "useDefaultReminders": false
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "e46cbbc3-d725-47b0-9bc3-16d96500bcb4",
      "name": "Update Event",
      "type": "n8n-nodes-base.googleCalendarTool",
      "position": [
        -944,
        2320
      ],
      "parameters": {
        "eventId": "={{ $fromAI('event_id') }}",
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "user@example.com"
        },
        "operation": "update",
        "updateFields": {
          "end": "={{ $fromAI('end_date') || '' }}",
          "start": "={{ $fromAI('start_date') || '' }}",
          "summary": "={{ $fromAI('event_title') || '' }}",
          "location": "={{ $fromAI('location') || '' }}",
          "description": "={{ $fromAI('event_description') || '' }}"
        },
        "useDefaultReminders": false
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "503f36cd-f63b-4b8f-9005-abb8f40c57bf",
      "name": "Send AI Response",
      "type": "n8n-nodes-zalo-bot-official.zaloBot",
      "position": [
        -640,
        1840
      ],
      "parameters": {
        "text": "={{ $('Calendar Manage!').item.json.output }}",
        "chatId": "={{ $('Start').item.json.message.chat.id }}",
        "parseMode": "markdown"
      },
      "credentials": {
        "zaloBotApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "ce652c49-f6a7-4de2-8885-8ee78e86fd3c",
      "name": "Send Error Noti",
      "type": "n8n-nodes-zalo-bot-official.zaloBot",
      "position": [
        -640,
        2032
      ],
      "parameters": {
        "text": "<i>\u274c C\u00f3 l\u1ed7i x\u1ea3y ra r\u1ed3i bro \u01a1i. B\u1ea3n d\u1ecbch ho\u1eb7c lu\u1ed3ng k\u1ebft n\u1ed1i l\u1ecbch b\u1ecb gi\u00e1n \u0111o\u1ea1n, h\u00e3y th\u1eed l\u1ea1i b\u1eb1ng l\u1ec7nh r\u00f5 r\u00e0ng h\u01a1n ho\u1eb7c ki\u1ec3m tra l\u1ea1i workflow nh\u00e9!</i>",
        "chatId": "={{ $('Start').item.json.message.chat.id }}",
        "parseMode": "html"
      },
      "credentials": {
        "zaloBotApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "c7cb0be9-3ed7-4a10-b616-b4bfd4683d42",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1536,
        2064
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "9fb43679-8872-4711-8715-05cb935b7b0f",
      "name": "If Message is Voice",
      "type": "n8n-nodes-base.if",
      "position": [
        -2224,
        1856
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a84e7e19-914f-4adc-b3eb-85da1c3c2510",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Context').item.json.message.message_type }}",
              "rightValue": "CHAT_VOICE"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b64825b6-cb58-4d41-9e29-de9b7c931b59",
      "name": "Context",
      "type": "n8n-nodes-base.set",
      "position": [
        -2464,
        1856
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cd902a9b-cf55-429e-b681-95ccf22cacf9",
              "name": "message.chat.chat_type",
              "type": "string",
              "value": "={{ $('Start').item.json.message.chat.chat_type }}"
            },
            {
              "id": "b20d34a4-abe2-4c85-b4a4-e89f383f86f0",
              "name": "message.chat.id",
              "type": "string",
              "value": "={{ $('Start').item.json.message.chat.id }}"
            },
            {
              "id": "55fce9bd-a7fa-4382-8d47-d480a0d6513f",
              "name": "message.message_type",
              "type": "string",
              "value": "={{ $('Start').item.json.message.message_type }}"
            },
            {
              "id": "3f1d035f-9714-484d-a402-19c317eaf1d5",
              "name": "message.from.display_name",
              "type": "string",
              "value": "={{ $('Start').item.json.message.from.display_name }}"
            },
            {
              "id": "c1bd5fc5-f7bd-4c32-b2c1-3578aef691d1",
              "name": "message.voice_url",
              "type": "string",
              "value": "={{ $('Start').item.json.message.voice_url }}"
            },
            {
              "id": "3f130d13-4ac0-4c5c-bb7b-6b5c2d1e6d6c",
              "name": "message.text",
              "type": "string",
              "value": "={{ $('Start').item.json.message.text || \"\" }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6c4da0cc-9c6a-4fb0-b50c-e95b18858b67",
      "name": "Transcribe a recording",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        -1968,
        1728
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash"
        },
        "options": {},
        "resource": "audio",
        "audioUrls": "={{ $('Context').item.json.message.voice_url }}"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "39e6617c-8c24-4b3b-99a8-186b5af63022",
      "name": "Main Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3360,
        1504
      ],
      "parameters": {
        "width": 550,
        "height": 936,
        "content": "## Manage Google Calendar events via Zalo Bot voice and text messages with AI Agent\n\nThis workflow turns your **Zalo Official Account (OA)** into an AI-powered smart assistant capable of managing your schedule. It dynamically handles both text strings and voice voice notes using **Gemini** translation, processing complex multi-turn calendar instructions directly into **Google Calendar** nodes via an **AI Agent** structural layout.\n\n### How it works\n1. **Trigger:** The Zalo Bot Webhook monitors incoming user interactions.\n2. **Classification:** Checks the message context to classify text vs voice payload data.\n3. **Transcription:** Audio note links are passed to the Gemini engine for speech-to-text processing.\n4. **Execution:** The Advanced AI Agent leverages an OpenAI Chat Model to pick and fire the exact semantic tools for your Google Calendar (Get, Create, Update, Delete).\n5. **Delivery:** Dispatches dynamic markdown confirmations right back to your active chat thread.\n\n### Setup\n* [ ] Bind your Zalo Bot Webhook endpoint with valid development credentials.\n* [ ] Authenticate your Google Calendar node using standard secure OAuth2 tokens.\n* [ ] Attach your Google Gemini configuration to the audio transcription pipeline.\n* [ ] Set your target OpenAI production tokens inside the core LangChain language sub-node.\n\n### LICENCE\nThis template is shared free of charge. Copyright belongs to Nguyen Thieu Toan. Any copying or modification must credit the author."
      },
      "typeVersion": 1
    },
    {
      "id": "bd3c31d0-4bf3-4e6c-bb85-e88a184861a9",
      "name": "Zalo Bot Installation Guide",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2784,
        2032
      ],
      "parameters": {
        "color": 3,
        "width": 550,
        "height": 404,
        "content": "## \u26a0\ufe0f Install Community Node Zalo Bot!\n\nTo make the workflow function and display the Zalo Bot node, you need to install the community extension package:\n\n1. Go to **Settings** -> **Community Nodes** -> Select **Install**.  \n2. Paste the exact package name: `n8n-nodes-zalo-bot-official`  \n3. Click **Install** to download it into the system.  \n\n*Recommendation:* After successful installation, you should **restart the n8n container** to ensure the nodes run most stably, especially when operating the system in **Queue Mode**.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7cc4fedf-93f8-4313-aaa4-ca014308738e",
      "name": "Section 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2784,
        1504
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 502,
        "content": "## Section 1: Inbound Webhook Parsing & Typing Management\nListens for all incoming text and voice items from the corporate Zalo API, pushes typing context alerts instantly to make sure the user has immediate feedback, and abstracts structural keys into memory blocks."
      },
      "typeVersion": 1
    },
    {
      "id": "a3015a7e-1c40-479a-95e5-1f1e8ae9f068",
      "name": "Section 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2096,
        1504
      ],
      "parameters": {
        "color": 7,
        "width": 486,
        "height": 502,
        "content": "## Section 2: Audio Conversion & Speech-to-Text Pipeline\nFilters incoming signals using conditional statements to isolate voice content type. Dispatches real voice paths to the modern Gemini model engine to translate human speaking voice parameters into clean processing strings."
      },
      "typeVersion": 1
    },
    {
      "id": "3478a495-f1ab-4e0f-b18c-9920003f3c6b",
      "name": "Section 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1600,
        1504
      ],
      "parameters": {
        "color": 7,
        "width": 762,
        "height": 1012,
        "content": "## Section 3: AI Intelligence Layer & Google Calendar Tools Execution\nThe structural LangChain core AI Agent analyzes processed prompts. It evaluates constraints and maps action variables seamlessly to concrete operations on the targeted calendar repository."
      },
      "typeVersion": 1
    },
    {
      "id": "bec1a13c-a0fc-4488-92a3-67a3968d5c52",
      "name": "Section 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -816,
        1504
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 742,
        "content": "## Section 4: Zalo Messenger Dispatch & Operational Error Handling\nRoutes text packages seamlessly into your Zalo user application window. Captures potential runtime interruptions cleanly and dispatches recovery recommendations to protect system continuity."
      },
      "typeVersion": 1
    },
    {
      "id": "4b6bf7a8-8e37-4838-acf5-48cf32b660e8",
      "name": "Author Message",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2208,
        2032
      ],
      "parameters": {
        "color": 4,
        "width": 598,
        "height": 412,
        "content": "## Author Message\n\nHi! I am **Nguyen Thieu Toan (Jay Nguyen)** \u2014 a Verified n8n Creator and CEO/Founder of **GenStaff**.\nThank you for using this template!\n\nThis workflow is shared with you for free. If it brings value to your operations, optimizations, or saves you time, you can buy me a coffee here: **[My Donate Website](https://nguyenthieutoan.com/payment/)** *(PayPal, Momo, Bank Transfer)*\n\n* Website: [nguyenthieutoan.com](https://nguyenthieutoan.com)\n* Email: me@nguyenthieutoan.com\n* Company: GenStaff ([genstaff.net](https://genstaff.net))\n* Socials (Facebook / X / LinkedIn): @nguyenthieutoan\n\n*Discover more of my automation solutions:* **[Click here](https://n8n.io/creators/nguyenthieutoan/)**"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "0b526537-4171-4a84-8dd0-5f10295a0012",
  "nodeGroups": [],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Send Typing Indicator",
            "type": "main",
            "index": 0
          },
          {
            "node": "Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Context": {
      "main": [
        [
          {
            "node": "If Message is Voice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get events": {
      "ai_tool": [
        [
          {
            "node": "Calendar Manage!",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Create Event": {
      "ai_tool": [
        [
          {
            "node": "Calendar Manage!",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Delete event": {
      "ai_tool": [
        [
          {
            "node": "Calendar Manage!",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Update Event": {
      "ai_tool": [
        [
          {
            "node": "Calendar Manage!",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Calendar Manage!": {
      "main": [
        [
          {
            "node": "Send AI Response",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Error Noti",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Calendar Manage!",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "If Message is Voice": {
      "main": [
        [
          {
            "node": "Transcribe a recording",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Calendar Manage!",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Transcribe a recording": {
      "main": [
        [
          {
            "node": "Calendar Manage!",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}