Order & returns AI agent on WhatsApp (Arabic)

Answers "where's my order?", gives delivery updates and logs returns and exchanges — in the customer's dialect.

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

Works with n8n · Make · Zapier

How it works

Trigger: WhatsApp — a customer sends a message
  1. A customer asks about their order on WhatsApp.
  2. The agent finds the order by number or by their phone number.
  3. It shares the status and tracking, or logs a return or exchange after confirming the details.
  4. It alerts your team on Telegram for returns and anything it can't solve.

What it can do

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

  • Finds orders by order number — or automatically by the customer's phone
  • Shares status, courier and tracking number
  • Logs return and exchange requests with item, reason and refund/exchange choice
  • Explains your return policy
  • Alerts your team for returns, damaged items and hand-overs

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 after-sales assistant for YOUR_STORE on WhatsApp. Reply in the customer's language and dialect (Egyptian Arabic, Gulf Arabic, Modern Standard Arabic or English). Be warm and brief.

You handle: "where is my order?", delivery updates, returns and exchanges.

Tools:
- "Look up order": finds orders by order number or by the customer's phone. Returns status, items, total, courier and tracking number.
- "Create return request": logs a return or exchange request. Use only after the customer confirms which item, the reason, and whether they want a refund or an exchange.
- "Notify team": alerts our team for every return request, damaged item, or anything you can't solve.

Our policy: YOUR_RETURN_POLICY (e.g. returns within 14 days, unused, with tags).

Rules:
- The customer's phone is {{ $('Get question').item.json.from }} — try it first if they don't give an order number.
- Never promise refunds, dates or compensation. Say the team will confirm.
- Never invent order details; if you can't find the order, ask for the order number.

Safety rules

Built into the prompt and the tools:

  • Never promises refunds, dates or compensation — the team confirms
  • Never invents order details
  • Confirms return details before logging them

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 questionCodeAfter-sales agentAI AgentClaude modelAnthropic Chat Mo…◷MemorySimple MemoryGLook up orderGoogle Sheets ToolGCreate return …Google Sheets ToolTNotify teamTelegram 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 (304 lines)
{
  "name": "Order & returns AI agent on WhatsApp (Arabic) (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## Order & returns AI agent on WhatsApp (Arabic)\nAnswers \"where's my order?\", gives delivery updates and logs returns and exchanges — in the customer's dialect.\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": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "updates": [
          "messages"
        ]
      },
      "id": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "name": "Incoming message",
      "type": "n8n-nodes-base.whatsAppTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ],
      "webhookId": "329e2b17-62e3-40d1-a6e5-e475fee4c948"
    },
    {
      "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": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "name": "Get question",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.question }}",
        "options": {
          "systemMessage": "=You are the after-sales assistant for YOUR_STORE on WhatsApp. Reply in the customer's language and dialect (Egyptian Arabic, Gulf Arabic, Modern Standard Arabic or English). Be warm and brief.\n\nYou handle: \"where is my order?\", delivery updates, returns and exchanges.\n\nTools:\n- \"Look up order\": finds orders by order number or by the customer's phone. Returns status, items, total, courier and tracking number.\n- \"Create return request\": logs a return or exchange request. Use only after the customer confirms which item, the reason, and whether they want a refund or an exchange.\n- \"Notify team\": alerts our team for every return request, damaged item, or anything you can't solve.\n\nOur policy: YOUR_RETURN_POLICY (e.g. returns within 14 days, unused, with tags).\n\nRules:\n- The customer's phone is {{ $('Get question').item.json.from }} — try it first if they don't give an order number.\n- Never promise refunds, dates or compensation. Say the team will confirm.\n- Never invent order details; if you can't find the order, ask for the order number."
        }
      },
      "id": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "name": "After-sales 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": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "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": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "name": "Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        430,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Finds orders by order number or phone. Returns status, items, total, courier and tracking number.",
        "operation": "read",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Orders",
          "mode": "name"
        },
        "filtersUI": {
          "values": [
            {
              "lookupColumn": "={{ $fromAI('column', \"Which column to search: order_id or phone\", 'string') }}",
              "lookupValue": "={{ $fromAI('value', \"The order number or phone number\", 'string') }}"
            }
          ]
        },
        "options": {}
      },
      "id": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "name": "Look up order",
      "type": "n8n-nodes-base.googleSheetsTool",
      "typeVersion": 4.5,
      "position": [
        600,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Logs a confirmed return or exchange request.",
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Returns",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "date": "={{ $now.toISO() }}",
            "phone": "={{ $('Get question').item.json.from }}",
            "order_id": "={{ $fromAI('order_id', \"Order number\", 'string') }}",
            "item": "={{ $fromAI('item', \"Which item\", 'string') }}",
            "reason": "={{ $fromAI('reason', \"Why they want to return it\", 'string') }}",
            "wants": "={{ $fromAI('wants', \"refund or exchange\", 'string') }}",
            "status": "new"
          }
        },
        "options": {}
      },
      "id": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "name": "Create return request",
      "type": "n8n-nodes-base.googleSheetsTool",
      "typeVersion": 4.5,
      "position": [
        770,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Alerts our team: every return request, damaged or wrong items, and anything you can't solve.",
        "chatId": "YOUR_TEAM_CHAT_ID",
        "text": "={{ $fromAI('message', \"What the team needs to know, including the customer's phone\", 'string') }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "id": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "name": "Notify team",
      "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": "329e2b17-62e3-40d1-a6e5-e475fee4c948",
      "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": "After-sales agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "After-sales agent": {
      "main": [
        [
          {
            "node": "Reply on WhatsApp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude model": {
      "ai_languageModel": [
        [
          {
            "node": "After-sales agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Memory": {
      "ai_memory": [
        [
          {
            "node": "After-sales agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Look up order": {
      "ai_tool": [
        [
          {
            "node": "After-sales agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Create return request": {
      "ai_tool": [
        [
          {
            "node": "After-sales agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Notify team": {
      "ai_tool": [
        [
          {
            "node": "After-sales agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • Keep tracking numbers in the Orders sheet (the Bosta flows can fill them in automatically).

Related flows