AutomationFlowsAI & RAG › Automate Restaurant Reservations with AI on Whatsapp and Google Sheets

Automate Restaurant Reservations with AI on Whatsapp and Google Sheets

ByBasil Irfan @basil on n8n.io

Streamline restaurant reservations on WhatsApp

Event trigger★★★★☆ complexityAI-powered23 nodesWhatsAppWhatsApp TriggerAgentOpenAI ChatGoogle Sheets ToolTool CalculatorMemory Buffer WindowGoogle Sheets
AI & RAG Trigger: Event Nodes: 23 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #6379 — we link there as the canonical source.

This workflow follows the Agent → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "5fc9e0fb-70c7-4a69-b24b-7c791f4b3bf1",
      "name": "Send message",
      "type": "n8n-nodes-base.whatsApp",
      "onError": "continueRegularOutput",
      "position": [
        1040,
        0
      ],
      "parameters": {
        "textBody": "={{ $json.output }}",
        "operation": "send",
        "phoneNumberId": "668904212970806",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $('WhatsApp Trigger').item.json.messages[0].from }}"
      },
      "typeVersion": 1
    },
    {
      "id": "250d747c-a938-47c6-92a7-5bba1b430ca7",
      "name": "WhatsApp Trigger",
      "type": "n8n-nodes-base.whatsAppTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {
        "options": {},
        "updates": [
          "messages"
        ]
      },
      "typeVersion": 1
    },
    {
      "id": "a2b3e9f9-cde6-41d9-87c9-e6f571df2a67",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueRegularOutput",
      "position": [
        624,
        0
      ],
      "parameters": {
        "text": "={{ $json.messages[0].text.body }}",
        "options": {
          "systemMessage": "=Role\nyour role is to act as a reservation agent for The carnival all the buffet. you are a highly intellectual individual who can cater to any customer needs regarding reservation assisting customers in making reservations by getting all the details and logging \"\"log reservation\"\" tool and confirming if they would like to in pay advance to secure their reservation spot or arrive 15 minutes early. once you have confirmed all the details prompt the customer that the reservation has been logged they will recive the confirmation shortly \nDate and time is: {{ $now.format('yyyy-MM-DDDD-hh-mm-ss-') }}\n\nTask\n\nGuide customers through the reservation process by collecting necessary information such as name, phone number, slot timings, date, and number of persons for the reservation make sure to collect all of the above details.Use the \"log reservation\" tool to input this information\n\nWhen customers inquire about the menu, the discounts on the cards, provide them with the link \n\nhttps://www.instagram.com/p/DJKBhCatQ1Y/?img_index=1\n\nIf they press D for the location of the restaurant, provide them with this link: https://www.google.com/maps/place/The+Carnival+All+Day+Buffet/@31.5217381,74.3486342,17z/data=!3m1!4b1!4m6!3m5!1s0x3919053a9b6bc1fb:0xf473ee386cffadaa!8m2!3d31.5217381!4d74.3512091!16s%2Fg%2F11thhhd98r?entry=ttu&g_ep=EgoyMDI1MDUxMy4xIKXMDSoASAFQAw%3D%3D\n\nthe following variables are required to make a reservation (\"name\", \"phone number\", \"date\", \"number of persons\", \"slot timings\").\n\nMake sure to confirm the customer avaliblity (arrive early or pay now) before logging in the reservation in \"log reservation\" tool\n\nAdditionally, DISCOUNT CALCULATION\nCalculation of discount does not count in  making a reservsation. calulating discount is a differetn part of your job not not combine it with logging reservations \n\nwhen calculating discount show all eligible debit-card names as a numbered list from ( the details have been provided below)\n\nInstruct the guest to reply with the number of their chosen card from ( the details have been provided below)\n\nWhen they send party size and card choice (gather both details in a single message) \n\nApply the given discount to the base price (2499) to get the discounted price.\n\nAdd 5% tax on the original base price (not the discounted price)\n\nMultiply the final per-head price (after discount + tax) by the number of people to get the total cost ( respect the discount cap on the cards)\n\nFormula (total_cost = ((2499  (1 - discount_rate)) + (2499 * 0.05)) * num_people) \n\nReturn only the final amount (hide intermediate math).\n\nmake sure your first message is like this:\n\nWelcome to The Carnival All Day Buffet.\n\nType A for Reservation,\n\nType B to get the Menu, Discount Information & Slot Timings,\n\nType C  for Calculation of the Discount on the given Bank Cards,\n\nType D to get the google pin/location of the restaurant,\n\nRules\n\nAlways return phone numbers as a 12-digit string beginning with \"92\". If the number starts with \"0\", drop the 0 and prepend \"92\". If it already starts with \"92\", leave it unchanged.\"\nFORMAT_PHONE = phone.replace(/[^0-9]/g,\"\").replace(/^0/,\"92\").replace(/^92/,\"92\") example:\"923480010872\"\n\nCollect the following details from the customer: name, phone number, slot timings, date, number of persons if any one of the variable is missing prompt the customer to provide it for you and log them in \"log reservation\" make sure to log the details first and then send the relevant message.\n\ntell the customer their request have been logged and they will receive their confirmation shortly\n\nAlways set the status to \"Pending\" if the customer has confirmed the reservation \"Pending\" and if the customer has opted to pay in advance, set the status to \"Paid\" no other status is valid and will not go through.\n\nWhen you ask the customer for reservation details (name, phone number, date, number of persons, slot timings), you MUST always display the available slot timings as part of your message. The available slot timings are:\n\"12:00 PM-1:30 PM\n1:45 PM-3:15 PM\n3:30 PM-5:00 PM\n5:15 PM-6:45 PM\n7:00 PM-8:30 PM\n8:45 PM-10:15 PM\n10:30 PM-12:00 PM\"\nNever ask for slot timings without showing the customer this list in your message.\n\nTool\nOnce you have all the details for the reservation log them in \"log reservation\"\nyou also have a \"calculator\" tool to calculate the discounts on the card \n\nEXAMPLES \n\nQ: hey \n\nA:  Welcome to The Carnival All Day Buffet.\n\nType A for Reservation,\n\nType B to get the Menu, Discount Information & Slot Timings,\n\nType C  for Calculation of the Discount on the given Bank Cards,\n\nType D to get the google pin/location of the restaurant,\n\nQ: A\n\nA: it seems like you like to make a reservation please provide the following details in a single message \n\nname \n\nphone number \n\ndate \n\nnumber of persons\n\nslot timings. please select the number: (1-7)\n\"12:00 PM-1:30 PM\n1:45 PM-3:15 PM\n3:30 PM-5:00 PM\n5:15 PM-6:45 PM\n7:00 PM-8:30 PM\n8:45 PM-10:15 PM\n10:30 PM-12:00 PM\"\n\nQ: \"\"\n\nA:Thank you for the details.  \n\nI will log the following reservation request:  \n\nName: \"\"\n\nPhone Number: \"\"  \n\nSlot Timing: \"\"\n\nDate: \"\" \n\nNumber of Persons: \"\"\n\nPlease confirm if all the details are correct before I proceed to submit your reservation request.  \n\nAdditionally, would you like to arrive 15 minutes early before the reservation slot time, or would you prefer to pay in advance to secure your reservation spot?\n\nQ: yes confirm i will arrive early \n\nA: Your reservation has been logged successfully you will recive the confirmation message shortly. If their is anything else i can help you with please feel free to ask \n\n\nNotes\n\nensure that you do not ask too many repetitive questions \n\nthe per-head price for the restaurant is 2499\n\nWhen calculating disounts on the given cards provide the final amount do not show the math\n\nIf a query falls outside reservation management or the customer asks for a human, redirect the customer to a human representative for further support. have them call the same WhatsApp number on the sim.\n\nMaintain a friendly, courteous, and professional tone\n\nhave a spartan tone and aviod any emojis be professional\n\nHere are the debit cards details:\nMeezan Bank\n\n25% Discount on Cards:\n\u2022 Visa Infinite Debit Card\n\u2022 Mastercard World Debit Card\n\nDiscount Cap: PKR 2,000\n\n20% Discount on Cards:\n\u2022 Visa Platinum Aura Card\n\u2022 Mastercard Platinum Debit Card\n\u2022 Visa Platinum Debit Card\n\nDiscount Cap: PKR 2,000\n\n15% Discount on Cards:\n\u2022 Visa Women Debit Card\n\u2022 Mastercard Titanium Debit Card\n\nDiscount Cap: PKR 2,000\n\n10% Discount on Cards:\n\u2022 Visa Gold Debit Card\n\u2022 Mastercard Classic Debit Card\n\u2022 Visa Silver Debit Card\n\nDiscount Cap: PKR 2,000\n\nDubai Islamic Bank\n\n50% Discount on Cards:\n\u2022 Visa Signature\n\nDiscount Cap: PKR 3,500\n\n30% Discount on Cards:\n\u2022 Visa Ayaan\n\nDiscount Cap: PKR 2,000\n\nZindigi (JS Bank)\n\n25% Cash Reward Terms & Conditions:\n\u2022 Zindigi customers: 25% cash reward, up to PKR 2,000 per month.\n\u2022 Non-Zindigi customers: 25% cash reward, up to PKR 500 (one-time).\n\u2022 Applicable on QR/Till ID payments at Zindigi RAAST merchants.\n\u2022 Cash reward will be posted on the next working day.\n\nAllied Bank\n\n40% Discount on Cards:\n\u2022 Premium Debit\n\nDiscount Cap: PKR 4,000\n\n20% Discount on Cards:\n\u2022 Platinum Debit\n\u2022 Titanium Debit\n\nDiscount Cap: PKR 2,000\n\nSamba Bank\n\n50% Discount on Cards:\n\u2022 Samba Gold Mastercard\n\nDiscount Cap: PKR 2,500\n\nGolootlo\nFlat 10% Off on 1st and 2nd slots only."
        },
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "d449cc1c-0a79-4879-9ef4-8650bf49a264",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        608,
        160
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {
          "maxTokens": 2000,
          "temperature": 0.5
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "72fc3993-6e60-4e26-86f5-26a7476f5194",
      "name": "log reservation",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        928,
        144
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Date', `The date should be in the following format \"2025-06-09\" `, 'string') }}",
            "Phone": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Phone', ``, 'string') }}",
            "Guests": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Guests', ``, 'string') }}",
            "Status": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Status', ``, 'string') }}",
            "Timestamp": "={{ $now.format('yyyy-MM-dd-hh-mm')}}",
            "Time slot ": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Time_slot_', `Time slot should be in the following format \"3:30 PM \u2013 5:00 PM\"`, 'string') }}",
            "CustomerName ": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('CustomerName_', ``, 'string') }}",
            "ReservationID": "={{ `RES-${$now.setZone('Asia/Karachi').toFormat('yyLLdd-HHmm')}-${Math.random().toString(36).slice(2,8).toUpperCase()}` }}"
          },
          "schema": [
            {
              "id": "ReservationID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "ReservationID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "CustomerName ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "CustomerName ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Time slot ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Time slot ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Guests",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Guests",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "HandledBY",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "HandledBY",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Slot ID",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Slot ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notified ",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Notified ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "ReservationID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/YOUR_AWS_SECRET_KEY_HERE_ElfiY/edit#gid=0",
          "cachedResultName": "Reservation"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1oG6mCFReg7CRgwjcnnSTSfy7u1TblEXVLuj3B_ElfiY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/YOUR_AWS_SECRET_KEY_HERE_ElfiY/edit?usp=drivesdk",
          "cachedResultName": "Carnival crm portal"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "76ad7647-6d2a-43b9-ab5e-e4acde05798e",
      "name": "Calculator",
      "type": "@n8n/n8n-nodes-langchain.toolCalculator",
      "position": [
        832,
        192
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "88d5a878-2804-468e-ab7a-0deb015e1f01",
      "name": "Filter",
      "type": "n8n-nodes-base.filter",
      "position": [
        304,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e231ce1b-505c-4006-acca-03deecad142a",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.messages[0].type }}",
              "rightValue": "text"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6f6bbfef-1ce2-4547-ad15-4b8069b9c73b",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        720,
        224
      ],
      "parameters": {
        "sessionKey": "={{ $('Filter').item.json.messages[0].from }}",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "dfa06e51-a5c4-44dc-9587-a7fb2038e5a9",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -208,
        -112
      ],
      "parameters": {
        "width": 400,
        "height": 112,
        "content": "Recivesd the messages via facebook developer app you have to create a business manager and a facebook developer app and connect your whatsaoo to it it will give you the cerdentails for it \n"
      },
      "typeVersion": 1
    },
    {
      "id": "4da74bf1-8a1a-4931-9b04-c4ee506d0d71",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        -96
      ],
      "parameters": {
        "width": 352,
        "height": 80,
        "content": "Filter the message based on only text you can setup any tyoe of filter here and sends it to ai agent the agent then froma reply \n"
      },
      "typeVersion": 1
    },
    {
      "id": "0d4c2514-a7dc-4108-830c-d1f321771c4b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        -96
      ],
      "parameters": {
        "height": 80,
        "content": "Once the reply is formed, it routes the message back to the sender"
      },
      "typeVersion": 1
    },
    {
      "id": "8c179aba-448c-40a9-a910-f71137771fd9",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        576,
        336
      ],
      "parameters": {
        "width": 480,
        "height": 80,
        "content": "OpenAIis connected for the brain's simple memory for storing conversation, and it has two tools: a calculator for calculating discounts and a google sheet doc for storing reservation details. \n"
      },
      "typeVersion": 1
    },
    {
      "id": "564f489c-51f4-45a6-8cb2-6af525237bc0",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        416,
        768
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "Confirmed",
              "lookupColumn": "Status"
            },
            {
              "lookupColumn": "Notified "
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/YOUR_AWS_SECRET_KEY_HERE_ElfiY/edit#gid=0",
          "cachedResultName": "Reservation"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1oG6mCFReg7CRgwjcnnSTSfy7u1TblEXVLuj3B_ElfiY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/YOUR_AWS_SECRET_KEY_HERE_ElfiY/edit?usp=drivesdk",
          "cachedResultName": "Carnival crm portal"
        },
        "combineFilters": "OR"
      },
      "typeVersion": 4.6
    },
    {
      "id": "f19ea81b-3ee3-4f23-84fb-39e097276c10",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        192,
        768
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "76261254-6c6c-4046-abd8-b627ecbc5ff3",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        656,
        768
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "be57c9ee-4ec0-473e-8c35-ba8f907e024b",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.Status }}",
              "rightValue": "Confirmed "
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "006f1f50-9485-4db7-9f31-f92a2bc18ddc",
      "name": "Send message1",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        880,
        864
      ],
      "parameters": {
        "textBody": "={{ $json['CustomerName '] }}, We regret to inform you your reservation on {{ $json.Date }} at slot {{ $json['Time slot '] }} Is rejected please conider another slot time, Thank you",
        "operation": "send",
        "phoneNumberId": "668904212970806",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $json.Phone.toString() }}"
      },
      "typeVersion": 1
    },
    {
      "id": "d06c22b2-c5d5-4740-a394-8a78159c525c",
      "name": "Update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1104,
        672
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('Get row(s) in sheet').item.json.Date }}",
            "Notes": "={{ $('Get row(s) in sheet').item.json.Notes }}",
            "Phone": "={{ $('Get row(s) in sheet').item.json.Phone }}",
            "Guests": "={{ $('Get row(s) in sheet').item.json.Guests }}",
            "Status": "={{ $('Get row(s) in sheet').item.json.Status }}",
            "Slot ID": "={{ $('Get row(s) in sheet').item.json['Slot ID'] }}",
            "HandledBY": "={{ $('Get row(s) in sheet').item.json.HandledBY }}",
            "Notified ": "Yes",
            "Timestamp": "={{ $('Get row(s) in sheet').item.json.Timestamp }}",
            "Time slot ": "={{ $('Get row(s) in sheet').item.json['Time slot '] }}",
            "CustomerName ": "={{ $('Get row(s) in sheet').item.json['CustomerName '] }}",
            "ReservationID": "={{ $('Get row(s) in sheet').item.json.ReservationID }}"
          },
          "schema": [
            {
              "id": "ReservationID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "ReservationID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "CustomerName ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "CustomerName ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Time slot ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Time slot ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Guests",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Guests",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "HandledBY",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "HandledBY",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Slot ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Slot ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notified ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Notified ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "ReservationID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/YOUR_AWS_SECRET_KEY_HERE_ElfiY/edit#gid=0",
          "cachedResultName": "Reservation"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1oG6mCFReg7CRgwjcnnSTSfy7u1TblEXVLuj3B_ElfiY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/YOUR_AWS_SECRET_KEY_HERE_ElfiY/edit?usp=drivesdk",
          "cachedResultName": "Carnival crm portal"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "813c220c-c340-4270-9f7d-7d7883944651",
      "name": "Update row in sheet1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1104,
        864
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('Get row(s) in sheet').item.json.Date }}",
            "Notes": "={{ $('Get row(s) in sheet').item.json.Notes }}",
            "Phone": "={{ $('Get row(s) in sheet').item.json.Phone }}",
            "Guests": "={{ $('Get row(s) in sheet').item.json.Guests }}",
            "Status": "={{ $('Get row(s) in sheet').item.json.Status }}",
            "Slot ID": "={{ $('Get row(s) in sheet').item.json['Slot ID'] }}",
            "HandledBY": "={{ $('Get row(s) in sheet').item.json.HandledBY }}",
            "Notified ": "Yes",
            "Timestamp": "={{ $('Get row(s) in sheet').item.json.Timestamp }}",
            "Time slot ": "={{ $('Get row(s) in sheet').item.json['Time slot '] }}",
            "CustomerName ": "={{ $('Get row(s) in sheet').item.json['CustomerName '] }}",
            "ReservationID": "={{ $('Get row(s) in sheet').item.json.ReservationID }}"
          },
          "schema": [
            {
              "id": "ReservationID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "ReservationID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "CustomerName ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "CustomerName ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Time slot ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Time slot ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Guests",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Guests",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "HandledBY",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "HandledBY",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Slot ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Slot ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notified ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Notified ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "ReservationID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/YOUR_AWS_SECRET_KEY_HERE_ElfiY/edit#gid=0",
          "cachedResultName": "Reservation"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1oG6mCFReg7CRgwjcnnSTSfy7u1TblEXVLuj3B_ElfiY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/YOUR_AWS_SECRET_KEY_HERE_ElfiY/edit?usp=drivesdk",
          "cachedResultName": "Carnival crm portal"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "006c7ae0-9458-46f5-a256-d714027265bc",
      "name": "Send message2",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        880,
        672
      ],
      "parameters": {
        "textBody": "={{ $json['CustomerName '] }},Your reservation at {{ $json.Date }} is confirmed. Looking forward to meet you at your desired slot time  {{ $json['Time slot '] }}",
        "operation": "send",
        "phoneNumberId": "668904212970806",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $json.Phone.toString() }}"
      },
      "typeVersion": 1
    },
    {
      "id": "b4f809cd-c1d7-4aeb-99ca-7fe3e19158dc",
      "name": "Filter1",
      "type": "n8n-nodes-base.filter",
      "position": [
        656,
        928
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bc063fbf-34db-46b0-976b-99be846fe228",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.Status }}",
              "rightValue": "Rejected"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "ad3c315a-e734-412d-b3e0-319ef98a8c69",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        -288
      ],
      "parameters": {
        "width": 352,
        "height": 80,
        "content": "# AI agent workflow "
      },
      "typeVersion": 1
    },
    {
      "id": "ce7db6fb-0a3a-4892-ae4a-2b1571c5ce2e",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        592
      ],
      "parameters": {
        "width": 624,
        "height": 80,
        "content": "#  reservation Confirmatrion workflow "
      },
      "typeVersion": 1
    },
    {
      "id": "44e79618-822c-4318-8199-f445c2defb8f",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        1072
      ],
      "parameters": {
        "width": 832,
        "height": 128,
        "content": "This workflow has a schedule trigger; it runs on a specific time you choose it gets the data from the sheets and decides it has built-in logic if the status is confirmation not sent, it plucks all the reservations and, based on their status, sends a message to the user the if module decided if the reservation is confirmed or rejected and sends it the the relevant field. "
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Send message2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Filter1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter1": {
      "main": [
        [
          {
            "node": "Send message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Send message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculator": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Send message1": {
      "main": [
        [
          {
            "node": "Update row in sheet1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send message2": {
      "main": [
        [
          {
            "node": "Update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "log reservation": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WhatsApp Trigger": {
      "main": [
        [
          {
            "node": "Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Streamline restaurant reservations on WhatsApp

Source: https://n8n.io/workflows/6379/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This template is designed for anyone who wants to use WhatsApp as a personal AI assistant hub. If you often juggle tasks, emails, calendars, and expenses across multiple tools, this workflow consolida

OpenAI Chat, Memory Buffer Window, Mcp Client Tool +12
AI & RAG

⚠️ EDUCATIONAL DEMONSTRATION ONLY - NOT FOR PRODUCTION MEDICAL USE ⚠️

Agent, Memory Postgres Chat, OpenAI Chat +7
AI & RAG

WhatsApp AI Assistant for Clinic Appointment Booking Automate your entire appointment lifecycle with an intelligent AI assistant that lives on WhatsApp. This workflow empowers any clinic or independen

Google Gemini Chat, WhatsApp Trigger, Memory Buffer Window +9
AI & RAG

This workflow implements a WhatsApp-based virtual restaurant assistant that automates customer interaction from the first message to post-dining follow-up.

WhatsApp Trigger, WhatsApp, Guardrails +8
AI & RAG

Whatsapp Ai Agent. Uses whatsAppTrigger, whatsApp, httpRequest, openAi. Event-driven trigger; 23 nodes.

WhatsApp Trigger, WhatsApp, HTTP Request +7