School parents AI agent on WhatsApp

Answers parents' questions about fees, dates and events, and tells them about their own child's absences and fees due.

AI agentAdvanced Saves ~20 hours/month AI AgentsBy Flowngn team

Works with n8n · Make · Zapier

How it works

Trigger: WhatsApp — a parent sends a message
  1. A parent asks a question on WhatsApp.
  2. The agent answers general questions from your School info sheet.
  3. For questions about their child, it looks up only the children linked to that parent's phone.
  4. It passes complaints, safety concerns and meeting requests to the office.

What it can do

Unlike a fixed flow, an agent decides which of its tools to use, in what order — and remembers the conversation.

  • Answers about fees, term dates, holidays, transport and events
  • Shares a child's absences and fees due with their own parent
  • Replies in Arabic dialects or English
  • Alerts the office about anything sensitive

System prompt

The instructions that shape the agent. It's already inside the n8n template — copy it into Make or Zapier, and adjust the YOUR_… parts.

System prompt
You are the WhatsApp assistant for YOUR_SCHOOL, talking to parents. Reply in the customer's language and dialect (Egyptian Arabic, Gulf Arabic, Modern Standard Arabic or English). Be warm and brief.

Today is {{ $now.toFormat('cccc d LLLL yyyy') }}. The parent's phone is {{ $('Get question').item.json.from }}.

Tools:
- "School info": fees, payment methods, term dates, holidays, uniform, transport, events and contacts. Answer general questions only from it.
- "My children": the children registered to THIS parent's phone (name, grade, class, teacher, absences this term, fees due). It only ever returns this parent's children.
- "Notify school": alerts the school office. Use it for complaints, health or safety concerns, bullying, fee disputes, meeting requests, and anything you can't answer.

Rules:
- If "My children" returns nothing, say the number isn't registered and ask them to contact the office; never share any child's details.
- Never discuss other students, staff personal details, or grades you don't have.
- Never promise exceptions, refunds or decisions; say the school will confirm.
- For anything urgent about a child's safety or health, use "Notify school" immediately and give them the office phone YOUR_OFFICE_PHONE.

Safety rules

Built into the prompt and the tools:

  • Only shows children registered to the parent's phone
  • Never discusses other students or staff
  • Sends safety and health concerns to the office straight away

Uses your own AI key (Claude, OpenAI or another model). Cost depends on the model and conversation length — a small, fast model keeps most conversations to a fraction of a cent.

Diagram

WIncoming messageWhatsApp Trigger{ }Get questionCodeParents agentAI AgentClaude modelAnthropic Chat Mo…◷MemorySimple MemoryGSchool infoGoogle Sheets ToolGMy childrenGoogle Sheets ToolTNotify schoolTelegram ToolWReply on WhatsAppWhatsApp Business Cloud
Trigger App Code AI Agent tool

Code

JavaScript used in the Code step — already included in the template below.

Get question · Code node
// Keeps only text messages and pulls out who sent it and what they asked.
const msg = $input.first().json.messages?.[0];
if (!msg || msg.type !== "text") return [];

return [{ json: { from: msg.from, question: msg.text.body } }];

Build it

Pick your tool — same automation, step by step.

Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder. AI steps use a Claude model node — swap it for OpenAI, Gemini or Ollama if you prefer.

