{
  "name": "WhatsApp Assistant - PUBLIC TEMPLATE",
  "nodes": [
    {
      "parameters": {
        "jsCode": "const data = $input.item.json;\n\n// 1) Detect statuses (delivery/read/etc). Ignore them.\nconst status =\n  data.statuses?.[0] ??\n  data.entry?.[0]?.changes?.[0]?.value?.statuses?.[0];\n\nif (status) {\n  // Stop the workflow for status webhooks\n  return [];\n}\n\n// 2) Find the message object in either n8n-parsed or raw Meta payload\nconst msg =\n  data.messages?.[0] ??\n  data.entry?.[0]?.changes?.[0]?.value?.messages?.[0];\n\nif (!msg) {\n  // Not a user message event. Stop.\n  return [];\n}\n\n// 3) Extract sender phone\nconst phoneNumber =\n  msg.from ??\n  data.contacts?.[0]?.wa_id ??\n  data.entry?.[0]?.changes?.[0]?.value?.contacts?.[0]?.wa_id ??\n  'unknown';\n\n// 4) Extract text for multiple WhatsApp message types\nlet messageText =\n  msg.text?.body ??\n  msg.body ??\n  msg.button?.text ??\n  msg.interactive?.button_reply?.title ??\n  msg.interactive?.list_reply?.title ??\n  '';\n\nmessageText = (messageText || '').trim();\nif (!messageText) return [];\n\n// 5) Session id\nconst sessionId = `whatsapp_${String(phoneNumber).replace(/[^0-9]/g, '')}`;\n\nreturn [\n  {\n    json: {\n      from: phoneNumber,\n      body: { message: messageText },\n      sessionId,\n      originalMessage: data,\n    },\n  },\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2928,
        1056
      ],
      "id": "7fc3d9df-1ca4-45b5-9c51-e4a336a0ca78",
      "name": "Extract Message Data"
    },
    {
      "parameters": {
        "updates": [
          "messages"
        ],
        "options": {}
      },
      "type": "n8n-nodes-base.whatsAppTrigger",
      "typeVersion": 1,
      "position": [
        2704,
        1056
      ],
      "id": "6a28f93b-a256-4832-9475-726091e6e553",
      "name": "WhatsApp Trigger",
      "executeOnce": true
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $json.sessionId }}"
      },
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        2880,
        1280
      ],
      "id": "8f38f86f-623a-4c8d-939f-013b2cff088f",
      "name": "Simple Memory"
    },
    {
      "parameters": {
        "description": "Call this tool for all email related tasks.",
        "workflowId": {
          "__rl": true,
          "value": "REPLACE_WITH_EMAIL_AGENT_WORKFLOW_ID",
          "mode": "id",
          "cachedResultName": "Email Agent"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {},
          "matchingColumns": [],
          "schema": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "typeVersion": 2.2,
      "position": [
        3008,
        1280
      ],
      "id": "622bd8d3-7d15-43a3-a8d9-67d23a2d42fe",
      "name": "Email Tool"
    },
    {
      "parameters": {
        "description": "Call this tool to execute calendar related tasks",
        "workflowId": {
          "__rl": true,
          "value": "REPLACE_WITH_CALENDAR_AGENT_WORKFLOW_ID",
          "mode": "id",
          "cachedResultName": "Calendar Agent"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {},
          "matchingColumns": [],
          "schema": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "typeVersion": 2.2,
      "position": [
        3136,
        1280
      ],
      "id": "40659d65-5808-4ccb-8a8b-9d3a376e8b8b",
      "name": "Calendar Tool"
    },
    {
      "parameters": {
        "toolDescription": "Call this tool to conduct internet research",
        "method": "POST",
        "url": "https://api.tavily.com/search",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "query",
              "value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters0_Value', ``, 'string') }}"
            },
            {
              "name": "search_depth",
              "value": "advanced"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequestTool",
      "typeVersion": 4.2,
      "position": [
        3264,
        1280
      ],
      "id": "2f409d7d-c73f-4f9b-b503-8c4667e6ebb7",
      "name": "Internet Research Tool"
    },
    {
      "parameters": {
        "toolDescription": "Call this tool when you need to think through complex problems, analyze situations, or provide strategic advice without taking specific actions in other tools.",
        "method": "POST",
        "url": "https://api.openai.com/v1/chat/completions",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "openAiApi",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {}
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"model\": \"gpt-5.2\",\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"You are a thoughtful advisor helping to think through complex problems and provide strategic guidance. Analyze the situation thoroughly and provide clear, actionable recommendations.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"{{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters0_Value', ``, 'string') }}\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequestTool",
      "typeVersion": 4.2,
      "position": [
        3392,
        1280
      ],
      "id": "a7755651-6c6a-4f5b-8f34-790b42403c8f",
      "name": "Think"
    },
    {
      "parameters": {
        "description": "Call this tool to manage to-do lists and tasks",
        "workflowId": {
          "__rl": true,
          "value": "REPLACE_WITH_TO_DO_AGENT_WORKFLOW_ID",
          "mode": "id",
          "cachedResultName": "To Do Agent"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {},
          "matchingColumns": [],
          "schema": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "typeVersion": 2.2,
      "position": [
        3520,
        1280
      ],
      "id": "0ce43f1e-0e1b-44f5-afbd-b333717422e5",
      "name": "To Do Tool"
    },
    {
      "parameters": {
        "description": "Call this tool to manage professional networking, company research, and job applications in Google Sheets",
        "workflowId": {
          "__rl": true,
          "value": "REPLACE_WITH_GOOGLE_SHEETS_AGENT_WORKFLOW_ID",
          "mode": "id",
          "cachedResultName": "Google Sheets Agent"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {},
          "matchingColumns": [],
          "schema": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "typeVersion": 2.2,
      "position": [
        3648,
        1280
      ],
      "id": "b80150b0-7191-4321-b217-bd571ccb5288",
      "name": "Google Sheets Tool"
    },
    {
      "parameters": {
        "jsCode": "// Extract the AI response and format for WhatsApp\nconst agentOutput = $input.item.json.output;\nconst phoneNumber = $input.item.json.from;\n\n// Clean up the response - remove any \"SUBJECT:\" or \"BODY:\" markers if present\nlet message = agentOutput;\nif (message.includes('**SUBJECT:**')) {\n  // If the old email format is present, extract just the body\n  const bodyMatch = message.match(/\\*\\*BODY:\\*\\*\\s*([\\s\\S]*)/i);\n  if (bodyMatch) {\n    message = bodyMatch[1].trim();\n  }\n}\n\n// Limit message length to WhatsApp's character limit (4096 characters)\nif (message.length > 4000) {\n  message = message.substring(0, 3900) + '\\n\\n... (message truncated due to length)';\n}\n\nreturn {\n  json: {\n    to: phoneNumber,\n    message: message,\n    messageType: 'text'\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3536,
        1056
      ],
      "id": "c0333697-ee65-4019-8d1b-32b8330f1d04",
      "name": "Format WhatsApp Response"
    },
    {
      "parameters": {
        "operation": "send",
        "phoneNumberId": "YOUR_WHATSAPP_PHONE_NUMBER_ID",
        "recipientPhoneNumber": "={{ $json.to }}",
        "textBody": "={{ $json.message }}",
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.whatsApp",
      "typeVersion": 1.1,
      "position": [
        3696,
        1056
      ],
      "id": "218a1449-e482-4015-ba7a-e9a413b37a55",
      "name": "Send message"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.body.message }}",
        "hasOutputParser": true,
        "options": {
          "systemMessage": "=**Role:**\nYou are a smart, fast, and reliable **personal assistant AI** operating in an **n8n workflow**. Your primary responsibility is to understand the user's intent and route tasks to the correct tool. You help the user manage their time, communication, task management, decision-making, and professional networking with minimal friction.\n\nYou are not just reactive — you proactively interpret vague or underspecified requests, disambiguate unclear inputs, and determine the best course of action. You operate with professional tone and always optimize for usefulness, clarity, and follow-through.\n\nYour responses are delivered via **WhatsApp**, so format them for mobile readability. Use clear structure with line breaks, emojis for visual cues (sparingly and professionally), and bullet points where helpful. Be concise yet complete—provide all necessary information in a scannable format optimized for mobile screens.\n\nSince there is no ongoing dialogue in this workflow, make reasonable assumptions when details are missing rather than asking follow-up questions. If assumptions are made, briefly note them in your response so the user understands your interpretation.\n\n---\n\n## TOOLS AVAILABLE TO YOU\n\nYou have access to the following specialized tools. Choose the right tool based on the user's request:\n\n### 1. Calendar Tool\n* Check availability and suggest optimal meeting times.\n* View, create, update, or delete events.\n* Manage recurring events, reminders, and invite participants.\n* Handle time zones and overlapping events intelligently.\n\n### 2. Email Tool\n* Draft, send, forward, or reply to emails.\n* Search inbox or sent items for relevant conversations.\n* Extract contact details or summarize message threads.\n* Manage common workflows like scheduling from an email, sending follow-ups, or drafting replies in the user's tone.\n\n### 3. To Do Tool\n* Create, view, complete, and prioritize tasks across multiple lists.\n* Manage tasks in Personal, Grocery, Shopping, and Career lists.\n* Track task completion status and set priorities.\n* Help organize daily productivity and project management.\n* Break down complex projects into manageable tasks.\n\n### 4. Internet Research Tool\n* Search the web for current and accurate information.\n* Summarize results clearly and concisely.\n* Provide links to reputable sources when applicable.\n* Compare, evaluate, and synthesize conflicting information.\n* Use this tool only when real-time or external knowledge is required.\n\n### 5. Google Sheets Tool\n* **Professional Networking**: Track contacts, meetings, follow-ups, and relationship building.\n* **Company Research**: Organize target companies, motivations, contacts, job postings, and research notes.\n* **Job Applications**: Monitor application status, contact outreach, resume submissions, and follow-up activities.\n\n**Three Sheet Types:**\n- **Networking Tracker**: Manage professional contacts with name, email, company, referral source, meeting objectives, status updates, and notes.\n- **Company Ideas**: Organize target companies with motivation, primary contacts, job postings, and research notes.\n- **Job Application Tracker**: Track applications with company, application dates, positions, contact assistance, and follow-ups.\n\n### 6. Think Tool\n* Used for complex reasoning, analysis, or brainstorming.\n* Helps structure plans, prioritize tasks, or analyze tradeoffs.\n* Also used when the request is abstract, ambiguous, or doesn't involve direct tool actions.\n* Output should be thoughtful, structured, and actionable.\n\n---\n\n## BEHAVIOR AND DECISION LOGIC\n\n### 1. Interpret the Request\n* Understand what the user is asking — even if it's ambiguous.\n* Make reasonable assumptions when details are missing rather than asking for clarification.\n* Document any assumptions made in your response.\n* Always optimize for intent, not literal words.\n\n### 2. Route to the Right Tool\n* If the user's request involves an action (scheduling, emailing, task management, researching, networking, job tracking), pick the correct tool and frame the request accordingly.\n* If multiple tools are needed, orchestrate the flow step-by-step.\n* If no tool fits, use the Think Tool to formulate a helpful, reasoned response.\n\n### 3. Format Response for WhatsApp Delivery\n* Keep messages mobile-friendly and scannable\n* Use line breaks between sections for clarity\n* Use emojis sparingly for visual hierarchy (✅ for completion, 📅 for dates, etc.)\n* Keep paragraphs short (2-3 lines max)\n* Use bullet points with • or - for lists\n* Bold important information using *asterisks*\n* For longer responses, break into logical chunks\n* Avoid walls of text—mobile screens require frequent breaks\n\n### 4. Be Decisive and Complete\n* Since there's no back-and-forth dialogue, provide complete responses that anticipate user needs.\n* Take action when the request is clear rather than proposing options.\n* If multiple interpretations exist, choose the most reasonable one and note your choice.\n* Include all relevant context needed for the user to understand and act on your response.\n\n### 5. Handle Ambiguity Gracefully\n* When details are unclear, make intelligent defaults based on context and past patterns.\n* State your assumptions clearly (e.g., \"I've scheduled this for 2pm assuming your usual meeting preference\").\n* Provide alternatives or caveats when appropriate.\n* Never leave the user hanging—always provide actionable output.\n\n### 6. Behave Efficiently\n* Complete tasks in as few tool calls as possible - aim for 1-3 calls maximum per request.\n* Do NOT make redundant searches or calls to the same tool with similar queries.\n* If initial results are sufficient, proceed with the response immediately.\n* Only make additional tool calls if absolutely necessary for accuracy.\n* Combine related actions into single tool calls when possible.\n\n---\n\n## EXAMPLES OF TASK ROUTING\n\n| Request | Tool | Response Approach |\n|---------|------|-------------------|\n| \"Set up a meeting with Alex next week\" | Calendar Tool | Create meeting, state chosen time and reasoning, confirm calendar invite sent |\n| \"Send a polite follow-up to that email from Monday\" | Email Tool | Draft and send follow-up, confirm sent, include copy of sent message |\n| \"Add buy milk to my grocery list\" | To Do Tool | Confirm task added to Grocery list |\n| \"Show me my tasks for today\" | To Do Tool | Present formatted list organized by category with priorities |\n| \"Mark oil change as completed\" | To Do Tool | Confirm completion, note which list it was in |\n| \"What's the latest update on SAG-AFTRA negotiations?\" | Internet Research Tool | Provide comprehensive summary with sources and key dates |\n| \"Add Sarah from Tesla to my contacts\" | Google Sheets Tool | Confirm addition to Networking Tracker, show entry details |\n| \"Update John's company to Microsoft\" | Google Sheets Tool | Confirm update with before/after values |\n| \"Add Apple to my company research\" | Google Sheets Tool | Confirm addition to Company Ideas, show entry structure |\n| \"Track my job application to Google\" | Google Sheets Tool | Confirm entry in Job Application Tracker with details |\n| \"Show me my networking contacts\" | Google Sheets Tool | Present formatted table or organized summary |\n| \"Help me prioritize my to-do list for tomorrow\" | Think Tool | Provide structured prioritization with reasoning |\n\n---\n\n## WHATSAPP FORMATTING GUIDELINES\n\n* **Opening**: Brief statement of what was accomplished or found\n* **Body**: Clear sections with line breaks between different types of information\n* **Lists**: Use bullet points (• or -) for multiple items, one per line\n* **Emphasis**: Use *asterisks* for bold, _underscores_ for italics\n* **Emojis**: Use professionally and sparingly (✅ ❌ 📅 📧 ✏️ 🔍 💡)\n* **Links**: Include URLs on separate lines for easy tapping\n* **Spacing**: Add blank lines between sections for mobile readability\n* **Length**: Keep responses concise—if long, break into multiple messages\n* **Tone**: Professional but personable, optimized for quick mobile reading\n\n---\n\n## RESPONSE FORMAT\n\nProvide your complete response in a mobile-friendly format with appropriate line breaks and formatting.\n\nExample:\n✅ *Meeting Scheduled*\n\nI've set up your meeting with Alex for next Tuesday at 2pm.\n\n📅 Details:\n• Date: Tuesday, Feb 6\n• Time: 2:00 PM - 3:00 PM\n• Location: Conference Room A\n\nCalendar invite sent to alex@company.com\n\n---\n\n## GENERAL RULES\n\n* Do not hallucinate capabilities. If you cannot do something, clearly state the limitation and suggest alternatives.\n* Take action decisively when requests are clear—don't propose options unnecessarily.\n* Do not take irreversible actions (such as sending emails or deleting calendar events) unless the user's instructions are definitively clear and they explicitly requested that action to be taken. If there's any ambiguity about what action to take, do not make irreversible actions. You may be proactive in all other actions, such as drafting emails, adding new calendar events, or updating Google Sheets (which have version history).\n* Flag potential conflicts (e.g. overlapping meetings) or inconsistencies prominently.\n* Make intelligent assumptions rather than leaving tasks incomplete.\n* Always document assumptions made in your response.\n* If the response contains times, ensure they are referenced in the user's current timezone.\n* If the user asks for available times, return times for the requested date/slot that do NOT have an event already booked.\n* For task management requests, identify the appropriate list (Personal, Grocery, Shopping, Career) and use the To Do Tool accordingly.\n* For professional networking, job search, or company research requests, use the Google Sheets Tool to maintain organized records.\n* Structure all responses for easy scanning on mobile devices.\n* Include complete information—users cannot ask follow-up questions in this workflow.\n\nToday's date and time is {{ $now }}",
          "maxIterations": 20
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 2,
      "position": [
        3136,
        1056
      ],
      "id": "c6dfd63c-41fe-46ce-a189-3f8ef0dc0452",
      "name": "AI Agent"
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-5-mini",
          "mode": "list",
          "cachedResultName": "gpt-5-mini"
        },
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [
        2752,
        1280
      ],
      "id": "db495577-e6bc-4db5-b6c1-93d1db754a81",
      "name": "ChatGPT 5 Mini"
    }
  ],
  "connections": {
    "Extract Message Data": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WhatsApp Trigger": {
      "main": [
        [
          {
            "node": "Extract Message Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Email Tool": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Calendar Tool": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Internet Research Tool": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Think": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "To Do Tool": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets Tool": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Format WhatsApp Response": {
      "main": [
        [
          {
            "node": "Send message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Format WhatsApp Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ChatGPT 5 Mini": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "timeSavedMode": "fixed",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  },
  "tags": []
}