Workflow JSON
Show code (292 lines)
{
  "name": "School parents AI agent on WhatsApp (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## School parents AI agent on WhatsApp\nAnswers parents' questions about fees, dates and events, and tells them about their own child's absences and fees due.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
        "height": 260,
        "width": 340
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "updates": [
          "messages"
        ]
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "Incoming message",
      "type": "n8n-nodes-base.whatsAppTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ],
      "webhookId": "45820912-e7e8-476e-a2a7-16e2eb03a79c"
    },
    {
      "parameters": {
        "jsCode": "// Keeps only text messages and pulls out who sent it and what they asked.\nconst msg = $input.first().json.messages?.[0];\nif (!msg || msg.type !== \"text\") return [];\n\nreturn [{ json: { from: msg.from, question: msg.text.body } }];"
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "Get question",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.question }}",
        "options": {
          "systemMessage": "=You are the WhatsApp assistant for YOUR_SCHOOL, talking to parents. Reply in the customer's language and dialect (Egyptian Arabic, Gulf Arabic, Modern Standard Arabic or English). Be warm and brief.\n\nToday is {{ $now.toFormat('cccc d LLLL yyyy') }}. The parent's phone is {{ $('Get question').item.json.from }}.\n\nTools:\n- \"School info\": fees, payment methods, term dates, holidays, uniform, transport, events and contacts. Answer general questions only from it.\n- \"My children\": the children registered to THIS parent's phone (name, grade, class, teacher, absences this term, fees due). It only ever returns this parent's children.\n- \"Notify school\": alerts the school office. Use it for complaints, health or safety concerns, bullying, fee disputes, meeting requests, and anything you can't answer.\n\nRules:\n- If \"My children\" returns nothing, say the number isn't registered and ask them to contact the office; never share any child's details.\n- Never discuss other students, staff personal details, or grades you don't have.\n- Never promise exceptions, refunds or decisions; say the school will confirm.\n- For anything urgent about a child's safety or health, use \"Notify school\" immediately and give them the office phone YOUR_OFFICE_PHONE."
        }
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "Parents agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.9,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "claude-sonnet-5",
          "mode": "list"
        },
        "options": {}
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "Claude model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "typeVersion": 1.3,
      "position": [
        260,
        220
      ]
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $('Get question').item.json.from }}",
        "contextWindowLength": 10
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        430,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Returns school information: fees, term dates, holidays, transport, events, contacts.",
        "operation": "read",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "School info",
          "mode": "name"
        },
        "options": {}
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "School info",
      "type": "n8n-nodes-base.googleSheetsTool",
      "typeVersion": 4.5,
      "position": [
        600,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Returns the children registered to the parent who is messaging.",
        "operation": "read",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Students",
          "mode": "name"
        },
        "filtersUI": {
          "values": [
            {
              "lookupColumn": "parent_phone",
              "lookupValue": "={{ $('Get question').item.json.from }}"
            }
          ]
        },
        "options": {}
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "My children",
      "type": "n8n-nodes-base.googleSheetsTool",
      "typeVersion": 4.5,
      "position": [
        770,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Alerts the school office about complaints, safety concerns, meeting requests and questions you can't answer.",
        "chatId": "YOUR_OFFICE_CHAT_ID",
        "text": "={{ $fromAI('message', \"What the office needs to know, including the parent's phone and child's name\", 'string') }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "Notify school",
      "type": "n8n-nodes-base.telegramTool",
      "typeVersion": 1.2,
      "position": [
        940,
        220
      ]
    },
    {
      "parameters": {
        "operation": "send",
        "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
        "recipientPhoneNumber": "={{ $('Get question').item.json.from }}",
        "textBody": "={{ $json.output }}"
      },
      "id": "45820912-e7e8-476e-a2a7-16e2eb03a79c",
      "name": "Reply on WhatsApp",
      "type": "n8n-nodes-base.whatsApp",
      "typeVersion": 1,
      "position": [
        900,
        0
      ]
    }
  ],
  "connections": {
    "Incoming message": {
      "main": [
        [
          {
            "node": "Get question",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get question": {
      "main": [
        [
          {
            "node": "Parents agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parents agent": {
      "main": [
        [
          {
            "node": "Reply on WhatsApp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude model": {
      "ai_languageModel": [
        [
          {
            "node": "Parents agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Memory": {
      "ai_memory": [
        [
          {
            "node": "Parents agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "School info": {
      "ai_tool": [
        [
          {
            "node": "Parents agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "My children": {
      "ai_tool": [
        [
          {
            "node": "Parents agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Notify school": {
      "ai_tool": [
        [
          {
            "node": "Parents agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • Save parent phones in the same format WhatsApp uses: country code, no + or spaces (e.g. 201001234567).

Related flows